let's encrypt の証明書を作ってみた
let's encrypt ってなに?
HTTPS 通信に必要な証明書を無料かつ、半自動で取得できる仕組みです。
無料で本当に使えるの?
ちゃんと使えます。 ただ、古いブラウザやガラケー()のサイトに使うのは時は注意が要ります。
特にガラケーは引っかかると思いますが、中間証明書が必要で中間証明書を含む certificate chain の検証に対応しないブラウザでは、無効な証明書として扱われてしまいます。これは無料だから、こうなっていると言うわけでもなく、有料ながら格安証明書の RapidSSL でも同様で、中間証明書が必要になります。
証明書の取得に必要なものは?
大きく二つ必要です。
- 所有しているドメイン
- 公開されている Web サーバ
当然と言えば当然です。
一般的な SSL サーバ証明書を取得する時に必要な CSR や、格安証明書を取得する時に必要なドメイン名のメールアドレスも不要です。
Ubuntu 14.04 LTS で let's encrypt の証明書を取得する
サーバの準備
EC2 の t2.micro インスタンスに Ubuntu 14.04 LTS (HVM) なイメージで OS はセットアップしてます。SSH ログインは説明しないので、気合いで何とかしてください。
EC2 のセキュリティグループは 22 番ポートしかデフォルトで空いてないので、80/443 ポートを開けるのをお忘れ無く。
前準備に以下のコマンドを流して必要なものをインストール&再起動します
$ sudo apt update $ sudo apt-get upgrade $ sudo apt-get install gcc build-essential libpcre3-dev zlib1g-dev libssl-dev libevent-dev curl git $ sudo reboot
ドメインの準備
ドメイン名は A レコードで登録を行う必要があり、EC2 で割り当てられたグローバル IP を使って、ドメイン名を登録します。 このエントリでは、 test.tnamao.net の証明書を取得します。
nginx-build/nginx インストール
$ wget https://github.com/cubicdaiya/nginx-build/releases/download/v0.6.9/nginx-build-linux-amd64-0.6.9.tar.gz $ ./nginx-build -d work -v 1.9.11 --prefix=/home/ubuntu/nginx --with-http_ssl_module $ cd work/nginx/1.9.11/nginx-1.9.11/ $ make install
supervisor のインストール
$ sudo apt-get install supervisor
続いて、 nginx の起動設定を supervisor に追加します。
/etc/supervisor/conf.d/nginx.conf を作成
内容は下記を参照
[program:nginx] command=/home/ubuntu/nginx/sbin/nginx -g "daemon off;" user=root autorestart=true stdout_logfile=/var/log/supervisor/nginx.log stdout_logfile_maxbytes=1MB stdout_logfile_backups=5 redirect_stderr=true
supervisor の設定読み込みと nginx の起動確認
$ sudo supervisorctl reread $ sudo supervisorctl relaod
nginx が起動出来てると
$ sudo supervisorctl status nginx RUNNING pid 18325, uptime 1:54:11
こんな感じです。
let's encrypt の証明書作成
$ git clone https://github.com/letsencrypt/letsencrypt.git $ cd letsencrypt $ ./letsencrypt-auto --help
ここまで来たら、nginx を停止します。
$ sudo supervisorctl stop nginx
nginx を起動したまま、次のコマンドを実行すると怒られるので注意。
./letsencrypt-auto certonly --standalone --agree-tos --email namao.takeshi<at>gmail.com -d test.tnamao.net
これを実行すると、
- /etc/letsencrypt/live/test.tnamao.net/fullchain.pem に証明書
- /etc/letsencrypt/live/test.tnamao.net/privkey.pem に秘密鍵
が作られます。これで証明書の取得は完了です。
nginx を停止したのは、letsencrypt-auto コマンドを --standalone オプションを付けて起動すると、letsencrypt-auto コマンドが 80 番ポートを listen して、証明書の取得に必要な処理を行うためです。
nginx の SSL 設定と再起動
コメントアウトされていた設定を書き換えます
# HTTPS server # server { listen 443 ssl; server_name test.tnamao.net; ssl_certificate /etc/letsencrypt/live/test.tnamao.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/test.tnamao.net/privkey.pem; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { root html; index index.html index.htm; } }
そして、nginx を起動します。
$ sudo supervisorctl start nginx
ブラウザでアクセスして、証明書を確認
証明書を確認すると…
できた! \(^o^)/
証明書の更新
let's encrypt で取得した証明書は、デフォ設定だと 3 ヶ月間と短く頻繁に証明書の更新が必要ですが、コマンドを実行するだけで期限が延長された証明書を取得できます。
まずは nginx をやっぱり停止
sudo supervisorctl stop nginx
続いて、証明書の更新処理を行います。
$ cd ~/letsencrypt $ ./letsencrypt-auto renew -nvv --standalone
これを実行すると…
The following certs are not due for renewal yet: /etc/letsencrypt/live/test.tnamao.net/fullchain.pem (skipped) No renewals were attempted.
ありゃ、失敗しました。 期限切れを起こさないとコマンドが失敗してしまう模様で、強制的に更新を行うには --force-renewal オプションを付けないと行けないようです。
$ letsencrypt-auto renew --force-renewal -nvv --standalone
今度こそ…
new certificate deployed without reload, fullchain is /etc/letsencrypt/live/test.tnamao.net/fullchain.pem Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/test.tnamao.net/fullchain.pem (success)
できた\(^o^)/
これで、nginx を再起動して
$ sudo supervisorctl start nginx
証明書の更新は完了です。
証明書のファイルパス
証明書の更新をしても、nginx の設定は不要ですが、過去の証明書はどうなっているかと言うと、しっかり残っています。
まずは証明書のパスを調べると
$ sudo ls -l /etc/letsencrypt/live/test.tnamao.net/ total 0 lrwxrwxrwx 1 root root 39 Feb 20 08:16 cert.pem -> ../../archive/test.tnamao.net/cert2.pem lrwxrwxrwx 1 root root 40 Feb 20 08:16 chain.pem -> ../../archive/test.tnamao.net/chain2.pem lrwxrwxrwx 1 root root 44 Feb 20 08:16 fullchain.pem -> ../../archive/test.tnamao.net/fullchain2.pem lrwxrwxrwx 1 root root 42 Feb 20 08:16 privkey.pem -> ../../archive/test.tnamao.net/privkey2.pem
シンボリックリンクになっていて、実体は別の場所になっています。この archive の中を見ると
$ sudo ls -l /etc/letsencrypt/archive/test.tnamao.net/ total 32 -rw-r--r-- 1 root root 1797 Feb 20 07:11 cert1.pem -rw-r--r-- 1 root root 1797 Feb 20 08:16 cert2.pem -rw-r--r-- 1 root root 1675 Feb 20 07:11 chain1.pem -rw-r--r-- 1 root root 1675 Feb 20 08:16 chain2.pem -rw-r--r-- 1 root root 3472 Feb 20 07:11 fullchain1.pem -rw-r--r-- 1 root root 3472 Feb 20 08:16 fullchain2.pem -rw-r--r-- 1 root root 1704 Feb 20 07:11 privkey1.pem -rw-r--r-- 1 root root 1704 Feb 20 08:16 privkey2.pem
こんな感じで、インデックス番号が振られてアーカイブされているんですね。
まとめなど
let's encrypt どんな感じかなと思ってましたが…
- とりあえず無料で証明書が取れる
- CSR いらない
- 証明書の販売ベンダのフォームから申し込む必要がない
- メール受信とかも不要
- (一時的に Web サーバ落とす必要があるけど)証明書の更新も自動化できそう
とまぁ、割とメリットも多い感じに。
さすがに EV な証明書ではないので、サイトの提供元などの証明などが欲しい場合は有料の証明書を取らないといけないけど、個人サイトで HTTPS の暗号化のみを期待している場合は let's encrypt でも十分だと思いました。