はじめに
最近はあらゆるサイトを HTTPS 化しましょうってことで HTTP だとブラウザが警告を出すようになってしまいました。ただ情報を掲載しているだけのサイトで果たして HTTPS 必要か、という議論はさておき、このような風潮となったのは Let's Encrypt で SSL 証明書が無料で導入できるようになったという背景があることは間違いないでしょう。そこで今回は、すでに散々量産されているであろう Let's Encrypt の導入についての記事です。
まず、発行される証明書は有効期限が 90 日しかないです。そこで certbot を使って自動更新する運用とし事実上無期限で利用するのがセオリーなのですが、ワイルドカード証明書だとちょっと厄介です。最近はワイルドカード証明書もちょっとした hack で自動更新できるようですが、そこは複数ドメイン指定で乗り切ることにします。ちなみにウェブサーバーは Apache とします。
パッケージ導入
sudo apt install -y letsencrypt certbot python-certbot-apache
証明書取得
ドメイン部分や webroot は適当に読み替えてください。
sudo certbot certonly --webroot -w /var/www/html/current -d hoge.co.jp -d domain1.hoge.co.jp -d domain2.hoge.co.jp -d domain3.hoge.co.jp
ハマりポイント
これをやると /var/www/html/current/.well-known/acme-challenge/FX5JCVj29PQIBMh47oamNhEFQCiXqEJRv_XXXXXXXXX のように一時ファイルが webroot 以下に作成される。そしてそのファイルが外から参照できるかどうかでサイトの実在性を確認している模様。
つまりサーバーが外からアクセスできることを前提に動作します。外に直接公開していないサーバーでやる場合は standalone オプションを利用すれば良いが、この記事では割愛します。
当然ながら例えば .htaccess で以下のようにしたりしていると .well-known 配下が参照できないので失敗します。
RedirectMatch 403 /\..*/
他にもパーミッションなど設定を確認し、一時ファイルにアクセスできるような環境を用意すれば良いでしょう。なお一定回数失敗すると 1 時間ほどロックアウトされる模様。
設定
SSLCertificateFile /etc/letsencrypt/live/yourdomainname/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yourdomainname/privkey.pem
これらはシンボリックリンクになっており、実体のファイルは更新されるごとにファイル名が連番で変化し、シンボリックリンクが最新のものに向き変わる仕様。
自動更新
以下のような cron ジョブが自動的に設定される。任せておけば良いです。
# /etc/cron.d/certbot: crontab entries for the certbot package
#
# Upstream recommends attempting renewal twice a day
#
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc. Renewal will only occur if expiration
# is within 30 days.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew
環境が変わるなどしたら、以下のコマンドで証明書の自動更新をテストできます。
certbot --dry-run renew
以上です。