6715.jp

2017-07-08

lua-nginx-auto-sslで全自動HTTPS

sekaisekai
luanginxOpenRestySSLインフラ自動化

備忘録!

全自動HTTPS

Let's Encryptの登場でHTTPSがぐっと身近になりましたが、やっぱり証明書をホスト名毎に取得するのは結構面倒ですし、90日毎に更新しなきゃいけないのも大変です。

そこで、OpenResty(nginxにいろいろ足したやつ)にlua-nginx-auto-sslを入れて、全自動で証明書取得から更新までしてくれる環境を作りたいと思います。 例によってArchLinuxでやります。

インストール

OpenRestyを入れます。 AURからPKGBUILDを落としてきてmakepkgでパッケージを作ってインストールします。

git clone https://aur.archlinux.org/openresty.git
makepkg --syncdeps --install --skippgpcheck

lua-nginx-auto-sslのインストールにLuaRocksを使うので、同様にインストール。

git clone https://aur.archlinux.org/openresty_luarocks.git
makepkg --syncdeps --install

LuaRocksでlua-nginx-auto-sslを入れる。

/opt/openresty/luajit/bin/luarocks install lua-resty-auto-ssl

設定

Arch公式リポジトリのnginxと同じ感じの操作感にするために、いろいろシンボリックリンクを貼ります。

ln -s /opt/openresty/nginx/conf /etc/nginx
ln -s /opt/openresty/nginx/logs /var/log/nginx
ln -s /opt/openresty/bin/openresty /usr/bin/nginx
ln -s /usr/lib/systemd/system/openresty.service /usr/lib/systemd/system/nginx.service

lua-nginx-auto-sslで取得する証明書の鍵アルゴリズムとか、取得失敗時に使う自己署名証明書とかを用意。

mkdir -p /etc/nginx/ssl/letsencrypt/conf.d
printf 'KEY_ALGO="prime256v1"\nCONTACT_EMAIL="[email protected]"' > /etc/nginx/ssl/letsencrypt/conf.d/custom.sh
openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -keyout /etc/nginx/ssl/fallback_key.pem -out /etc/nginx/ssl/fallback_crt.pem -subj "/CN=NaruseJun/"
chown -R http:http /etc/nginx/ssl

/etc/nginx/sslは、lua-nginx-auto-sslが証明書を置いたりするのに使うディレクトリです。 後ほど、nginxの設定でこのディレクトリを指定します。

OpenRestyの実行ユーザ(Archのデフォルトはhttp)がこのディレクトリに書き込み出来ないと証明書の取得に失敗するので、chmodしています。

OpenSSL 1.0系を使う設定

lua-nginx-auto-sslが内部て使っているletsencryptクライアントのdehydratedはバージョンが少々古くて、OpenSSL 1.1系に対応していません。 ArchLinuxはOpenSSL 1.1系なので、このまま運用すると証明書が取得できているのにdehydratedが落ちてしまいます。 lua-nginx-auto-sslくんはアクセスが有るたびに証明書を取得しようとするので、あっという間にRateLimitに引っかかってしまいます……!

ということで、OpenSSL 1.0系を使ってくれるようにdehydratedをパッチします。

pacman -Sy openssl-1.0
sed -i "2a shopt -s expand_aliases\nalias openssl=openssl-1.0\n" /opt/openresty/luajit/bin/resty-auto-ssl/dehydrated

nginxの設定

lua-nginx-auto-ssl特有の設定をいろいろ入れないといけません。

lua-nginx-auto-sslのドキュメントを読めば大体わかりますが、 ハマる可能性のあるポイントをいかにリストアップしておきます。

  • resolverを必ず設定する
  • ホスト毎に必ずlocation /.well-known/acme-challenge/の設定を入れる
  • auto_ssl:set("allow_domain", ...)を必ず設定する

全部設定したのがコレです。

動かす

systemctl start nginx
systemctl enable nginx

初回アクセス時は、証明書の取得が完了するまでレスポンスが返ってこないので、ちょっと時間がかかります。 途中で作った自己署名証明書が使われてしまう場合は、証明書の取得に失敗しています。 /var/log/nginx/error.logにエラーメッセージが出力されているので、確認しましょう。

おわり

これで放っといても勝手に証明書を更新してくれたり、nginxの設定をコピーすれば新しいホストに対して証明書を発行してくれる環境ができました! lua-nginx-auto-sslを導入したので、このブログもSSL化してみました。

余談

Let's Encryptでワイルドカード証明書が発行できるようになるそうです。すごい。

追記

ワイルドカード証明書が発行できるようになりました。