今回は CentOS7 で Certbot
と BIND
を連携させてワイルドカード証明書の取得および自動更新の設定方法を紹介します。
手動でワイルドカード証明書の更新が面倒な方、Cloudflare ( クラウドフレア ) も嫌な方には DNS-RFC2136 方法がお勧めです。
Certbot の DNS-RFC2136 プラグインは、RFC 2136 Dynamic Updates ( 動的更新 ) を使用して TXTレコード
を作成 & 削除することにより、DNS01検証
が自動で行われます。
なので、一旦この環境を構築してしまえば、ワイルドカード証明書を一々管理する必要がなくなり、より楽に使用することができると思います
環境・条件
サーバ・パッケージ情報
- CentOS 7.6
- Apache 2.4.39 ( → Nginx でも動作 OK )
- BIND 9.9.4
- Certbot 0.34.2
[root@centos7 ~]# cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) [root@centos7 ~]# /usr/local/apache2/bin/httpd -v Server version: Apache/2.4.39 (Unix) [root@centos7 ~]# named -v BIND 9.9.4-RedHat-9.9.4-74.el7_6.1 (Extended Support Version) [root@centos7 ~]# # certbot --version certbot 0.34.2
Certbot・BIND の設置場所
- Cerbot Work Directory: /etc/letsencrypt
- BIND 設定ファイル:/etc/named.conf
- BIND Work Directory : /var/named.conf
DNSSEC を無効化しています。
#dnssec-enable yes; #dnssec-validation yes; // DNSSEC無効化 dnssec-enable no; dnssec-validation no; dnssec-lookaside no;
BIND の VIEW は internal と external に分離します。
view "external" { match-clients { any; }; match-destinations { any; }; include "/etc/named/named.example.com.zone.wan"; }; view "internal" { match-clients { localnets; }; match-destinations { localnets; }; zone "." IN { type hint; file "named.ca"; }; include "/etc/named.rfc1912.zones"; include "/etc/named.root.key"; include "/etc/named/named.example.com.zone"; };
それでは、環境を設定していきます。
関連パッケージをインストール
Certbot
と dns-rfc2136
プラグインをインストールします。
yum install certbot python2-certbot-dns-rfc2136
でインストールし、yum list installed | grep certbot
でパッケージを確認できます。
※ 既に設置されたパッケージがあれば /etc/letsencrypt
をバックアップし、全て削除してからインストールします。
# 削除 ( 任意 ) [root@centos7 named]# mv /etc/letsencrypt /etc/letsencrypt-bak [root@centos7 named]# yum remove -y `yum list installed | cut -d " " -f 1 | grep certbot` # 設置 [root@ centos7〜]# yum install epel-release [root@ centos7〜]# yum install certbot python2-certbot-dns-rfc2136 # 確認 [root@centos7 named]# yum list installed | grep certbot certbot.noarch 0.34.2-3.el7 @epel python2-certbot.noarch 0.34.2-3.el7 @epel python2-certbot-dns-rfc2136.noarch 0.34.2-1.el7 @epel [root@centos7 named]#
DNS-RFC2136 における自動更新の流れ
「DNS-RF2136を使用したワイルドカード証明書の自動更新」環境を構築するため、どういう流れでいくのか整理しておきます。 ( 私見 )
この環境が構築されたら、CRON JOB
に登録 ( = 自動化 ) して、毎日2回(正午、真夜中)更新をチェックすることを前提にします。
- Step 1証明書の更新プロセスを開始
CRON JOB
に 毎日 2 回(正午、真夜中)更新するよう、登録することで自動開始できます。( 最後に登録します )
- Step 2ワイルドカード証明書の発行・更新をリクエスト
Certbot ▶︎ Let’s Encryptに、対象ドメインの証明書の発行・更新を依頼します。このステップは構築後自動で
Certbot
がやってくれます。( 対象ドメインのリストを Step 4 で設定します )
- Step 3ドメイン検証用のTXTレコードのトークンを発行し、照会リクエスト待つ!
Let's Encrypt
はそのドメインが有効なのかを含め検証するためのトークンを Certbot に渡して、検証準備が終わったら知らせろ!と指示します。Certbot
はBIND
と検証作業 ( Step 4、5 ) を始め、Let's Encrypt
はこの検証作業の完了報告 ( Step 6 ) を待ちます。( 設定不要!)
- Step 4BIND の TXTレコードの追加・更新リクエスト
ドメインを検証する方法として、BIND の TXT レコードを利用しますが、
Certbot
とBIND
はお互い連携されていませんので、このステップを我々が設定してあげる必要があります。この設定を完了すると、
Certbot
からBIND
に TXTレコードに対象ドメインの追加・更新の依頼が自動で行われます。( 要設定!)
- Step 5TXTレコードの追加・更新完了を通知
BIND
からドメインの検証準備ができたらCertbot
に知らせます。Step 4
と同じくお互い連携されていませんのでこのステップも設定が必要です。( 要設定!)
- Step 6TXTレコードの追加・更新完了を通知 ( 照会リクエスト )
BIND
からの検証準備 OK のサインを受けると、Certbot
はLet's Encrypt
に照会リクエスト
を送ります。( 設定不要!)
- Step 7TXTレコードを照会
Let's Encrypt
がBIND
の設定をみてドメインの検証を始めます。( 設定不要!)
- Step 8ワイルドカード証明書発行・更新
Let's Encrypt
はドメインの検証が成功 ( 照会成功 ) すると証明書を発行・更新してくれます。( 設定不要!)
- Step 9証明書を保存
Certbot
はその証明書を指定の場所に保存します。 - Step 10更新プロセスを終了
これから、保存された証明書をウェブサーバ側で設定して利用できます。
以上、自分なりの「DNS-RF2136を使用したワイルドカード証明書の自動更新」の流れでした。
若干複雑に見えましたが、やることは Certbot
と BIND
を連携してあげることでした!
それでは、Step 4
を設定しましょう。
BIND の TXTレコードの追加・更新リクエストを設定
DNS-RFC2136
プラグインを使用するには、Credentials ( 認証情報 ) が含まれている設定ファイルが必要です。Credentials ( 認証情報 ) には、ターゲット DNS サーバーと、RFC-2136
動的更新をサポートするオプションのポート、TSIG キーの名前、TSIG キーシークレット、および使用されるアルゴリズムを含みます。
認証情報ファイルの例:
# Target DNS server dns_rfc2136_server = 192.0.2.1 # Target DNS port dns_rfc2136_port = 53 # TSIG key name dns_rfc2136_name = keyname. # TSIG key secret dns_rfc2136_secret = 4q4wM/2I180UXoMyN4INVhJNi8V9BCV+jMw2mXgZw/CSuxUT8C7NKKFs AmKd7ak51vWKgSl12ib86oQRPkpDjg== # TSIG key algorithm dns_rfc2136_algorithm = HMAC-SHA512
新しい SHA512 TSIG キーを生成します
TSIG キーの名前、TSIG キーシークレット、使用されるアルゴリズムは TSIG キーを生成 して取得できます。
BIND では3つの TSIG キージェネレーター ( dnssec-keygen
、rndc-confgen
、ddns-confgen
) コマンドを提供してますが、ここでは より優しい ddns-confgen
を使用します。
ddns-confgen
のいいところはコマンドを打つと詳しくガイドラインを標準出力してくれる点です。そのアウトプトにあるスクリプトを少し変更して使います。
書式:ddns-confgen [-a algorithm] [-h] [-k keyname] [-q] [-r randomfile] [ -s name | -z zone ]
-s name : ドメイン検証用ドメイン、例:_acme-challenge.example.com
keyname: -s の name のサブドメイン形で、例:ddns-key.name -> ddns-key._acme-challenge.example.com
ddns-confgen -a hmac-sha512 -k ddns-key._acme-challenge.example.com -s _acme-challenge.example.com # 参考 dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST ddns-key._acme-challenge.example.com
実行してみると、▼
[root@centos7 named]# ddns-confgen -a hmac-sha512 -k ddns-key._acme-challenge.example.com -s _acme-challenge.example.com # To activate this key, place the following in named.conf, and # in a separate keyfile on the system or systems from which nsupdate # will be run: key "ddns-key._acme-challenge.example.com" { algorithm hmac-sha512; secret "NbnwUKmAJT3LRwIrb7J28AwSTQmNOiXNLLn1El4HB5N5XTHxqfwnTVLOgTRM9YrGCK5X6q/Bz5TzKBXqCr1ydw=="; }; # Then, in the "zone" statement for the zone containing the # name "_acme-challenge.example.com", place an "update-policy" statement # like this one, adjusted as needed for your preferred permissions: update-policy { grant ddns-key._acme-challenge.example.com name _acme-challenge.example.com ANY; }; # After the keyfile has been placed, the following command will # execute nsupdate using this key: nsupdate -k <keyfile> [root@centos7 named]#
TSIG キー情報を別のファイルに保存します。
上記の ddns-confgen
のアウトプットの中でライン番号05〜08までの key "ddns-key._acme-challenge.example.com" {…}
部分をコピして別のファイルを作ります。( 場所は任意 )
[root@centos7 named]# vi /etc/named/ddns-key._acme-challenge.example.com key "ddns-key._acme-challenge.example.com" { algorithm hmac-sha512; secret "NbnwUKmAJT3LRwIrb7J28AwSTQmNOiXNLLn1El4HB5N5XTHxqfwnTVLOgTRM9YrGCK5X6q/Bz5TzKBXqCr1ydw=="; }; # 実行権限、所有権も変更しておきます。 [root@centos7 named]# chmod 600 ddns-key._acme-challenge.example.com [root@centos7 named]# chown named ddns-key._acme-challenge.example.com
Certbot 用の Credentials ( 認証情報 ) ファイルを作成します。( 場所・ファイル名は任意 )
※ dns_rfc2136_server
には localhost
や 127.0.0.1
を入力するとエラーになります。外部から参照できる IP アドレスを使ってください。
なお、dns_rfc2136_name
の最後には点 ( . ) を付けます。dns_rfc2136_port
以外は適宜変更して下記のように作成してください。
[root@centos7 certbot]# vi ~/.secrets/certbot/rfc2136-example.com.ini dns_rfc2136_server = 123.123.123.10 dns_rfc2136_port = 53 dns_rfc2136_name = ddns-key._acme-challenge.example.com. dns_rfc2136_secret ="XTKPevWdAjgWC2u3Hw86q5wHcVxfaPQlZLqBxxPak2bRt86FHdc2a0ifzL9QAsL1Az12fnv3oAiYJpd/kQt0kQ==" dns_rfc2136_algorithm = HMAC-SHA512 # 実行権限を変更 [root@centos7 certbot]# chmod 600 ~/.secrets/certbot/rfc2136-example.com.ini
nsupdate による Dynamic Updates ( 動的更新 ) 更新
nsupdate
コマンドを実行してプロンプト ( > ) だけ表示されれば OK です。quit
か CTRL + D
で終了します。
[root@newiff named]# nsupdate -k ddns-key._acme-challenge.example.com > <何も表示されない> > > quit
実行されると動的更新の対象ドメインにはジャーナルファイル ( *.jnl
) が生成されるし、証明書を発行しても生成されます。
[root@centos7 named]# ll /var/named/_acme-challenge.example.com.db.wan.jnl -rw-r--r-- 1 named named 5456 Jun 17 11:36 /var/named/_acme-challenge.example.com.db.wan.jnl [root@centos7 named]#
これで、Step 4、BIND の TXTレコードの追加・更新リクエスト 設定でした。
次は、Step 5
の TXTレコードの追加・更新完了を通知 設定を行いましょう。
TXT レコードの追加・更新完了を通知を設定
TSIG キー情報ファイルを読み込み ( include ) するよう追加します。
include "/etc/named/ddns-key._acme-challenge.example.com";
TSIG キー情報ファイルでの動的更新を許可します。
allow-update { key ddns-key._acme-challenge.example.com; };
”_”を含むホスト ( _acme-challenge ) を使うため、オプションを変更します。
internal view の zone ファイルにも追加してください。
check-names ignore;
Zone ファイルに検証用サブドメインを追加し、update-policy を設定します。
ddns-confgen
のアウトプット中でライン番号 13〜15 までの update-policy {...}
部分をコピして下記のように追加します。最後の ANY を TXT に変更してください。
update-policy { grant ddns-key._acme-challenge.example.com name _acme-challenge.example.com. TXT; };
最終的には、▼
[root@centos7 named]# cat named.example.com.zone zone "example.com" { type master; file "example.com.db"; check-names ignore; }; [root@centos7 named]#
[root@centos7 named]# vi /etc/named/named.example.com.zone.wan include "/etc/named/ddns-key._acme-challenge.example.com"; zone "example.com" { type master; file "example.com.db.wan"; check-names ignore; allow-query { any; }; allow-update { key ddns-key._acme-challenge.example.com; }; notify yes; }; zone "_acme-challenge.example.com" { type master; allow-query { any; }; check-names ignore; file "_acme-challenge.example.com.db.wan"; update-policy { grant ddns-key._acme-challenge.example.com name _acme-challenge.example.com. TXT; }; }; [root@centos7 named]#
ここからは _acme-challenge.example.com
ドメインを設定していきます。普通の BIND 設定です。
example.com のゾーンデータベースに _acme-challenge を追加します。
[root@centos7 named]# vi /var/named/example.com.db.wan $TTL 86400 @ IN SOA ns1.example.com. root.example.com.( 2019051324 ; Serial 60 ; Refresh 7200 ; Retry 2419200 ; Expire 86400 ) ; Minimum IN NS ns1.example.com. ns1 IN A 123.123.123.10 _acme-challenge IN NS ns1.example.com. [root@centos7 named]#
_acme-challenge.example.com.db.wan ファイルを作ります。
[root@centos7 named]# vi _acme-challenge.example.com.db.wan $TTL 86400 @ IN SOA ns1.example.com. root.example.com.( 2019061313 ; Serial 60 ; Refresh 7200 ; Retry 2419200 ; Expire 86400 ) ; Minimum IN NS ns1.example.com. [root@centos7 named]#
これで完了です。
デーモンを再起動
named
デーモンを再起動して、rndc reload
で named.conf
とゾーン情報をリロードします。
[root@centos7 named]# systemctl restart named [root@centos7 named]# rndc reload
いよいよ証明書を発行できますが、問題なく発行できるかテストできるのでやっておきます。
証明書の発行テスト
tail -f /var/log/message
又は、journalctl -fu named
でエラーが出ないことを確認しながら進みましょう。
--dry-run
と --debug
オプションを追加して実行します。
実行すると、The dry run was successful.
と表示されれば OK です。
certbot certonly \
–dry-run \
–debug \
–dns-rfc2136 \
–dns-rfc2136-credentials ~/.secrets/certbot/rfc2136-example.com.ini \
–dns-rfc2136-propagation-seconds 5 \
-d example.com \
-d “*.example.com”
[root@centos7 named]# certbot certonly \ > --dry-run \ > --debug \ > --dns-rfc2136 \ > --dns-rfc2136-credentials ~/.secrets/certbot/rfc2136-example.com.ini \ > --dns-rfc2136-propagation-seconds 5 \ > -d example.com \ > -d "*.example.com" Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator dns-rfc2136, Installer None Starting new HTTPS connection (1): acme-staging-v02.api.letsencrypt.org Cert not due for renewal, but simulating renewal for dry run Renewing an existing certificate IMPORTANT NOTES: - The dry run was successful. << ここ! [root@centos7 named]#
Certbot アカウントを登録 ( 任意 )
発行テストが通れたら Certbot
アカウントを登録して実際のワイルドカード証明書を発行します。
登録済みであれば、スキップしてください。
# メールアドレスをシェアしないで登録する certbot register --email admin@example.org --agree-tos --no-eff-email
ワイルドカード証明書を発行
--dns-rfc2136-propagation-seconds
オプションはデフォルトで 60 秒
、長いと思ったら調整します。ここでは 5 秒
にして発行します。
certbot certonly \
–dns-rfc2136 \
–dns-rfc2136-credentials ~/.secrets/certbot/rfc2136-example.com.ini \
–dns-rfc2136-propagation-seconds 5 \
-d example.com \
-d “*.example.com”
※ デバッグが必要な場合は、次のページにある デバッグ情報
をご参考ください。
[root@centos7 named]# certbot certonly \ > --dns-rfc2136 \ > --dns-rfc2136-credentials ~/.secrets/certbot/rfc2136-example.com.ini \ > --dns-rfc2136-propagation-seconds 5 \ > -d example.com \ > -d "*.example.com" Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator dns-rfc2136, Installer None Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org Obtaining a new certificate Performing the following challenges: dns-01 challenge for example.com dns-01 challenge for example.com Waiting 5 seconds for DNS changes to propagate Waiting for verification... Cleaning up challenges IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/example.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/example.com/privkey.pem Your cert will expire on 2019-09-15. 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 [root@centos7 named]#
発行されたら、
/etc/letsencrypt/live/ドメイン名
以下に保存されます。
[root@centos7 named]# ls /etc/letsencrypt/live/example.com/ cert.pem chain.pem fullchain.pem privkey.pem README [root@centos7 named]#
// 成功時のログメッセージ [root@centos7 ~]# journalctl -fu named Jun 17 15:08:59 centos7 named[8062]: client 123.123.123.10#37662/key ddns-key._acme-challenge.example.com: view external: updating zone '_acme-challenge.example.com/IN': adding an RR at '_acme-challenge.example.com' TXT Jun 17 15:08:59 centos7 named[8062]: client 123.123.123.10#37664/key ddns-key._acme-challenge.example.com: view external: updating zone '_acme-challenge.example.com/IN': adding an RR at '_acme-challenge.example.com' TXT Jun 17 15:09:06 centos7 named[8062]: client 123.123.123.10#37666/key ddns-key._acme-challenge.example.com: view external: updating zone '_acme-challenge.example.com/IN': deleting an RR at _acme-challenge.example.com TXT Jun 17 15:09:06 centos7 named[8062]: client 123.123.123.10#37668/key ddns-key._acme-challenge.example.com: view external: updating zone '_acme-challenge.example.com/IN': deleting an RR at _acme-challenge.example.com TXT
発行された証明書は有効期間が 3ヶ月
しかありませんので、自動更新設定は管理上必須で、更新に問題ないかを事前チェックしてから自動更新を設定します。
証明書の更新テスト
更新テストは certbot renew --dry-run
を実行するだけです。
Congratulations, all renewals succeeded.
と、表示されたら OK です。
※ デバッグが必要な場合は、次のページにある デバッグ情報
をご参考ください。
[root@centos7 named]# certbot renew --dry-run Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Processing /etc/letsencrypt/renewal/example.com.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cert not due for renewal, but simulating renewal for dry run Plugins selected: Authenticator dns-rfc2136, Installer None Starting new HTTPS connection (1): acme-staging-v02.api.letsencrypt.org Renewing an existing certificate - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - new certificate deployed without reload, fullchain is /etc/letsencrypt/live/example.com/fullchain.pem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ** 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/example.com/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [root@centos7 named]#
自動更新設定 ( CRON JOB へ登録 )
自動更新をテストしてエラーがなければ CRON JOB
へ登録します。
毎日 2 回(正午、真夜中)更新するように設定しますが、回数は適宜変更して設定してください。
[root@centos7 named]# crontab -e #下記の内容を追加 0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 60)' && certbot renew [root@centos7 named]#
これで、 Let's Encrypt ワイルドカード証明書
を継続的に使えることができます。
コメント