nginxにHTTPSを設定

443 番で待たせる

証明書と鍵ができました。あとは nginx に「443 番でも待て、そのときはこの証明書を使え」と伝えるだけです。書く場所は 3 章で作った server ブロックの中です。

server { listen 80; listen 443 ssl; ssl_certificate /etc/ssl/certs/mysite.crt; ssl_certificate_key /etc/ssl/private/mysite.key; server_name mysite.local; root /var/www/mysite; ... }

足したのは3行です。listen 443 sslssl が、この番号では暗号化して話す、という指定です。これを書き忘れて listen 443 だけにすると、443 番で平文を話すサーバーになり、ブラウザからは何も読めません。

残り2行は、どの証明書とどの鍵を使うかです。ssl_certificate が公開する証明書、ssl_certificate_key が秘密鍵。名前が似ているので、逆に書いて起動しない、というのが定番の失敗です。

80 番の行は消さない

ここでは 80 番の待ち受けを残したままにします。次の回で、80 番に来た訪問者を 443 番へ送る仕組みを作るからです。いま消してしまうと、http:// で来た人が繋がらないサイトになります。

両方書けることが分かると、listen は 1 つの server ブロックに何行でも書ける、という感覚もつかめます。

反映と確認

手順はいつもの3手です。

nginx -t systemctl reload nginx

nginx -t は証明書と鍵が読めるかどうかも見ます。パスの書き間違いや、鍵の権限が厳しすぎて nginx から読めない場合も、ここで止まります。

警告が出るのが正しい

curl https://localhost/

これは失敗します

curl: (60) SSL certificate problem: self-signed certificate

壊れているのではありません。前々回に見たとおり、この証明書はブラウザや curl が信頼する一覧に入っていないので、拒まれるのが正しい動きです。ここでエラーが出ないほうがおかしいのです。

信頼の確認をあえて飛ばして中身を見るには、こう書きます。

curl -k https://localhost/

-k は、証明書の検証を省く指定です。これでページが返れば、暗号化そのものは成立していると分かります。足りないのは第三者の保証だけ、という状態が、この2つのコマンドの差にそのまま出ています。

-k は学習と検証のための指定です。本番のスクリプトで使うと、途中の誰かにすり替えられても気づけなくなります。安易に付ける癖を付けないでください。

どんな暗号で話しているかを見る

curl -kv https://localhost/ 2>&1 | grep -i 'SSL connection\|TLS'

-v を付けると、やり取りの詳細が出ます。TLS のどのバージョンで、どの暗号方式で合意したかまで見られます。設定を締めていくときは、ここを見ながら進めます。

ファイアウォールも忘れない

4章で 22 番と 80 番だけを通しました。443 番はまだ塞がったままです。

ufw allow 443/tcp

サーバー本体からの curl は通ってしまうので、この開け忘れは手元では気づけません。外から見えないという苦情で初めて分かる、という典型的な見落としです。待ち受けを足したら、通す設定も足す。4章の点検で見た噛み合わせの話が、そのまま出てきます。

手を動かす

自分のサイトを 443 番でも待たせ、暗号化された通信が成立するところまでを確かめます。ファイアウォールも合わせて開けます。

ヒント

  • 1. mysite.conf に listen 443 ssl; を足す。80 番の行は残す
  • 2. ssl_certificate と ssl_certificate_key で証明書と鍵を指定する
  • 3. nginx -t のあと systemctl reload nginx で反映する
  • 4. curl -k https://localhost/ > /root/https-ok.txt で中身を保存する
  • 5. curl https://localhost/ > /root/https-refused.txt 2>&1 で拒まれる様子を保存する。-s は付けない。そのあと ufw allow 443/tcp を打つ

10 項目で採点します