Chap-12. Website の HTTPS 化


前提

2024-10
 いつものとおり、自宅サーバが前提です。言ってみれば、趣味のサーバとか、SOHOレベル。なので1台のサーバにドメイン一つ。簡単な条件です。
「今まで HTTP でサーバを公開していて、これから常時 HTTPS 化する」というケースを想定しています。
なお、Apache も Nginx も自前でコンパイルします。
また、HTTPS 化には、秘密鍵、公開鍵、証明書が必要です。これについては、いろいろなサイトで解説されています。文献6にも詳しく書いてあります。
すでに、秘密鍵、公開鍵、証明書について理解が進んでいるものとします。
前半は Apache のメモ。
後半は Nxinx です。


Apache 編
Sec-1.まずTCP443ポートを開けてみる
Sec-2.SSLを有効にしてみる
Sec-3.443 番ポート をHTTPS とし、80 番ポートを HTTP にする
Sec-4.80番ポートに来たアクセスを 443番ポートに飛ばす
Sec-5.Apache のコンパイルについて
Sec-6.SSL サーバ証明書の購入
Sec-7.SSL サーバ証明書の有効期限更新

Nginx 編
Sec-11. 設定ファイル
Sec-12. その他、雑感

.


Sec-1.まずTCP443ポートを開けてみる

 Apache は以下のような設定ファイルとします。

###################  httpd.conf #######################
ServerRoot "/var/www"

Listen 80
hogehoge
hogehote

LoadModule hogehoge
LoadModule ......................
  ......................
  ......................
  ......................


<IfModule unixd_module>
User  daemon
Group daemon
</IfModule>

ServerAdmin **************
ServerName  www.quinos.net

  ......................
  ......................
  ......................

######################################################

 ここで、単純に Listen 443 を Listen 80 の後に一行加えてみます。よくTCP/IP の説明だと 80 は HTTP、 443 は HTTPS とか書いてあります。一行加えた後で普通に

http://www.quinos.net:443/

としたらアクセスできます。http://www.quinos.net:80/ としても同じ。
ただ単に、80 と 443 の二つの HTTP ポートが開いただけです。HTTPS じゃありません、(笑)


.


Sec-2.SSLを有効にしてみる

 1では HTTP ポートを二つ開けただけなので、今度は HTTPS 化してみます。ネットの解説等を探すと、例えば、こんな記述があります。

<IfModule ssl_module>
  SSLRandomSeed startup builtin
  SSLRandomSeed connect builtin
  SSLSessionCache  dbm:/var/www/logs/ssl_cache_file
  SSLSessionCacheTimeout 3600
</IfModule>
#
  SSLEngine   on
  SSLProtocol all -SSLV2
  SSLCertificateFile     /var/www/conf/ssl/server.crt
  SSLCertificateKeyFile  /var/www/conf/ssl/server.key

 server.crt はいわゆるCRTファイル。最初はCRTファイルはオレオレ認証でやってみます。server.key は鍵ファイルです。
SSLRandomSeed とか SSLEngine だとかの各ディレクティブは文献6に詳しく解説してあります。
試しに httpd.conf の中に上のステートメントをそのまま書いてみます。
また、ssl_module と cache のモジュールをロードするようにしておきます。
で、ブラウザで https://www.quinos.net/ とやると、以下のような表示が出て、ちゃんと HTTPS 化していることがわかります。
オレオレCRTなので、警告が出ています(笑)


https-access

ところが、この設定のままで
http://www.quinos.net/ と入力すると、以下の表示が出てしまいます。



not-http-access


ようするに「HTTP じゃだめだ。 HTTPS でアクセスしなさい」という表示です。
つまるところ、HTTPS(SSL) を使うための上記ステートメントをコンフィグファイルにべたに書き込むと、すべてにそれが適用されてしまいます。先ほどとは逆で、TCP80 も TCP443 も、両方とも HTTPS 化されてしまったわけです。
これでは、いささか、じゃなくてとっても具合が悪いです。



.


Sec-3.443 番ポート をHTTPS とし、80 番ポートを HTTP にする

 少しずつ、順に出来ることからやります。
