certbotを使ってサイトをhttps化した
6月5日から変わっています。wwwも付いたり付かなかったりだったのを付いてない方に統一しました。
- 旧: http://www.songmu.jp/riji/
- 新: https://songmu.jp/riji/
アーカイブ 見ると、徐々にはてブが移行されているっぽくて面白い。
令和にもなったし、301を返していれば、はてブも統合されるようになったので、流石に充電期間中httpsにするかーと思っていた。
令和にもなるのにまだhttpなんですか!? (Firebase Hostingを使っています https://t.co/H1lG4NChq1
— Daisuke Murase (@typester) 2019年4月18日
今どきのオシャレな方法で実現しようかとも思ったが、結局時間が取れなかったので、今のVPSのNginxからRijiで生成した静的ファイルを配信する方式を維持したまま、certbotでぱぱっとやってしまった。非常に簡単だった。同様の事例はたくさんあるが、メモがてらログを残しておく。
- 環境構築
- 証明書の発行
- サーバー設定
- 証明書の更新
- 更新自動化
環境構築
リポジトリをcloneするだけ。
% git clone https://github.com/certbot/certbot.git
% cd certbot
% ./certbot-auto ...
以降、certbot-auto
というコマンドを使って各種操作をおこなうことになりますが、こいつを叩くと、追加依存のインストールや、自動更新、sudoでの実行など諸々よしなにやってくれる。ツールの特性上、自動更新がちゃんとされるのは安心。ただ、いろいろ頑張っているからか、起動はかなり遅く、もっさりしている。致し方ないか。
証明書の発行
以下のようなコマンド実行するだけ。今回はNginxが既に実稼働しているサーバーなので、そのwebrootを指定している。
./certbot-auto certonly --webroot \
--webroot-path /home/Songmu/htdocs \
--domain songmu.jp \
--email y.songmu@gmail.com \
--agree-tos -n
/etc/letsencrypt
配下に証明書や諸々が書き込まれる。
サーバー設定
/etc/letsencrypt/live/ドメイン
以下に証明書が配置されるので、Nginxであれば以下のように書いてやれば良い。
server {
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/songmu.jp/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/songmu.jp/privkey.pem;
server_name songmu.jp;
証明書の更新
これも非常に簡単で、以下のコマンドを実行すれば良い。
./certbot-auto renew --post-hook 'sudo service nginx reload'
特にドメインの指定などが必要ないのは、/etc/letsencrypt/renewal
以下に /etc/letsencrypt/renewal/songmu.jp.conf
のような設定ファイルが書き込まれているため。
ドメイン期限が1ヶ月以内に迫っているときだけ更新をしてくれる親切仕様になっている。また、--post-hook
は証明書が更新された時のみ実行される便利フック設定。ここではNginxのリロードを指定している。 certbot-auto renew && sudo service nginx reload
などとしてしまうと証明書が更新されてなくても毎回リロードかかってしまうので、ちょっと困る。
上記のコマンドは、実行しても証明書を発行したばかりの時はスキップされるので、更新動作を確認したい場合は、--force-renewal
を指定して動作確認をしてみると良いでしょう。ただ、--force-renewal
はLet's Encryptのサーバーへの負荷の観点もあり、普段は使わないほうが良いオプションです。
更新の自動化
cronを適当に仕込んでおけばよいが、certbot-autoもNginxのリロードもsudoが必要で、cronでsudoを使えるようにするのは大変。つまり、sudoersのrequirettyのユーザー設定と、パスワード無しでsudoができるコマンドを指定するなどが必要。
めんどい上にセキュリティを緩めることにもなるので、それは避けて普通にrootのcronで動かすようにしてしまった。
# /etc/cron.d/certbot-renew
37 18 * * 5 root /usr/bin/mkr wrap -n certbot-renew -- /home/Songmu/certbot/certbot-auto renew --post-hook '/sbin/service nginx reload'
ちゃんと動くか少し不安なので、mkr wrap
を使ってMackerel監視するようにした。便利。
これも、Let's Encrypt側のサーバー負荷の観点から、実行時間を散らすためにランダムスリープなどを入れることが望ましいとされています。実際Debianでパッケージインストールした場合は、 perl -e 'sleep int(rand(3600))' && certbot -q renew
というようなcron設定がなされるようです。Perlが使われていてウケる。
それをやっても良いのですが、日次じゃなくて、週次(5なので毎週金曜日)で動かすようにしたので、まあそれでいいでしょう、ということで。