Let's Encrpyt を使って自ドメインの TLS/SSL 証明書を取得するやり方のメモを残す。
更新履歴
(2019.01.27) 作成。
(2024.07.13) CentOS 7 から Rocky Linux 9 へ変更。
目次
1. はじめに
自ドメイン(NMINORU.JP)のために Let's Encrpyt で TLS/SSL 証明書を取得する。 Let's Encrypt で TLS/SSL 証明書を取得するにはいくつか方法があるが、自ドメインの DNS サーバーの TXT レコードを使う方法(DNS-01方式)で取得する。
2. 設定
2.1 certbot インストール
まず NMINORU.JP の DNS サーバーは Rocky Linux 9 だが、ここに certbot をインストールする。 certbot は EPEL リポジトリに登録されているので、必要なら先に epel-release パッケージをインストールし、その後で certbot をインストールする。
# dnf install epel-release # dnf install certbot
2.2 BIND サーバーの設定
NMINORU.JP ドメインの DNS サーバーはローカルネットには view internal を、インターネットには view external を見せている。 その両方から参照される _acme-challenge.nminoru.jp というサブドメインを作る。 _acme-challenge のサブドメインは Dynamic DNS とする。 このために /etc/named.conf に赤字の部分を追加する。
acl "local-network" { 127/8; 10/8; }; options { listen-on-v6 port 53 { ::1; }; version "unknown"; 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-transfer { 127/8; 10/8; }; allow-query-cache { localhost; local-network; }; allow-query { any; }; dnssec-enable no; dnssec-validation no; bindkeys-file "/etc/named.iscdlv.key"; managed-keys-directory "/var/named/dynamic"; forwarders { 8.8.8.8; 8.8.4.4; }; forward only; pid-file "/run/named/named.pid"; session-keyfile "/run/named/session.key"; }; logging { channel default_debug { file "data/named.run"; severity dynamic; }; }; view "internal" { match-clients { localhost; local-network; }; match-destinations { localhost; local-network; }; recursion yes; allow-recursion { localhost; local-network; }; zone "." IN { type hint; file "named.ca"; }; zone "nminoru.jp" { // nminoru.jp type master; file "zone/jp.nminoru-intra.defs"; check-names ignore; }; zone "_acme-challenge.nminoru.jp" { type master; file "zone/jp.nminoru._acme-challenge.defs"; allow-update { localhost; local-network; }; check-names ignore; }; zone "230.20.10.in-addr.arpa" { type master; file "10.20.230.revs"; }; include "/etc/named.rfc1912.zones"; include "/etc/named.root.key"; }; view "external" { match-clients { any; }; match-destinations { any; }; recursion no; zone "nminoru.jp" { type master; file "zone/jp.nminoru.defs"; check-names ignore; }; zone "_acme-challenge.nminoru.jp" { type slave; file "slaves/jp.nminoru._acme-challenge.defs"; masters { 127.0.0.1; }; allow-notify { 127.0.0.1; }; }; };
NMINORU.JP ドメインを外側に提供する zone/jp.nminoru.defs と内側に提供する zone/jp.nminoru-intra.defs の _acme-challenge.nminoru.jp のサブドメインに対するネームサーバーの定義を追加する(赤字の部分)。
$TTL 3600
@ IN SOA ns.nminoru.jp. postmaster.nminoru.jp. (
2019011902 ; serial
3600 ; refresh
900 ; retry
3600000 ; expire
3600 ; default_ttl
)
// ここに元からの定義を書く
_acme-challenge IN NS ns.nminoru.jp.
_acme-challenge.nminoru.jp のサブドメインに対するゾーン定義ファイルをも作成する。 これを jp.nminoru._acme-challenge.defs とする。
$ORIGIN . $TTL 60; 1 minute _acme-challenge.nminoru.jp IN SOA ns.nminoru.jp. root.nminoru.jp. ( 2019012614 ; serial 86400 ; refresh (1 day) 3600 ; retry (1 hour) 86400 ; expire (1 day) 60 ; minimum (1 minute) ) NS ns.nminoru.jp.
Dynamic DNS が働いていることを確かめる。 nsupdate コマンドを使って _acme-challenge.nminoru.jp サブドメインの TXT レコードを書き換えることを確認する。
# nsupdate -l > update add _acme-challenge.nminoru.jp. 60 IN TXT "abc" > send > quit
成功すると jp.nminoru._acme-challenge.defs ゾーン定義ファイルの隣に jp.nminoru._acme-challenge.defs.jnl というジャーナルファイルが作成される。 _acme-challenge.nminoru.jp サブドメインの TXT レコードが先ほど設定した値が見えることを確認する。
$ dig _acme-challenge.nminoru.jp TXT
nsupdate コマンドを -l オプションを付けたので、更新されるのは内側(view internal)のみである。 外側(view external)を更新するために BIND サーバーを再起動すると、jp.nminoru._acme-challenge.defs.jnl ジャーナルファイルが適用され外側からも設定した TXT レコードが見えるようになる。
# systemctl restart named $ dig @8.8.8.8 _acme-challenge.nminoru.jp TXT
2.3 certbot の設定
次に certbot を実行する時に、Let's Encrypt のサーバーからの指示で _acme-challenge.nminoru.jp の TXT レコードを書き換えるスクリプトと、証明書取得後に解除する処理を作成する。
作成するクリプトは環境変数 $CERTBOT_DOMAIN にドメイン名(nminoru.jp)が、$CERTBOT_VALIDATION には毎回変わるランダムな文字列が入る。
#! /bin/sh logger dns-01-auth.sh echo " update delete _acme-challenge.$CERTBOT_DOMAIN TXT update add _acme-challenge.$CERTBOT_DOMAIN 10 IN TXT $CERTBOT_VALIDATION send " | nsupdate -l # slave を削除する rm -f /var/named/slaves/*.defs /var/named/slaves/*.defs.jnl systemctl restart named # named 起動後しばらく時間をおく sleep 10
#! /bin/sh logger dns-01-clean.sh echo " update delete _acme-challenge.$CERTBOT_DOMAIN TXT send " | nsupdate -l systemctl restart named
スクリプトの最後に systemctrl の named を再起動しているのは、internal ビューに対して行った TXT レコードの書き換えを external ビュー側にも適用するためである。 DNS サーバーの master-slave の同期は時間がかかるようで、適当なスリープ時間を挟み込む。
3. 証明書の初回取得
最後に Let's Encrypt の初回の証明書を取得するために certbot コマンドを使用する。
まず証明書の取得のためにアカウントを作成する。 連絡用アドレスの指定が必要だが、これを Certbot の開発元である電子フロンティア財団とシェアしない場合には以下のようにコマンドを入力する。
# certbot register --email root@nminoru.jp --agree-tos --no-eff-email
最後に以下のように入力する。
# certbot certonly -d nminoru.jp -d "*.nminoru.jp" --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory \ --manual \ --manual-auth-hook /etc/letsencrypt/dns-01-auth.sh \ --manual-cleanup-hook /etc/letsencrypt/dns-01-clean.sh
- -d *.nminoru.jp は取得したいドメイン名を指定する。www.nminoru.jp でもよいが、*.nminoru.jp だとワイルドカードなドメイン名に対する証明書が取得できる。
- --preferred-challenges dns-01 は DNS を使った TLS/SSL 証明書の取得方式であることを支持する。
- --server https://acme-v02.api.letsencrypt.org/directory
- --manual、--manual-auth-hook /etc/letsencrypt/dns-01-auth.sh、--manual-cleanup-hook /etc/letsencrypt/dns-01-clean.sh は 2.3 節のスクリプトの位置を指定する。
成功すれば以下のようなメッセージが表示される。
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 nminoru.jp
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
Resetting dropped connection: acme-v02.api.letsencrypt.org
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/nminoru.jp/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/nminoru.jp/privkey.pem
Your cert will expire on 2019-04-27. 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
成功すれば /etc/letsencrypt/live/nminoru.jp/ の下に cert.pem、chain.pem、fullchain.pem、privatekey.pem ができる。