上記2で一応 HTTPS 化は出来ました。
次に何をするか?
良くあるのは 80番ポートは従来どおりHTTP で開けておいて、アクセスが有るとこれを443番ポートに飛ばす。もちろん443番ポートに来たアクセスはそのまま HTTPS で対応する、というものです。
でも、いきなりやると難しいので、順に少しずつやります。
まずは

 としてみます。
この場合、VirtualHost ディレクティブが使えます。すなわち

<VirtualHost: *:80>
  hogehoge-1
  hogehote-2
</VirtualHost>

<VirtualHost: *:443>
  hogehoge-3
  hogehote-4
</VirtualHost>

 とすると、80番ポートに来たアクセスに対しては hogehoge-1 と hogehoge-2 が適用されて、443番ポートに来たアクセスに対しては hogehoge-3 と hogehote-4 が適用されます。
そこで、さっきの SSL のステートメントを VirtualHost の中に入れます。

###################  hddpd.conf #######################
ServerRoot "/var/www"

Listen 80
Listen 443
hogehoge
hogehote

LoadModule hogehoge
LoadModule ......................
  ......................
  ......................
  ......................
LoadModule ssl_module modules/mod_ssl.so
LoadModule socache_dbm_module modules/mod_socache_dbm.so


<IfModule unixd_module>
User  daemon
Group daemon
</IfModule>

ServerAdmin **************
ServerName  www.quinos.net

  ......................
  ......................
  ......................


<IfModule ssl_module>
  SSLRandomSeed startup builtin
  SSLRandomSeed connect builtin
  SSLSessionCache  dbm:/var/www/logs/ssl_cache_file
  SSLSessionCacheTimeout 3600
</IfModule>

<VirtualHost *:80>
#
</VirtualHost>

<VirtualHost *:443>
    SSLEngine   on
    SSLProtocol all -SSLV2
    SSLCertificateFile     /hoge/hoge/conf/ssl/server.crt
    SSLCertificateKeyFile  /hoge/hoge/conf/ssl/server.key
</VirtualHost>


######################################################

注:SSLRandomSeed と SSLsessionCache のステートメントは VirtualHost の中には置けません。

 これで試してみると HTTP も HTTPS も、うまくいきます。
ようやく 80番ポートは HTTP 、443番ポートは HTTPS となりました。後ちょっと



.


Sec-4.80番ポートに来たアクセスを 443番ポートに飛ばす

 上記3のコンフィグファイルにヒントがあります。80番ポート用の VirtualHost のところに、飛ばすためのステートメントを入れるだけです。
ネットで探して、適当に入れてみました(^^)
うちでは、以下の記述でうまくいきました。
なお、それぞれの html ファイルに meta を使って飛ばすやり方も上手くいきました。でも、そっちはすべての html ファイルに書き込まなくてはなりません。それより rewrite ディレクティブを使って、httpd.conf の中のステートメントで飛ばした方が楽ですね。(^^)
この飛ばすためのステートメントは下記のサイトを参考にしました。とても詳しく書いてあるので勉強になります。

   https://gist.github.com/koudaiii/8cb8e6a4f6daf180e0e5

著者さん、ありがとうございます。飛ばすためのステートメントは下記のようです。


  <IfModule rewrite_module>
    RewriteEngine  on
    RewriteRule  ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
  </IfModule>

 なお、上記ステートメントで分かるように rewrite のためには、 rewrite モジュールのロードが必要です。

LoadModule rewrite_module modules/mod_rewrite.so

 を一行 httpd.conf に加えてください。基本的には、これで出来上がりです(^^)

 これまで HTTP で開放していたウェブサイトを HTTPS 化すると、html ファイルの中の引用部など、かなりの書き換えが必要になります。各種ウェブサイトに注意事項が載っていますので、それらを参考にしてマメに html ファイルを書き換えてから HTTPS でサービス開始してください。これまでの html ファイルの書き方によっては、結構大変な作業です。(うちは、書き換え部分が少なくて楽だったですけどね・・・)

 実際にHTTPS(SSL)の証明書を買ってサイトを公開する時は、購入元から中間ファイルだとか、が与えられます。これはアパッチディレクティブで言うと SSLCertificateChainfile というものです。それをSSL の記述の中にいれておきます。例えば、与えられた中間ファイルをserver.chain と mv して

     SSLCertificateChainfile /hoge/hoge/conf/ssl/server.chain

 こんな感じのステートメントを <VirtualHost *:443> --- </VirtualHost> の中に書き込みます。


