はじめに
サーバー証明書を無料で発行してくれるということでStartSSL(StartCom運営)を利用していましたが、不正な証明書を発行した、ということで信用を失ってしまったようです。主要ブラウザーで警告が表示されるようになってしまう、ということで、他の無料サービスであるLet’s Encryptでサーバー証明書を取得してみました。
SSH秘密鍵を生成してCSRを作成して…といった従来の手順とは異なり、サーバー実在証明のためにWebサーバーを起動しておく必要があるなど手順が少し複雑なのでまとめておきます。
(参照) Help with certbot on the new “Amazon Linux 2”
大まかな流れ
大まかな流れは下記の通りです。
- certbot-autoコマンドインストール
- certbot-autoの調整
- サーバー実在証明のためのWebサーバー構築
- certbot-autoコマンド実行
- サーバー証明書の適用
- (オプション)サーバー証明書の自動更新プログラムインストール
サーバー証明書のCSR作成からサーバー実在証明確認、サーバー証明書の受領までを自動的に実行してくれる、certbot-autoコマンドをインストールします。
WebサーバーはApacheでもNginxでも構いません。certbot-autoコマンドはサーバー実在証明のためのファイルをWebサイトのドキュメントルート直下に一時的に配置します。ドキュメントルート直下にファイルを作成されますが、apacheユーザーやnginxユーザーでcertbot-autoCommandを実行する必要はありません。今回はec2-userでサーバー証明書を作成・適用してみたいと思います。
手順
今回、OSはAmazonLinux (2017.03)、ユーザーec2-userで実施しました。
certbot-autoコマンドインストール
$ mkdir -p ~/bin
$ curl -L https://dl.eff.org/certbot-auto \
-o ~/bin/certbot-auto
$ chmod a+x ~/bin/certbot-auto
certbot-autoの調整
本投稿で一番キモになる部分です。certbot-autoはまだ(2018/07/01時点)でAmazon Linux2を認識できません。よって、「Amazon Linux2はAmazon Linuxと同じ扱いでよろしくねー」という旨にスクリプトを調整します。
~/bin/certbot-auto
$ cp ~/bin/certbot-auto ~/bin/certbot-auto.org
$ vi ~/bin/certbot-auto
$ diff ~/bin/certbot-auto.org ~/bin/certbot-auto
843c843,849
< elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then
---
> #elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then
> # Bootstrap() {
> # ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon
> # }
> # BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION"
> elif grep -i "Amazon Linux" /etc/issue > /dev/null 2>&1 || \
> grep 'cpe:.*:amazon_linux:2' /etc/os-release > /dev/null 2>&1; then
サーバー実在証明のためのWebサーバー構築
certbot-autoコマンドは、オプション「-w <ドキュメントルートディレクトリ>」に指定したディレクトリにディレクトリ「.well-known」というディレクトリを作成して、この中にドメイン認証用のファイルを一時的に生成します。ですので、WebサーバーがNginxであってもApacheであっても、ドキュメントルート以下にディレクトリ「.well-known」がcertbot-autoコマンドで自動的に作成されるんだな、とだけ認識しておけば大丈夫かと思います。
すでにWebサーバーが稼働している場合はそのWebサーバーのマニュアルを参照してください。Nginxの構築手順はこちらの投稿を参照して下さい。(通常、certbot-auto用に専用の設定は不要だと思います。)
certbot-autoコマンド実行
certbot-autoコマンドを実行します。うまく行けば、長々としたメッセージの中に、「- Congratulations! Your certificate and chain have been saved at:」という記述があるはずです。
$ certbot-auto certonly \
--webroot \
-w /var/www/www.example.com/public_html/ \
-d www.example.com \
-d example.com \
-m webmaster@example.com \
--agree-tos \
--debug
サーバー証明書の適用
「- Congratulations! Your certificate and chain have been saved at:」という記述の続きに、実ファイルは記載されていますので、Nginxにサーバー証明書をインストールする場合はこちらの投稿を参照してサーバー証明書のインストールを完了して下さい。
(オプション)サーバー証明書の自動更新プログラムインストール
ceretbotで発行したサーバー証明書の有効期限は90日です(参照: Why ninety-day lifetimes for certificates?)。また、更新しようにも残り30を超えて有効期限が残っていれば、certbotにより更新を拒否されます(参照: Renew says “Cert not yet due for renewal” though it is more than 30 days old)。
このため、私の場合は2週間に1回の頻度で自動更新をかけるようにしています(残り89日〜30日の間に実行すれば、certbotにより更新拒否されて手元の証明書に変更はなし。残り29日〜16日の間に実行すれば手元の証明書が更新される)。 早速、自動更新プログラムcertbot-renewを作成しましょう。
$ touch ~/bin/certbot-renew
$ chmod 755 ~/bin/certbot-renew
~/bin/certbot-renew
#!/bin/bash
/home/ec2-user/bin/certbot-auto renew
# (see also) /etc/letsencrypt/renewal/www.example.com.conf
#/home/ec2-user/bin/certbot-auto certonly \
# certbot-auto certonly \
# --webroot \
# -w /var/www/www.example.com/public_html/ \
# -d www.example.com \
# -d example.com \
# -m webmaster@example.com \
# --agree-tos \
# --debug
sudo systemctl reload nginx
# if CentOS6
#sudo service nginx reload
そう、実はcertbot-renewなる自前スクリプトを作成するまでもなく、certbot-auto renewコマンドを実行するだけでいいのです。が、どうせならnginxへの適用まで含めて、cronなどで自動化してしまいましょう。
$ crontab -e
# renew cert for www.example.com
0 15 * * mon /home/ec2-user/bin/certbot-renew | mail -s "LetsEncryptRenewLog for $(hostname)" hostmaster@example.com
おわりに
AmazonLinux2はCentOS7系のOSとなりました。従来のAmazonLinuxはCentOS6系です。AmazonLinux2はまだリリースされたばかりなので、この手の話題が多く出てくるかと思いますが、きっと将来、もっと楽に対応できるようになる事を願っております。