Chap-12. Website の HTTPS 化 (2018-06-06当初、2019-06-10更新)


前提

 いつものとおり、自宅サーバが前提です。言ってみれば、趣味のサーバとか、SOHOレベル。なので1台のサーバにドメイン一つ。簡単な条件です。
「今まで HTTP でサーバを公開していて、これから常時 HTTPS 化する」というケースを想定します。
なお、Apache は自前でコンパイルする。また、設定ファイルは httpd.conf という名前とします。modules は /var/www/modules ディレクトリとします。
また、HTTPS 化には、秘密鍵、公開鍵、証明書が必要です。これについては、いろいろなサイトで解説されています。文献6にも詳しく書いてあります。
すでに、秘密鍵、公開鍵、証明書について理解が進んでいるものとします。
ここでは Apache の設定に絞って記述します
このチャプターの動作確認で、Apache バージョン 2.4.33 を使っています。


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 サーバ証明書の有効期限更新

.


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

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

###################  hddpd.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 とか書いてあります。一行加えた後で・・・・

https://www.quinos.net/

などとブラウザに入力しても、www サーバのウェブサイトにアクセス出来ません。まあ、当たり前ですが、普通に

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

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


.


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     /var/www/conf/ssl/server.crt
    SSLCertificateKeyFile  /var/www/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 /var/www/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年もので契約しました。そろそろ有効期限更新の時期です。
丁寧にも、さくらインターネットから更新必要の通知が来ましたし、さっそくやります。


基本的な手順
今、自分のサイトの所定の場所(外からのブラウザで読めない場所)に

の3つのファイルが置いてあります。このうち、鍵ファイルは継続して使います。証明書の有効期限更新時に変更しなくても良いです。
なので、証明書と中間ファイルの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日までとなります。ちゃんと、期限切れの日から二年にしてくれますので、作業は早めにやっても大丈夫です(笑)