日記

日々のことと、Python/Django/PHP/Laravel/nodejs などソフトウェア開発のことを書き綴ります

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

ブラウザでアクセスして、証明書を確認

証明書を確認すると…

f:id:monajiro:20160220200333j:plain

できた! \(^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 でも十分だと思いました。