Certbotを使って Conoha+Kusanagi(nginx/centos7) に無料でSSL/TLC証明書をインストール・自動更新する方法は過去に書いた。“無料でSSL/TLC証明書を手に入れる”
CertbotサイトにOSとWebサーバの組み合わせを入力すると対応するインストール手順が表示される。メジャーな組み合わせであれば証明書の取得から自動更新まで全自動でやってくれる。
2016年7月現在、AWS(EC2)は未対応のため、Certbotツールを使って試行錯誤する必要がある。Certbotの一次情報をもとに何とかやってみたので記録を残しておく。
- AWS(EC2)にCertbotでSSL/TLC証明書をインストールする
- ElasticBeanstalkのロードバランサに取得した証明書を登録しhttpsでアクセスできるようにする
- 自動更新のセットアップを行う
AWS(EC2)にCertbotを使ってSSL/TLC証明書をインストールする
いくつか前提がある。
- ドメインは取得済みであること。
- ドメインがElasticBeanstalkのIPアドレスを指すようにRoute53を設定済みであること。
- EC2インスタンスにSSHでログインできるようにしておく。
- Certbot利用時、外部からEC2インスタンスにhttpでアクセスを受ける。ElasticBeanstalkにRoutingを変更するようなアプリがデプロイされているとアクセスが失敗するのでDocumentRootにindex.phpがあるだけという状態にしておく。
- SSL/TLC証明書をインストールするだけなら443番を開けておく必要はない。ロードバランサはデフォルトの80番だけ開けていれば良い
- EC2インスタンスのrootパスワードが設定済みであること
- AWS CLIがインストール済みであること。
- IAMで証明書登録ポリシーを付与済みであること。
さっそくEC2インスタンスにログイン。基本的にec2-userで作業する。
一応下記を実行。
1 2 3 4 |
$ sudo yum install epel-release Loaded plugins: priorities, update-motd, upgrade-helper Package epel-release-6-8.9.amzn1.noarch already installed and latest version Nothing to do |
Certbotをダウンロードする。
1 2 |
$ wget https://dl.eff.org/certbot-auto $ chmod a+x certbot-auto |
Certbotを実行してみる。その際、–debugオプションを付けないと怒られる。would like to work on improving it と言っておきながら –debug がmust。きっと実行内容がCertbotに送られるのだろう。
1 2 3 4 |
$ ./certbot-auto WARNING: Amazon Linux support is very experimental at present... if you would like to work on improving it, please ensure you have backups and then run this script again with the --debug flag! |
指示通り、–debugオプションを付けて実行してみる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ ./certbot-auto --debug ... Installed: augeas-libs.x86_64 0:1.0.0-5.7.amzn1 dialog.x86_64 0:1.1-9.20080819.1.5.amzn1 libffi-devel.x86_64 0:3.0.13-11.4.amzn1 python27-tools.x86_64 0:2.7.10-4.120.amzn1 system-rpm-config.noarch 0:9.0.3-42.27.amzn1 Complete! Creating virtual environment... Installing Python packages... Installation succeeded. Requesting root privileges to run certbot... /home/ec2-user/.local/share/letsencrypt/bin/letsencrypt --debug Version: 1.1-20080819 Version: 1.1-20080819 No installers are available on your OS yet; try running "letsencrypt-auto certonly" to get a cert you can install manually |
いろいろインストールされる。/home/ec2-user/.local/share/letsencrypt/ 以下にPython27 が入る。今回の試行錯誤では自力でPythonを上げなかった。たぶん、自力でPythonのバージョンを上げなくてもコレが使われるんじゃないか。
肝心のインストーラはインストールされず、”letsencrypt-auto certonly”というコマンドを実行せよ、と出る。が、これはtypo。
No installers are available on your OS yet; try running “letsencrypt-auto certonly” to get a cert you can install manually
ディレクトリを移動する。
1 |
$ cd /home/ec2-user/.local/share/letsencrypt/bin |
ここにある certbot コマンドを叩く。ドメイン名、メールアドレスを指定する。
1 |
sudo ./certbot certonly -d hoge.com --agree-tos -m hoge@hoge.com --debug |
すると、中途半端にグラフィカルな画面が表示される。簡易Webサーバを起動するか、現在のWebサーバのDocumentRootを教えるか、2択となる。簡易Webサーバだとどうしても上手くいかなかった。Webサーバを上げたまま(ElasticBeanstalkのヘルスチェックがOKの状態)、DocumentRootを指定すると上手くいった。
うまくいくと、以下のようなメッセージが表示される。
1 2 3 4 5 6 7 8 9 10 11 |
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/arst.me/fullchain.pem. Your cert will expire on 2016-09-29. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le |
/etc/letsencrypt/live に証明書が作られている。なお、live には ec2-user でアクセスできない。ここでrootに昇格。
1 2 3 4 5 6 7 |
$ su - # cd /etc/letsencrypt/live # ls hoge.com # cd hoge.com # ls cert.pem chain.pem fullchain.pem privkey.pem |
ElasticBeanstalkのロードバランサに証明書を登録する
AWS CLI経由で証明書を登録する。その際、IAMにてポリシーを追加しておく必要がある。過去エントリを参照のこと。成功するとJSONで登録情報が返る。ここでは、HogeCertification という名前で登録を行っている。
1 2 3 4 5 6 7 8 9 10 11 12 |
$ aws iam upload-server-certificate --server-certificate-name HogeCertification --certificate-body file://cert.pem --private-key file://privkey.pem { "ServerCertificateMetadata": { "ServerCertificateId": "ASCAI***********A6F5GI", "ServerCertificateName": "HogeCertification", "Expiration": "2016-09-29T01:57:00Z", "Path": "/", "Arn": "arn:aws:iam::281631559249:server-certificate/HogeCertification", "UploadDate": "2016-07-01T03:10:18.440Z" } } |
ElasticBeanstalkのロードバランサの設定で、証明書欄から HogeCertification を選べるようになる。選んで 443/HTTPS を通すようにすれば、晴れて https://独自ドメイン/ で ElasticBeanstalk の URL が開く。
証明書の自動更新
更新自体はcertbot renewコマンドで行う。certbot renewコマンドは/var/www/html/.well-known/以下にファイルを置いて外部から開きにくる。困ったことに、CakePHPやLaravelアプリをデプロイしているとフレームワークのルーティング機能により上手くいかない。
以下の戦略で対応する。
- certbot renew 時だけ、DocumentRoot を アプリ用からcertbot用に切り替える
- Laravel等のように DocumentRoot がサブディレクトリにオフセットされている場合に対応する
ElasticBeanstalkで自動生成される環境を見ると、/var/www/html が /var/app/current へのシンボリックリンクとなっている。Certbot renew を叩くときだけ、シンボリックリンクを差し替える。
1 2 3 4 5 |
$ cd /var/app $ sudo mkdir -p certbot/project/public $ sudo chown -R webapp:webapp certbot $ cd /var/www $ sudo ln -s -f /var/app/certbot html |
また、certbot用の.well-knownディレクトリが /var/www/html 直下に作られる仕様になっている。DocumentRootはさらに project/public にオフセットされているため、/var/www/html/project/public/.well-known が /var/www/html/.well-known を指すようにシンボリックリンクを作成する。
1 2 |
$ cd /var/app/certbot/project/public $ sudo ln -s ../../.well-known |
この状態で certbot renew –dry-run を叩くと無事成功する。
1 2 3 4 5 6 7 8 9 10 |
$ pwd /home/ec2-user/.local/share/letsencrypt/bin $ sudo certbot renew --dry-run ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates below have not been saved.) Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/ikuty.com/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) |
シンボリックリンクの作成は一度だけで良いが、アプリ用とCertbot用のシンボリックリンク張替は都度必要となる。
以下のシェルスクリプトをcronで叩けば良い。
1 2 3 4 5 6 7 8 9 10 11 |
#!/bin/bash cd /var/www sudo unlink html sudo ln -s -f /var/app/certbot html cd ~ pwd sudo ./.local/share/letsencrypt/bin/certbot renew --debug cd /var/www sudo unlink /var/www/html sudo ln -s -f /var/app/current html |
不要な更新は実行されないため、1日2回の頻度で実行してよい旨、ドキュメントに記述がある。
Note: if you’re setting up a cron or systemd job, we recommend running it twice per day (it won’t do anything until your certificates are due for renewal or revoked, but running it regularly would give your site a chance of staying online in case a Let’s Encrypt-initiated revocation happened for some reason). Please select a random minute within the hour for your renewal tasks.