やーまんぶろぐ

気が向いた時にだけ書くブログ

Let’s Encrypt SSL証明書を自動更新する方法 AWS Nginx編

Let’s Encryptは最近流行り?の無料の証明書のことです。自動更新するスクリプトが既に用意されているのが良いですね。
本番での使用ではなく、開発環境で使用を検討中。

この記事では、AWS上で動くNginxのSSL証明書を自動更新する方法について書いていきます。

一部こちらのリンクを参考にしました。
postd.cc

ドメインの購入

ドメインを持ってない場合は事前に購入しておきましょう。
yamano3201.hatenablog.jp

Nginxの80番ポートの設定追加

nginx.confの80番ポートをlistenしているところで、/.well-knownの設定を追加しておきましょう。
Let’s Encryptから/.well-knownにアクセスすることでドメイン認証を行っているようです。

server {
    listen 80;
    location '/.well-known' {
        root        nginxのルートPATH;
    }
}

SecurityGroupの設定変更

開発環境なので、普段は特定のアドレスからしか開けていない想定です。
AWS側の設定変更で一時的に80番ポートをフルオープン(0.0.0.0/0)にします。
オープンしておかないと、Let’s Encryptから/.well-knownにアクセスすることができません。
f:id:yamano3201:20160423105959p:plain

ここはセキュリティ的に良くないので、検討する必要があります。

証明書の取得

それでは実際に取得してみましょう。

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto --help # 実行できなければ--debug を付ける
./letsencrypt-auto certonly --webroot -w nginxのルートPATH -d 購入したドメイン

実行すると、メールアドレスを聞かれますので入力して同意しましょう。
f:id:yamano3201:20160423104426p:plain

f:id:yamano3201:20160423104628p:plain

Nginx にhttp_ssl_moduleを追加する

次の設定に入る前に、私の環境ではsslのところでエラーが出てしまったのでsslのモジュールが入っているか確認しておきましょう。
nginx -V してhttp_ssl_module がなければ、追加しておきましょう。

qiita.com
configureするときは今の設定に追加して実行するようにしましょう。

./configure --prefix=/etc/nginx \
--with-ld-opt="-Wl,-rpath,/usr/local/luajit/lib" \
--add-module=../ngx_dynamic_upstream\
--add-module=../nginx_upstream_check_module \
--without-http_gzip_module \
--with-http_ssl_module

※実際の設定ではありません。あくまで例です。

Nginxの443番ポートの設定追加

nginx.confの443番ポートをlistenしているところで、証明書の設定を追加してreloadします。

server {
    listen 443 ssl;
    # ssl_certificate "xxxxxxxxxxxx";
    # ssl_certificate_key "xxxxxxxxxxxxx";
    ssl_certificate "/etc/letsencrypt/live/購入したドメイン/fullchain.pem";
    ssl_certificate_key "/etc/letsencrypt/live/購入したドメイン/privkey.pem";
}

※既に設定が入っている場合は、その設定をコメントアウトしておきましょう。
※証明書取得前にこの設定を入れると、Nginxが起動できないので注意しましょう
ssl_certificateには、certではなくfullchainを指定しましょう

ブラウザから確認

ブラウザからhttpsでアクセスしてみましょう。
無事にNginxの画面が見れて、Let’s Encryptの証明書が設定されていることが確認できればOKです。

気になる点

気になる点を列挙していきたいと思います。

証明書の追加と更新は同じコマンドでいけるのか

同じcertonlyでいける。更新の場合は、更新かどうかを聞かれます。
f:id:yamano3201:20160423110513p:plain

ワイルドカードは使えるか

Wildcard domains are not supported: *.riicho.net
ワイルドカードは使えませんでした。

アクセス制限はどうするか

開発環境なので80番ポートをフルオープンにはしたくないのでいくつか考える必要がありますね。
luaで特定のドメインだけアクセスを許すようなコードを書けるのではと考え中。

こちらの「【EC2のNginxの設定】セキュリティについて考える」でも同じところで悩んだので、近いうちに検証します。
yamano3201.hatenablog.jp

鍵作成時の確認画面はオプションで飛ばすことはできるか

初回は --email admin@example.com と、--agree-tos で飛ばせそうでした。更新時は --renew-by-default で飛ばせました。

証明書更新失敗に気付けるかどうか

opensslのコマンドで日付は確認できるので、外部から監視することはできそうですね。要検討。

さまざまなデバイスやサービスから使用できるか

LINE BOT APIではLet’s Encryptが使用できない(現在は使えるらしい)ということがあったように、古いデバイスからでもアクセスできるかなど検証が必要ですね。

Nginxを冗長化した場合の証明書の扱いはどうするか

2台で別々に更新かけると中身が違うけどいいのかな。1台で更新して、2台目に送りこむようなことをしないといけないのか。。開発環境だし割り切るかな。。

自動更新する方法

あとはcronで回すだけです。
隔月1日の5:00に実行するcron例になります。

00 05 01 */2 * /usr/local/letsencrypt/letsencrypt-auto certonly --webroot -w NginxのルートPATH -d 購入したドメイン --renew-by-default && /etc/init.d/nginx reload

最後に

更新作業もめんどくさいですが、社内の購入手続きが何よりめんどくさい。
Let’s Encryptを導入して少しでもラクできるといいなぁと思って検証してみました。

気が向いたら、また書きます。