DNS TXTレコードを自動で登録する仕組み
- ダイナミックなDNSサーバーを立ち上げる
スクリプトでTXTレコードを書き換えられるDNSということで、独自DNSを立ち上げてみることにします。 これなら取得時のhookを利用すればどうにかなるのではということですね。自分でDNSサーバーを立ち上げるのは実に久しぶりです。
安全のためセカンダリーはプロバイダーのセカンダリーサービスを利用することにします。
今回検証用にしばらくこのDNSサーバーを運用してみることにします。 - 証明書取得準備作業 スクリプト作成
- まず手動操作でcertbotによりSSL/TLS サーバ証明書を取得
この時 dns-01認証で要求、hook を利用して DNSにTXTレコードを追加してDNSを更新(nsupdateを使う) - DNSのTXTレコードが登録されると certbotのタスクが検知、証明書を発行してくれる。
- 発行された証明書によりApacheにSSLを登録(今回は手作業)
- その後、更新(renew)も認証用スクリプトで証明書をマニュアル操作なく更新可能
今回インストールしたサーバー環境
- linux
$ cat /etc/centos-release
CentOS Linux release 7.4.1708 (Core) - Webサーバー
$ apachectl -v
Server version: Apache/2.4.6 (CentOS)
Server built: Aug 23 2017 15:47:21 - certbot バージョン確認
$ certbot –version
certbot 0.23.0 - bind(named)のバージョン
$ named -v
BIND 9.11.1
DNS環境の構築
1 |
$ sudo yum -y install bind bind-utils |
named.conf
named.confはインストールしたデフォルトのファイルを一部修正しますが、ほぼ内容は同じです。外部に公開する場合はport53をファイヤーウォール等々で解放します。
ドメインのネームサーバーも自前のDNSに変更する手続きや設定も必要です。ドメインを取得したプロバイダーで設定します。
DNSは狙われやすいので、今回の設置では、実際には chroot 対応にしてあります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
options { listen-on port 53 { any; }; // Port53を解放 directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; allow-query { localhost; any; }; recursion yes; dnssec-enable yes; dnssec-validation yes; bindkeys-file "/etc/named.iscdlv.key"; managed-keys-directory "/var/named/dynamic"; pid-file "/run/named/named.pid"; session-keyfile "/run/named/session.key"; }; logging { channel default_debug { file "data/named.run"; severity dynamic; }; }; zone "." IN { type hint; file "named.ca"; }; zone "natts.info" IN { type master; file "natts.info.zone"; allow-update { 127.0.0.1; // プログラムによる変更を許可するアドレス xxx.xxx.xxx; // 他のサイトの場合IPアドレスを追加、変更 }; allow-transfer { // セカンダリDNS転送を許可するアドレスを記述 }; also-notify { // ゾーン転送の強制実行するアドレスを記述 }; }; |
対象となるドメインのZONEファイル
1 2 3 4 5 6 7 8 9 10 11 12 |
$TTL 86400 @ IN SOA natts.info. root.natts.info. ( 201807100 ;Serial 3600 ;Refresh 1800 ;Retry 604800 ;Expire 86400 ;Minimum TTL ) IN NS ns.natts.info. IN NS 2nd.dnsv.jp. www IN A xxx.xxx.xxx.xxx |
構築したDNSの起動動作確認
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[root@xxx ~]# systemctl start named // Bind 起動 [root@xxx ~]# systemctl enable named // 自動起動設定 [root@xxx ~]# dig natts.info // 正常に起動できているか確認 ; <<>> DiG 9.11.1 <<>> natts.info ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34937 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 3 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;natts.info. IN A [以下略] ・ ・ |
実際にTXTレコードが 「nsupdate」コマンドにより更新できているか同様に確認する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
[root@xxxx ~]]# nsupdate > add _acme-challenge.natts.info 60 TXT "CERTBOT_VALIDATION_TEXT_SampleText" > show Outgoing update query: ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 0 ;; flags:; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0 ;; UPDATE SECTION: _acme-challenge.natts.info. 60 IN TXT "CERTBOT_VALIDATION_TEXT_SampleText" > send > quit [root@xxxx ~]# nslookup -q=txt _acme-challenge.natts.info // 登録できているか確認 Server: xxx.xxx.xxx.xxx Address: xxx.xxx.xxx.xxx#53 _acme-challenge.natts.info text = "CERTBOT_VALIDATION_TEXT_SampleText" [root@xxx ~]# nsupdate // テストで登録したTXTレコードを削除 > delete _acme-challenge.natts.info txt > send > quit [root@xxx ~]# nslookup -q=txt _acme-challenge.natts.info // 削除できているか確認 Server: xxx.xxx.xxx.xxx Address: xxx.xxx.xxx.xxx#53 ** server can't find _acme-challenge.natts.info: NXDOMAIN |
証明書取得準備作業 スクリプト作成
認証用スクリプト
1 2 3 4 5 6 |
#!/bin/sh if [ "$CERTBOT_VALIDATION" != "" ] && [ "$CERTBOT_TOKEN" != "" ]; then echo -e "delete _acme-challenge.$CERTBOT_DOMAIN TXT\n"\ "add _acme-challenge.$CERTBOT_DOMAIN 10 IN TXT \"$CERTBOT_VALIDATION\"\n" \ | nsupdate fi |
TXTレーコードのクリーンアップ用スクリプトの記述
1 2 3 4 |
#!/bin/sh if [ "$CERTBOT_VALIDATION" != "" ] && [ "$CERTBOT_TOKEN" != "" ]; then echo -e "delete _acme-challenge.$CERTBOT_DOMAIN TXT\n" | nsupdate fi |
certbot dns-01認証による証明書取得
1 2 3 4 5 6 7 8 9 |
[root@xxx ~]# certbot certonly \ -d *.natts.info \ -d natts.info \ -m khagiwara@codingstock.jp \ --preferred-challenges dns-01 \ --server https://acme-v02.api.letsencrypt.org/directory \ --manual \ --manual-auth-hook /etc/letsencrypt/renewal-hooks/pre/dns-01-auth.sh \ --manual-cleanup-hook /etc/letsencrypt/renewal-hooks/post/dns-01-clean.sh |
- certonly
- 証明書取得のみ
- d natts.info
- ドメインでの証明書
- -d *.natts.info
- ワイルドカードでの証明書
- –preferred-challenges dns-01
- dns-01での認証
- –server https://acme-v02.api.letsencrypt.org/directory
- ACME ディレクトリリソースの URI を指定します。
- –manual
- ドメイン名の認証を手動で行い、SSL/TLS サーバ証明書を取得
- –manual-auth-hook /etc/letsencrypt/renewal-hooks/pre/dns-01-auth.sh
- TXTレコードを取得事前hookにより登録
- –manual-cleanup-hook /etc/letsencrypt/renewal-hooks/post/dns-01-clean.sh
- 取得後のhookによりTXTレコード削除
実行結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator manual, Installer None Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org Obtaining a new certificate Performing the following challenges: dns-01 challenge for natts.info dns-01 challenge for natts.info ------------------------------------------------------------------------------- NOTE: The IP of this machine will be publicly logged as having requested this certificate. If you're running certbot in manual mode on a machine that is not your server, please ensure you're okay with that. Are you OK with your IP being logged? ------------------------------------------------------------------------------- (Y)es/(N)o: Y Waiting for verification... Cleaning up challenges IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/natts.info/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/natts.info/privkey.pem Your cert will expire on 2018-10-26. 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 |
取得した証明書を確認
更新(renew)も認証用スクリプトで証明書をマニュアル操作なく更新可能
renewの動作確認
–dry-run を利用して登録してある全ての証明書の更新を検証する。
このオプションで実際には更新されない。
renewは登録してある全てのLet’s Encryptで発行した証明書を更新します。
renew (–dry-runを指定しない場合)では更新期限ではない証明書は発行しません。
実際の自動更新は crontab 等を利用して定期的にこのコマンドを実行する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
[root@xxx ~]# certbot renew --force-renewal --dry-run Saving debug log to /var/log/letsencrypt/letsencrypt.log ・ [途中省略] ・ ・ ------------------------------------------------------------------------------- Processing /etc/letsencrypt/renewal/natts.info.conf ------------------------------------------------------------------------------- Plugins selected: Authenticator manual, Installer None Starting new HTTPS connection (1): acme-staging-v02.api.letsencrypt.org Pre-hook command already run, skipping: /etc/letsencrypt/renewal-hooks/pre/dns-01-auth.sh Renewing an existing certificate Performing the following challenges: dns-01 challenge for natts.info dns-01 challenge for natts.info Waiting for verification... Cleaning up challenges ------------------------------------------------------------------------------- new certificate deployed without reload, fullchain is /etc/letsencrypt/live/natts.info/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/natts.info/fullchain.pem (success) ・ // 今回検証したワイルドカードの証明書のrenewのテストが成功 [途中省略] ・ ・ ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) ------------------------------------------------------------------------------- Running post-hook command: /etc/letsencrypt/renewal-hooks/post/dns-01-clean.sh |