.


Sec-5.Apache のコンパイルについて

 apache のコンパイルについては、Chap-7. にまとめました。そっちを見てください。



.


Sec-6.SSL サーバ証明書の購入

 鍵ファイルやCSRファイルの作り方自体は、あちこちのサイトに載っています。良くそれらを読んでください。ここでは、私が SSL サーバ証明書の購入に戸惑った、その顛末を書いておきます。ようするに私の失敗談です(汗)

 wiki でSSLサーバ証明書を調べると、「公開鍵証明書」という表現で解説があります。詳しくは文献6や wiki 、さらに各種説明サイトを読んでもらえば良いですが、ここでは「認証局(CA)が証明してくれて、ユーザは代理店から証明書を購入する」とだけ理解してください。
実際には(大抵は・・・)ネット経由で買えます。代理店にアクセスして申し込めば、ものによっては証明書(ファイル)を即日入手出来ます。

一般に代理店は、複数の認証局の代理をやっていて、しかも各認証局が複数のSSLサーバ証明書を販売しています。
で、その複数のSSLサーバ証明書ごとに、鍵ファイルやCSRファイルの作り方が、微妙に違います。そこがややこしいところです。
大抵、どこの代理店も鍵ファイルやCSRファイルの作り方が認証局ごとに違っていることや、その作り方を、詳しくアップしています。なので、本来はそれを良く読んでトライすればすむことです。が、私はこのSSLサーバ証明書の購入に三日間の時間を要してしまいました。ちっともうまくいかなかった。トホホです。
(^^;;;

 簡単に、要点だけを書いておきます。下の表を見てください。私の場合の、CSRファイル(の一部)の例です。
CSRファイルを入力して、代理店からCRTファイル(SSLサーバ証明書)を買います。
私はさくらのドメイン認証型という証明書を買いました。年あたり972円。激安証明書なので有難いです(笑)
左側がうまくいかなかった事例。右はうまくいきました。CSRファイルを代理店にインプットする段階で失敗ばっかりでした。なんと、大文字小文字の使い分けか、あるいは、組織の記載欄のどちらかで弾かれていたのです。代理店の注意書きをもっと良く読むべきでした。

FQDN は、私の場合 www.quinos.net です。ここの欄もE-mail欄も小文字で大丈夫でした。private も小文字で入力しました。


CSR file

 私がボケなだけなのか、それとも CSR ファイルが思ったよりもデリケートなのか?
とにかく、いざ購入される場合は慎重にやりましょう。


.


Sec-7.SSL サーバ証明書の有効期限更新

(2019-06-10)

 2018年6月初旬に始めてサイトをHTTPS化して、一年がたちました。サーバ証明書を当初は1年もので契約しました。そろそろ有効期限更新の時期です。
丁寧にも、さくらインターネットから更新必要の通知が来ましたし、さっそくやります。


基本的な手順
Sec-3. 4. で示したように、今、自分のサイトの所定の場所(外からのブラウザで読めない場所)に

の3つのファイルが置いてあります(httpd.conf の中でそう設定しました)。このうち、鍵ファイルは継続して使います。証明書の有効期限更新時に変更しなくても良いです。
なので、証明書と中間ファイルの2つを更新します。
基本的な手順は、さくらのウェブサイトにマニュアルがあり、そこに書いてあります。

https://help.sakura.ad.jp/hc/ja/articles/360000000401

手順はシンプル。

以上が更新の手続きです。基本的に、当初購入時と同じです。


CSR の作成

$ openssl req -new -key server.key -out server.csr -sha256

とすればCSRファイルが生成されます。(注:これは jprs のドメイン認証型の場合のやり方です)
server.key は自分が使っている鍵ファイルの名前。-out server.csr で出力ファイルの名前を指定します。
以下は、私がやったときの上記コマンドの入力例です

Country Name (2 letter code) [AU]:JP ーーーーーー ここは絶対に大文字、笑
State or Province Name (full name) [Some-State]:Hoge
Locality Name (eg, city) []:Hogehoge
Organization Name (eg, company) [Internet Widgits Pty Ltd]:private
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:www.quinos.net
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

上記6.で私はe-mail アドレスを入力しちゃいました。でもマニュアルの注意書きを良く読むと「入力するな」と書いてありますね(笑)
なので、今回は一年前の反省を踏まえて(?)入力しませんでした。(笑)


認証ファイルのアップ及び証明書と中間ファイルのインストール
認証ファイルは32バイトのテキストファイル。長い名前です。これを /hoge/hogehoge/htdocs/.well-known/pki-validation/hogege.txt とかに置きます。htdocs は自分のウェブサイトの場所(ドキュメントルート)です。
30分もすると、自分のサーバが本当に動いているかのチェックが済んで、メールが来ます。証明書発行したってことと、中間ファイルを持ってけってこと。
これらは簡単にダウンロード出来ますので、以下、自分のサイトの所定の場所に置いておくだけ。

 以上の作業で、証明書の更新が済みました。
当初は2018年6月7か8日に購入しました。その結果、有効期限は2019年6月30日までとなりました。購入月の月末までらしいです。
今回、二年分の更新をしたので次の有効期限は2021年6月30日までとなります。ちゃんと、期限切れの日から二年にしてくれますので、作業は早めにやっても大丈夫です(笑)





*2021年6月にまた更新しました。今回は2年のメニューが見当たらなくて、一年更新としました。次の更新は2022年6月です。
*2022年6月更新うまくいきました、笑。今回も一年更新のメニューしかありませんでした。
*2023年6月更新うまくいきました。延長期間二年のメニューは完全に無くなりました。去年は一台はインストールしてもう一台にインストールを忘れました。今年はちゃんとやります、やるつもりです、笑。
*2024年6月更新うまくいきました。多分以下同、笑。料金は当初から変わらず年額990円なので有り難いです。

  










ここから下は Nginx 関連です。

.


Sec-11.設定ファイル

2024-10
 前に書いた Apache は順に出来ることを進めていって、最終的に

 としました。
が、今回は一気に設定ファイルのポイント部分を書きます。というのは、Apache に比較して Nginx は設定ファイルが分かりやすく簡単だからです。肝心の部分だけを下記に示します。

http {
    hoge
    hoge
    ------

    server {
        listen  80;
        server_name www.quinos.net  quinos.net;
        return 301 https://www.quinos.net$request_uri;
    }

    server {
        listen       443 ssl;
        ssl_certificate         /hoge/hoge/ssl/bundle.crt;
        ssl_certificate_key     /hoge/hoge/ssl/server.key;
        ssl_protocols           TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers             HIGH:!aNULL:!MD5;

        server_name  www.quinos.net;

        hoge
        hoge
        hoge
        -----

    }

}

 なんとなく、すぐに理解できそうな記述方式です。
http://www.quinos.net (80) と http://quinos.net (80) に来たアクセスを https://www.quinos.net (443) に飛ばしています。
ここまでは apache に比較して簡単でした。ややこしかったのは認証に必要なファイルの置き方でした。
Apache では 証明ファイル、鍵ファイルの他に中間ファイル(chain filre)を置くための記述がありました。
以下の如き具合でした。

    SSLCertificateFile          /hoge/hoge/conf/ssl/server.crt
    SSLCertificateKeyFile       /hoge/hoge/conf/ssl/server.key
    SSLCertificateChainfile     /hoge/hoge/conf/ssl/server.chain

 ところが Nginx だと中間ファイルを置いておくための記述方法がありません。
最初は「要らないのかなあ・・・」なんて考えて、置かずにやってみました。
ところが、何度やっても認証エラーで繋がりません。自分としては記述の仕方が悪いと思い込んで、そっちばかりを検討し続けました。
が、何度トライしてもダメ。ネットで色々と調べて書いてもダメ。
困りました。
Apache の時はもっと簡単に繋がったんですがね。
そのうち、どうにかして中間ファイルを置かないとダメなのか? と思い始めました。で、ネットで検索して理解しました。
Nginx では通常の証明書(証明ファイル)の後半に中間ファイルを連結して、1つのファイルにして置いておくようです。
Apache では server.crt としていたファイル名を bundle.crt に変えたのはそれが理由です。bundle.crt は証明書(証明ファイル)と中間ファイル(chain file)を一つに連結したものです。私は emacs を使って連結しました。
結局、これで無事に https の接続が出来るようになりました。


 初めて https に挑戦したときは証明書の購入が出来なくて丸三日間もがきました。
今回は、中間ファイルの置き方が分からなくて一時間くらい悪戦苦闘しました。
https についてはいつもなにがしか苦労します、笑。





.


Sec-12.雑感、その他

雑感
 以下は Nginx を試してみて、あるいは使い始めて感じたことです。雑感。

 こんなところです。
コンパイルは以下のようでした。Apache 等のコンパイルに必要な諸々の開発セットがすでにマシンに入れてあったので、追加開発セットは大体において不要でした。Debian-12、SUSE(leap)15.6、Slackware-15 で簡単にコンパイル出来ました。メインラインでも安定版でも同じようにコンパイル出来ます。(注:Debian の CUI インストールだと libzip-dev を追加でインストールする必要がありました)
下記のコンパイルオプションが最適なのかどうか、そこまでは言えません。うちで運用する分には、下記で大丈夫なようです。

$ ./configure --prefix=hoge/hoge  --with-http_ssl_module
$ make -j N
# make install



その他
 クラック狙いのアクセスへの対応について

 http サーバを運用するとすぐに分かりますが、クラック狙いのアクセスが頻繁に来ます。世界中からきます、笑。
うちでは、それらのアクセスに対して過去数年間に渡り厳しい対応をしてきました。
明らかにクラック狙いのアクセスと、クラック狙いっぽいなあと思われるアクセス。その両者に対して対応してきました。
 ところが最近になってネット記事で自分が想像していなかった事柄の説明を読みました。始めて知りました。「ボッコなスマホのボッコなブラウザは https に際しておかしなコードを送出するバグがある・・・」とか。
これを読んで焦りました。もしかしたら自分がこれまで厳しい対応をしてきたクラック狙いと思われる(思われた)アクセスの一部は、クラック狙いではなくて、単に
「スマホがボッコなだけなのに・・・」
ってヤツかもしれません。
以下のような例です。uri だけを示します。

\x00\x0E8\xBFF\xD39\x18\xFEW\xEB\x00\x00\x00\x00\x00

\x16\x03\x01\x00\xCA\x01\x00\x00\xC6\x03\x03\xD9\xFD\x88\xBDe\xC6\x8D\xD2\xD4A\x12=\x89\xF8\xDEK\xED\x0C

\x16\x03\x01\x00{\x01\x00\x00w\x03\x03\xAF\xC3<\xAA\x8Dw\xEF8;4P\xD6\xE0X\x81\xC0\xF0t\xC5m\xB8\x17\x16\xCF88\xB5\xD2/\xC7\x00\x00\x1A\xC0・・・・・長く続く

\x16\x03\x01

 うーん・・・・・?? なんなんでしょう?
ボッコなスマホが出すおかしなコードがこの中にあるのかどうか、該当行だけを見ていても判断出来ません。
これまでは、これらのアクセスのほとんど全てに厳しい対応をしてきました。が、過剰対応の可能性が出てきたのでしばらくはこの手のアクセスに対してのみ対応を一旦保留しています。
現在、過去のログを見直しながらクラック狙いのアクセスと、スマホがボッコなだけのアクセスを区別しようと試みています。スマホがボッコなだけのは、救済したいし。
ただし区別する基準を見つけるのはやっかいです。もしかしたら、頑張ってみたけど結局判別出来なくてもとの「これら全てに厳しく対応する」ってやり方に戻すかもしれません。本意ではないですが、判別出来なければ仕方ないです。
頭が痛いです、笑。「スマホがボッコなだけなのに・・・」なんて笑ってる場合じゃないです、笑。


 HTTP のクラック対策は SMTP のスパム対策よりも手がかります。ただしクラック対策と言っても実際のところ上記の様なアクセスでクラックは出来ません。なので厳密に言えばログファイルがばばっちくなるのを防止するための対策です。


2024-10-22 補足
 ログチェックしてみても、結局区別出来ませんでした。仕方ないので9月頃の設定に戻しました。
このため今は上記のようなアクセスは基本的に全部厳しく対応します。本意ではないですが区別出来ないので仕方ないです。