lego と Cloud DNS で Let's Encrypt の自動更新
気づいたらブログの証明書の期限が切れていた。めんどくさて数日放置していたけど、 さすがにエンジニアとしてまずいだろうということで自動化することに。
Let’s Encrypt (DNS-01)
使用していたのは Let’s Encrypt の証明書。証明書は ACMEというプロトコルを使用して 発行されるが、その手順の中で「ドメインの所有者どうか」といった認証がある。
この認証によく使われているのはHTTP-01
だが、今回はDNS-01
を使っている。
- DNS-01 の流れ
- ACMEクラインアントが Let’s Encrypt に
challenge
を要求 - 受け取った
challenge
を _acme-challenge.harasou.jp の TXT レコードにセット - Let’s Encrypt が TXT レコードの
challenge
を確認できれば証明書発行
- ACMEクラインアントが Let’s Encrypt に
自動化にあたって、ACMEクライアントには golang製の lego を利用し、API経由での操作が 必要なDNSプロバイダには Google の DNS サービスである Cloud DNS を使った。
lego のセットアップ
ACMEクライアントとしては Certbot が有名だが、今回は golang 製の lego を 利用することにする。
# Linux-AMD64用のバイナリ
curl -L https://github.com/xenolf/lego/releases/download/v0.4.1/lego_linux_amd64.tar.xz | tar Jxvf - lego_linux_amd64
sudo install -o root -g root -m 755 lego_linux_amd64 /usr/local/bin/lego
バイナリ一つ落としてくれば良いので便利。最新の release を落としてきて、パスが通った ディレクトリに配置しておく。
Cloud DNS 更新の準備
Cloud DNS を lego から更新するためには サービスアカウント の作成が必要 (たぶん)。 対象のプロジェクトで、DNS の操作をサービスアカウントに許可し、lego からの利用時に 必要な key を取得しておく。
gcloud iam service-accounts create sa-lego --display-name="lego service account"
gcloud iam service-accounts list
gcloud projects add-iam-policy-binding harasous-garden --member=serviceAccount:sa-lego@harasous-garden.iam.gserviceaccount.com --role=roles/dns.admin
gcloud iam service-accounts keys create key.json --iam-account=sa-lego@harasous-garden.iam.gserviceaccount.com
パラメータ | 説明 |
---|---|
sa-lego | サービスアカウントの名前。なんでもよい |
harasous-garden | プロジェクトID。Cloud DNS があるプロジェクト |
sa-lego@harasous-garden.iam.gserviceaccount.com | サービスアカウントのEMAIL。サービスアカウント名とプロジェクトIDで決まる |
roles/dns.admin | サービスアカウントの役割 |
key.json | 保存する key のファイル名 |
Google の IAM については、全然わかってないので、他にちゃんとしたやり方がありそう (Cloud KMS とか)。
証明書の取得と更新
いざ、証明書の取得。Cloud DNS を使う時に必要な変数を設定して、lego コマンドを実行。
うまく行くと ~/.lego/certificates
配下に証明書が作成される。
GCE_PROJECT="harasous-garden" \
GCE_DOMAIN="harasou.jp" \
GCE_SERVICE_ACCOUNT_FILE="key.json" \
lego --domains=harasou.jp --email=harasou5+letsencrypt@gmail.com --dns=gcloud run
cron に以下のような感じで登録すれば、2ヶ月に一回勝手に更新される。便利。
GCE_PROJECT="harasous-garden"
GCE_DOMAIN="harasou.jp"
GCE_SERVICE_ACCOUNT_FILE="key.json"
00 00 01 */2 * /usr/local/bin/lego --domains=harasou.jp --email=harasou5+letsencrypt@gmail.com --dns=gcloud renew && sudo systemctl reload nginx.service