Nwht0xn1

Let's EncryptとAmazon LinuxとNginxでamakan.netをHTTPSに対応させたCreated on 2016-07-03 by r7kamura

https://amakan.net/ というサービスをHTTPSに対応させたので記録を。

Let's Encrypt

実は使ったことが無かったので色々調べてLet's Encryptを使ってみた。Let's Encrypt以前はβ版だったが、2016年4月から正式なサービスとして運用されるようになったらしい。調べてもまだβ版時代の情報が沢山出てくるが、大きく変わることはないはず。https://letsencrypt.jp/ に日本語情報があって助かる。

Let's Encryptは、git cloneでレポジトリごと取得して、中に含まれている実行可能ファイルを実行するという形式で動作させる。自分は /usr/loca/letsencrypt に配置することにした。以下のコマンドで依存しているライブラリなどがインストールされる。この方式で依存ライブラリを入れる方法は色々と制御しづらい部分が出てくるので気に食わないが、仕方ないので従っておくことにする。なお、Amazon Linuxで使うには --debug を付ける必要がある。

sudo /usr/loca/letsencrypt/letsencrypt-auto --debug --help

次にLet's Encryptの認証サービスと通信を行いながら認証鍵などをダウンロードするためのスクリプトを動かす。amakan.net は今回対象としているドメイン名。また、/home/alice/amakan/current/public は提供するサービスのドキュメントルート (Railsを利用していてUnicornでデプロイしていると大体こうなる)。

sudo /usr/loca/letsencrypt-auto certonly --debug --webroot -d amakan.net --webroot-path /home/alice/amakan/current/public

これで証明書が /etc/letsencrypt/live/amakan.net/fullchain.pem に、秘密鍵が /etc/letsencrypt/live/amakan.net/private.pem に配置される1ので、これらのファイルをNginxの設定で指定することになる。

Serverkitを利用して自動化することを考えたが、サーバ設定とドメイン設定との対応が1対1ではないので、Let's encryptについては手動対応することにした。Let's encryptを使うような規模のサービスであればどうせ小規模なサービスだろうということを考えると問題ないだろうという判断。

Nginx

nginxの設定はこういう感じにしてみた。最初は add_header Strict-Transport-Security 'max-age=63072000'; のような設定を書いていたが、どうやらRailsがStrict-Transport-Securityヘッダを付けてくれるらしいので、二重になるのを避けるために消した。

server {
  listen 443 ssl http2;
  server_name amakan.net;

  ssl on;
  ssl_buffer_size 8k;
  ssl_certificate /etc/letsencrypt/live/amakan.net/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/amakan.net/privkey.pem;
  ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
  ssl_ecdh_curve secp384r1;
  ssl_session_tickets off;
  ssl_dhparam /etc/nginx/dhparam.pem;
  ssl_prefer_server_ciphers on;
  ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
  ssl_session_cache shared:SSL:3m;
  ssl_session_timeout 10m;
  ssl_trusted_certificate /etc/letsencrypt/live/amakan.net/fullchain.pem;

  # Enable OCSP Stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8;
  resolver_timeout 5s;

  root /home/alice/amakan/current/public;
  error_page 404 /404.html;
  error_page 500 502 503 504 /500.html;
  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_pass http://unicorn;
  }
}

サービス側

Amazonの商品画像がHTTPになっていたので、HTTPSで商品画像を返すように修正した。これについては Amazon Product Advertising APIで得られた画像のHTTPS版を利用する - Programming という記事を書いた。

結果

手元のGoogle Chromeから接続してみたところ、上手くいっている模様。

image

https://www.ssllabs.com でもう少し詳しく調べた限りでも問題なさげ。

image


  1. 実際にはこれはシンボリックリンクになっている