普段は ELB や CF で証明書をサクッと作成してるのですが、EC2 単体だと ACM が使えないので自分で証明書を作成する必要が出てきます。 証明書の更新などで考慮事項があったので共有します。
概要
Let’s Encrypt は数ある認証局の中でも無料で SSL 証明書を発行してくれます。
Certbot は無料かつ自動で SSL 証明書を発行できるツールです。
CSR と KEY ファイルの作成から Web サーバーの設定まで自動で行ってくれます。
さらに Cron と組み合わせることで、証明書の更新作業までも完全に自動化することが可能です。
証明書の署名と発行は Let’s Encrypt と呼ばれる認証局によって行われます。
https://avinton.com/academy/creating-ssl-certificate-by-certbot/
Let’s Encrypt + Certbot のメリット
- 無料
- ブラウザのオレオレ証明書を使用した際などの警告画面が出ない
- Certbot が鍵作成などの作業を自動でやってくれる
- 更新作業が自動化できる
- ただし更新時にセキュリティが若干危うくなったり(HTTP 認証の場合ポートを公開する必要がある)、過剰な機能をサーバーに持たせる必要が出る(DNS 認証の際にスクリプトでレコードを更新する)
- 上記が嫌な場合は手動で更新作業が必要
オレオレ証明書のメリット
- 更新作業が不要
- 更新期限を好きに設定できるため
前提
OS: AmazonLinux2023 WEB サーバー: apache インストール済、Route53 の権限を持った IAM ロールを付与済み ドメイン: example.com(Route53 で管理)
Certbot のインストール
インストール方法はたくさんあるのですが、今回は Python のパッケージ管理の pip でインストールします。 https://certbot.eff.org/instructions?ws=apache&os=pip
# 必要なパッケージをインストールします。
sudo dnf install -y python3 augeas-libs
# venv作成
python3 -m venv /opt/certbot/
# pipを最新版にアップグレードします。
sudo /opt/certbot/bin/pip install --upgrade pip
# CertbotとCertbotのApacheプラグインをインストールします。
sudo /opt/certbot/bin/pip install certbot certbot-apache
# Certbotの実行可能ファイルへのシンボリックリンクを作成します。
sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot
SSL 証明書作成
DNS 認証と呼ばれる方式で SSL 証明書の作成を行います。 HTTP 認証と DNS 認証があるのですが、HTTP 認証はサーバーをパブリックインターネットに公開する必要があるので、セキュリティを考慮すると DNS 認証が良さそうです。
DNS 認証は、Let’s Encrypt が指定したワンタイムトークンを DNS の TXT レコードとして登録し、Let’s Encrypt のサーバー側でそのレコードが確認できれば、証明書が取得できます。
DNS レコードの追加・削除の処理が必要なのですが、今回 Route53 を使っているので AWS API を使用すれば、追加・削除がスクリプトで行えそうです。 この場合、certbot-dns-route53 という便利なプラグインが使えます。
# プラグインのインストール
sudo /opt/certbot/bin/pip install certbot-dns-route53
# SSL証明書の取得
sudo certbot certonly --dns-route53 -d example.com -d *.example.com
SSL 証明書の更新
Let’s Encrypt は 90 日で期限が切れるので、定期的な更新が必要です。 今回は cron を利用して、certbot renew コマンドで更新します。
# cronコマンドのインストールと自動起動有効化
sudo dnf install -y cronie
sudo systemctl enable crond
# 毎月1日にcertbot renewを実行する
echo "0 0 1 * * root sudo certbot renew --dns-route53" | sudo tee -a /etc/crontab > /dev/null
apache に SSL の設定を行う
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/html
SSLEngine on # ★
SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem # ★
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem # ★
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem # ★
</VirtualHost>
systemctl restart httpd
これで対象のドメインに HTTPS でアクセスすることができるようになってると思います。