無料SSL証明書であるLet's Encryptの正式版がリリースされ、誰でも簡単にSSL/TLS証明書を導入できるようになりました。 この記事では、Let's Encryptの概要から、CentOS+Nginx上にこれを設置する方法について解説します。

動作環境

この記事の内容は、以下の環境において動作を確認しています。

  • さくらのVPS v4
  • CentOS v6.8
  • Nginx v1.11.1
  • Certbot v0.8.1

注意事項

この記事では、SSLサーバ証明書を設置するための、必要最低限の解説を行ないます。

実際のサーバ運用に必要な各種セキュリティ設定(ファイアウォールなど)には言及しません。 これについては必要に応じて設定することを想定しています。

また、本記事に関する予備知識としてSSL/TLSの仕組みもあわせてご覧ください。

Let's Encryptとは

Let's Encryptは、「認証局としてSSLサーバ証明書を無料で発行するプロジェクト」です。

ただ無料で発行するだけでなく、専用のソフトウェアにより発行〜更新のプロセスを自動化しています。 これにより、サーバ管理者にSSL導入を促進させ、これを広く普及することを目的としています。

次のような特徴があります。

1. 対応ブラウザ

SSLサーバ証明書は、クライアントのブラウザが搭載するルート証明書により検証されるため、その信頼性が求められます。

Let's EncryptのSSLサーバ証明書は、広く普及しているIdenTrustのクロスルート証明書であり、このためほとんどのブラウザに対応することができます。

2. SSLサーバ証明書の種類

Let's Encryptで取得できるSSLサーバ証明書はドメイン認証型となります。

このため、発行の際には、サーバ管理者がドメインの所有者であることを確認できる必要があります。

3. 有効期限

Let's Encryptが発行するSSLサーバ証明書の有効期限は90日間です。 これは、更新頻度を多くすることで、サーバ管理者にプロセスの自動化を促進するためでもあるようです。

SSLサーバ証明書の取得〜設置方法

それでは、Let's EncryptでSSLサーバ証明書を取得し設置する方法について以下に示します。

なお、Let's Encryptはドメイン認証型の証明書なので、独自ドメインからの正引きでIPアドレスに到達できている必要があります。

ここでは、ドメイン名をexample.comとして説明を進めます。

1. Certbotをインストールする

Certbotとは、Let's Encryptの各種作業を行なうためのクライアントソフトウェアです。 まずはこのCertbotをインストールします。

これはGitリポジトリをクローンするだけで完了します。

$ git clone https://github.com/certbot/certbot

2. SSLサーバ証明書を取得する

次のコマンドで、SSLサーバ証明書を取得するためのプロセスが実行されます。 画面の表示にしたがって進めます。

$ cd certbot/
$ ./certbot-auto
$ ./certbot-auto certonly --standalone -d example.com

なお、作業を進めるには次の必要があります。 ファイアウォールの設定やサーバソフトウェアの停止など、必要な作業を行なっておきます。

  • 80/443番ポートを開放していること
  • ソフトウェアなどで80/443番ポートをListenしていないこと

最終的に、以下のような表示がされれば完了です。

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/example.com/fullchain.pem. Your cert
   will expire on 2016-09-25. To obtain a new or tweaked version of
   this certificate in the future, simply run certbot-auto again. To
   non-interactively renew *all* of your certificates, run
   "certbot-auto renew"

3. Nginxをインストールする

今回はサーバソフトウェアとしてNginxを用いるため、これをインストールします。

まず、リポジトリ情報を追加するために次のファイルを作成します。

/etc/yum.repo.d/nginx.repo:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/rhel/$releasever/$basearch/
gpgcheck=0
enabled=1

インストールは次のコマンドで行ないます。

$ yum install nginx

4. Nginxの設定をする

次に、SSLサーバ証明書を設置するための必要最低限の設定を行ないます。 必要なセキュリティ対策は次章以降で示します。

/etc/nginx/conf.d/default.conf:

server {
  listen 80;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;

  ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  root /usr/share/nginx/html;
}

動作確認する

以上で、https://example.com/にアクセスするとSSLの設定完了が確認できると思います。

次に、SSL通信に関するセキュリティ対策について解説していきます。

セキュリティ対策を行なう

このままでは、脆弱性のあるSSLプロトコルの使用など、セキュリティ対策が完全ではありません。

ここでは、客観的な評価手法として、SSL Server TestでA+の評価を得るための設定を示します。

1. プロトコルをTLSのみに制限する

SSLにはPOODLEに代表される脆弱性が存在するため、SSLプロトコルの使用許可は推奨されていません。

次の設定で、クライアントからのSSL要求を制限し、TLSのみ許可します。

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

2. Forward Secrecyに対応する

Forward Secrecyとは、簡単に言うと「鍵が漏洩した場合でも、それまでの暗号化された通信内容が解読されない」という性質です。 これは、鍵交換方式としてECDHを指定すればよいです。

暗号スイートはssl_ciphersで指定します。 なお、以下の指定はMozillaが公開しているSecurity/Server Side TLSを参考に設定しています。

ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';

なお、次の記事:

によると、Forward Secrecyに完全に対応するには、Session Ticketの問題を解決する必要があります。

このSession Ticketの暗号化に使われるマスターキーを定期的に更新しない限り、マスターキーが流出してしまった場合、過去の通信内容がすべて解読されてしまうことになるのです。

ロードバランサを使用しない場合はssl_session_ticketsoffにすればよいですが、そうでない場合の設定は本記事のテーマから外れてしまうため、ここでは言及しません。

こういった問題があることだけ把握しておき、必要に応じて対策するようにします。

3. HTTP Strict Transport Security

HTTP Strict Transport Securityとは、HTTPの代わりにHTTPSを用いて通信を行なうよう、サーバからクライアントに伝達するための機能です。

これは、次の設定で有効化することができます。

add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains' always;

設定のすべて

以上の設定をまとめると、以下のようになります。 SSL Server TestでA+の評価を得られることが確認できると思います。

/etc/nginx/conf.d/default.conf:

server {
  listen 80;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;

  ssl on;

  ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';

  add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains' always;

  root /usr/share/nginx/html;
}

冒頭でもことわりましたが、これはSSLサーバ証明書を設置するための必要最低限の設定です。 実際の運用にはその他にもセキュリティ対策を含む様々な設定が必要になりますが、この記事では言及しません。

更新を自動化する

最後に、SSLサーバ証明書の更新を自動化します。 これはcronで対応します。

以下は、毎月1日の4:00に証明書を更新し、Nginxを再起動するコマンド例です。

$ crontab -e
00 04 01 * * /path/to/certbot-auto certonly --webroot -w /usr/share/nginx/html -d example.com --renew-by-default --post-hook 'service nginx reload'

なお、証明書取得の際は80/443番ポートを空ける必要がありましたが、Webrootプラグインを用いることにより、Nginxを停止することなく更新することができます。

あわせて読みたい

おわりに

以上で、無料でSSLサーバ証明書をサーバに導入することができます。 非常に簡単に導入でき、更新も自動化できるため、これまで以上にサイトのSSL化対応が容易になったと思います。

SSL化の際は、ぜひ参考にしてみてください。