Let's encrypt の証明書の更新( Cloudflare/DNS-01 )
スポンサーリンク
CDNとしてCloudflareを利用している環境で、Let's Encrypt の証明書を更新した際のメモ。
証明書を取得した際にはCloudflareは利用していなかった。
前提
新規の取得ではなく、既存証明書の更新作業。Cloudflare のCDNを一時的に無効化するのはなんか負けた気がするので認証方法を変更する。
通常の認証方式ではなく、DNSのtxtレコードを利用するDNS-01方式を使う。
Let's Encrypt のサーバーに証明書の発行を依頼すると、一時的に有効なトークン文字列が送られてくるので、これをDNSのtxtレコードに記載するという方式。 Webサーバーがなくても利用できるし、今回のようなCDN環境やNAT利用時にも証明書の取得・更新が可能。
DNSの設定変更は面倒であるが、Cloudflare の場合はプラグインがややこしい作業はやってくれる。このプラグインとLet's Encrypt のコマンドさえインストールすればいい。
セットアップ
Ubuntu 16.04 標準のletsencrypt
パッケージを諦めて、新しくcertbot
*1をインストールする。
選択肢は下記の4つ。
Let's Encrypt の公式リポジトリのパッケージは微妙に古いうえにCloudFlare用のプラグインパッケージを含まない。本来であればOSのお作法に従うべきなので 1. が最有力だが肝心の Cloudflare用のプラグインを別途入れる必要がある。管理の手間が増えるのは好ましくない。
妥協案として4. のpip
コマンド経由でインストールする。
$ sudo apt install python-pip $ pip install certbot-dns-cloudflare
インストール先がpip
コマンドを実行したユーザーのホームディレクトリ配下である点に注意する。
Credential ファイルの作成
API キーを記載したクレデンシャル(Credential : 信任状)ファイルを作成する。
$ vi /etc/letscrypt/cloudflare.ini
書式は以下のとおり。
dns_cloudflare_email = cloudflare@example.com dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234567
Cloudflare に登録したメールアドレスと、Global API Key
を記載する。APIキーはCloudflareにログインして右上のメールアドレスをクリックするとメニューが表示されるのでそこから”My Profile"を選択すると表示される。
誰でも読み取れるのは好ましくないので、パーミッションを変更しておく。
$ sudo chmod 600 /etc/letscrypt/cloudflare.ini
パーミッションが不適切だと下記の警告メッセージが表示される。
Unsafe permissions on credentials configuration file: /etc/letsencrypt/cloudflare.ini
参考:certbot/init.py at master · certbot/certbot · GitHub
テスト
$ sudo /path/to/certbot renew --dry-run --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini
/path/to/
の箇所は環境に応じて変更。
テストに成功すると以下のようなメッセージが表示される。
------------------------------------------------------------------------------- ** 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/www.example.com/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) -------------------------------------------------------------------------------
更新
--dry-run
オプションを外して実行。
$ sudo /path/to/certbot renew --dns-cloudflare --dns-cloudflare-credentials /etc/let sencrypt/cloudflare.ini
成功時のメッセージは以下のようになる*3。
------------------------------------------------------------------------------- new certificate deployed without reload, fullchain is /etc/letsencrypt/live/www.example.com/fullchain.pem ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/www.example.com/fullchain.pem (success) -------------------------------------------------------------------------------
あとはwebブラウザに設定をリロードさせておく。
$ sudo systemctl reload nginx
次回以降の更新
一度証明書の更新に成功すると設定ファイルも自動的に更新されるのでややこしいオプション指定は不要になる。
$ sudo /path/to/certbot renew
cronによる自動更新
証明書の有効期限は90日。一ヶ月前から更新できるはず。
月に一回のチェックでは心もとないので週に一回実行する。更新可能期間に入ると残り日数にかかわらず更新する。
/etc/cron.weekly/
に、letsencrypt
というファイルを作成する。
$ sudo vim /etc/cron.weekly/letsencrypt
更新スクリプトの例。
#! /bin/bash if [ ! -d /tmp/letsencrypt-auto ] ; then mkdir -p /tmp/letsencrypt-auto fi cd /tmp/letsencrypt-auto /usr/local/bin/certbot renew && systemctl reload nginx
chmod +x
で実行権限を付与しておく。
更新されなかったときのメッセージ
ドメイン名は実際のものとは別。あまり役に立つかはわかりませんが一応。Ubuntu側の設定を変更していなければ管理者宛にメールで結果を送信されるはず。
Saving debug log to /var/log/letsencrypt/letsencrypt.log ------------------------------------------------------------------------------- Processing /etc/letsencrypt/renewal/www.example.com.conf ------------------------------------------------------------------------------- Cert not yet due for renewal ------------------------------------------------------------------------------- The following certs are not due for renewal yet: /etc/letsencrypt/live/www.example.com/fullchain.pem (skipped) No renewals were attempted. -------------------------------------------------------------------------------
更新に成功したとき
更新に成功したときの出力。
Saving debug log to /var/log/letsencrypt/letsencrypt.log ------------------------------------------------------------------------------- Processing /etc/letsencrypt/renewal/www.example.com.conf ------------------------------------------------------------------------------- Cert is due for renewal, auto-renewing... Plugins selected: Authenticator dns-cloudflare, Installer None Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org Renewing an existing certificate Performing the following challenges: dns-01 challenge for www.example.com dns-01 challenge for support.example.com dns-01 challenge for text.example.com Starting new HTTPS connection (1): api.cloudflare.com Starting new HTTPS connection (1): api.cloudflare.com Starting new HTTPS connection (1): api.cloudflare.com Waiting 10 seconds for DNS changes to propagate Waiting for verification... Cleaning up challenges Starting new HTTPS connection (1): api.cloudflare.com Starting new HTTPS connection (1): api.cloudflare.com Starting new HTTPS connection (1): api.cloudflare.com ------------------------------------------------------------------------------- new certificate deployed without reload, fullchain is /etc/letsencrypt/live/www.example.com/fullchain.pem ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/www.example.com/fullchain.pem (success) -------------------------------------------------------------------------------
まとめ
初回からDNS-01 方式で証明書を取得しておくと面倒がなくていいと思う。