SSL 証明書 CertbotDNS-RFC2136ワイルドカード証明書無料取得自動更新

Let’s Encrypt ワイルドカード証明書を取得・自動更新を完結する|DNS-RFC2136

https-dns-rfc2136 SSL 証明書
スポンサーリンク

今回は CentOS7 で CertbotBIND を連携させてワイルドカード証明書の取得および自動更新の設定方法を紹介します。

手動でワイルドカード証明書の更新が面倒な方、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";
};

それでは、環境を設定していきます。

\お🉐なキャンペーン実施中!/

\お🉐なキャンペーン実施中!/

関連パッケージをインストール

Certbotdns-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回(正午、真夜中)更新をチェックすることを前提にします。

DNS-RF2136を使用したワイルドカード証明書の自動更新
  • Step 1
    証明書の更新プロセスを開始

    CRON JOB 毎日 2 回(正午、真夜中)更新するよう、登録することで自動開始できます。

    ( 最後に登録します )

  • Step 2
    ワイルドカード証明書の発行・更新をリクエスト

    Certbot ▶︎ Let’s Encryptに、対象ドメインの証明書の発行・更新を依頼します。このステップは構築後自動で Certbot がやってくれます。

    ( 対象ドメインのリストを Step 4 で設定します )

  • Step 3
    ドメイン検証用のTXTレコードのトークンを発行し、照会リクエスト待つ!

    Let's Encrypt はそのドメインが有効なのかを含め検証するためのトークンを Certbot に渡して、検証準備が終わったら知らせろ!と指示します。

    CertbotBIND と検証作業 ( Step 4、5 ) を始め、Let's Encrypt はこの検証作業の完了報告 ( Step 6 ) を待ちます。

    ( 設定不要!)

  • Step 4
    BIND の TXTレコードの追加・更新リクエスト

    ドメインを検証する方法として、BINDTXT レコードを利用しますが、CertbotBIND はお互い連携されていませんので、このステップを我々が設定してあげる必要があります。

    この設定を完了すると、Certbot から BIND に TXTレコードに対象ドメインの追加・更新の依頼が自動で行われます。

    ( 要設定!)

  • Step 5
    TXTレコードの追加・更新完了を通知

    BIND からドメインの検証準備ができたら Certbot に知らせます。
    Step 4 と同じくお互い連携されていませんのでこのステップも設定が必要です。

    ( 要設定!)

  • Step 6
    TXTレコードの追加・更新完了を通知 ( 照会リクエスト )

    BIND からの検証準備 OK のサインを受けると、CertbotLet's Encrypt照会リクエスト を送ります。

    ( 設定不要!)

  • Step 7
    TXTレコードを照会

    Let's EncryptBIND の設定をみてドメインの検証を始めます。

    ( 設定不要!)

  • Step 8
    ワイルドカード証明書発行・更新

    Let's Encrypt はドメインの検証が成功 ( 照会成功 ) すると証明書を発行・更新してくれます。

    ( 設定不要!)

  • Step 9
    証明書を保存

    Certbot はその証明書を指定の場所に保存します。

  • Step 10
    更新プロセスを終了

    これから、保存された証明書をウェブサーバ側で設定して利用できます。

以上、自分なりの「DNS-RF2136を使用したワイルドカード証明書の自動更新」の流れでした。

若干複雑に見えましたが、やることは CertbotBIND を連携してあげることでした!

それでは、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-keygenrndc-confgenddns-confgen ) コマンドを提供してますが、ここでは より優しい ddns-confgen を使用します。

ddns-confgen のいいところはコマンドを打つと詳しくガイドラインを標準出力してくれる点です。そのアウトプトにあるスクリプトを少し変更して使います。

Certbot 0.34.2 バージョンで使えるアルゴリズムは HMAC-MD5、HMAC-SHA1、HMAC-SHA224、HMAC-SHA256、HMAC-SHA384、HMAC-SHA512 です。

書式: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 です。
quitCTRL + 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]#

example2.com ドメインを追加する場合、ファイル名を rfc2136-example2.com.ini に変更して追加すれば複数対応できます。

これで、Step 4、BIND の TXTレコードの追加・更新リクエスト 設定でした。

次は、Step 5TXTレコードの追加・更新完了を通知 設定を行いましょう。

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 {...} 部分をコピして下記のように追加します。最後の ANYTXT に変更してください。

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 reloadnamed.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 ワイルドカード証明書 を継続的に使えることができます。

スポンサーリンク

コメント

タイトルとURLをコピーしました