15年以上前から、格安サーバ証明書を使っていましたが、今は無料で手に入るんですね!しかも憧れのワイルドカード証明書さえも無料です!
Let’s Encryptでサーバ証明書を取得するには難易度があります。
- Webサーバ経由→簡単!
- クラウドやレンタルサーバのdns経由→ちょっと難しい
- 自宅サーバのdns経由→超絶難しい!(bindの新機能で簡単になりました!)
ワイルドカードのサーバ証明書はdns経由でないと取得できません。頑張って設定してみましょう!
サーバ証明書を取得するには、そのドメインの所有者であることを証明しなくてはなりません。
例えば、以前の格安サーバ証明書を取得するためには「admin@ドメイン名」のメールアドレスで、メールを受け取ることが条件でした。
Let’s Encryptでdnsサーバ経由でサーバ証明書を取得するためには「_acme-challenge.ドメイン名」のホストに、指示された内容のTXTレコードを書き込めることが条件になります。
また、証明書の有効期限は90日と短くなっています。そのつど手動で更新するのは大変なので、ツールを使って自動化します。
certbotのインストール
[root@ace ~]# dnf install certbot python3-certbot-dns-rfc2136
サブスクリプション管理リポジトリーを更新しています。
メタデータの期限切れの最終確認: 1:17:20 前の 2024年02月05日 18時32分53秒 に実施 しました。
依存関係が解決しました。
================================================================================
パッケージ Arch バージョン リポジトリー サイズ
================================================================================
インストール:
certbot noarch 2.6.0-1.el9 epel 18 k
python3-certbot-dns-rfc2136
noarch 2.6.0-1.el9 epel 32 k
依存関係のインストール:
fontawesome-fonts noarch 1:4.7.0-13.el9 rhel-9-for-x86_64-appstream-rpms 207 k
fonts-filesystem noarch 1:2.0.5-7.el9.1
rhel-9-for-x86_64-baseos-rpms 11 k
python3-acme noarch 2.6.0-1.el9 epel 160 k
python3-certbot noarch 2.6.0-1.el9 epel 644 k
python3-cffi x86_64 1.14.5-5.el9 rhel-9-for-x86_64-appstream-rpms 257 k
python3-configargparse
noarch 1.7-1.el9 epel 45 k
python3-configobj noarch 5.0.6-25.el9 rhel-9-for-x86_64-appstream-rpms 66 k
python3-cryptography
x86_64 36.0.1-4.el9 rhel-9-for-x86_64-baseos-rpms 1.2 M
python3-dns noarch 2.3.0-2.el9 rhel-9-for-x86_64-baseos-rpms 469 k
python3-josepy noarch 1.13.0-1.el9 epel 60 k
python3-parsedatetime
noarch 2.6-5.el9 epel 79 k
python3-pyOpenSSL noarch 21.0.0-1.el9 epel 90 k
python3-pycparser noarch 2.20-6.el9 rhel-9-for-x86_64-appstream-rpms 139 k
python3-pyrfc3339 noarch 1.1-11.el9 epel 18 k
python3-pytz noarch 2021.1-5.el9 rhel-9-for-x86_64-appstream-rpms 55 k
弱い依存関係のインストール:
python-josepy-doc noarch 1.13.0-1.el9 epel 19 k
トランザクションの概要
================================================================================
インストール 18 パッケージ
ダウンロードサイズの合計: 3.5 M
インストール後のサイズ: 14 M
これでよろしいですか? [y/N]: y
:
略
:
インストール済み:
certbot-2.6.0-1.el9.noarch
fontawesome-fonts-1:4.7.0-13.el9.noarch
fonts-filesystem-1:2.0.5-7.el9.1.noarch
python-josepy-doc-1.13.0-1.el9.noarch
python3-acme-2.6.0-1.el9.noarch
python3-certbot-2.6.0-1.el9.noarch
python3-certbot-dns-rfc2136-2.6.0-1.el9.noarch
python3-cffi-1.14.5-5.el9.x86_64
python3-configargparse-1.7-1.el9.noarch
python3-configobj-5.0.6-25.el9.noarch
python3-cryptography-36.0.1-4.el9.x86_64
python3-dns-2.3.0-2.el9.noarch
python3-josepy-1.13.0-1.el9.noarch
python3-parsedatetime-2.6-5.el9.noarch
python3-pyOpenSSL-21.0.0-1.el9.noarch
python3-pycparser-2.20-6.el9.noarch
python3-pyrfc3339-1.1-11.el9.noarch
python3-pytz-2021.1-5.el9.noarch
完了しました!
[root@ace ~]#
certbotはLet’s Encryptのサーバ証明書を発行するときに使うツールです。
certbot_dns_rfc2136は、「_acme-challenge.ドメイン名」に対して、TSIGキーを使ってTXTレコードを動的更新(DynamicDNS)してくれるプラグインになります。説明書はこちら
DDNSゾーンの追加
DDNSの設定をする前にcertbot_dns_rfc2136のドキュメントにも書いてありますが、TSIGキーを作っておきましょう。
[root@ace ~]# ddns-confgen -k ddns-key
# 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" {
algorithm hmac-sha256;
secret "***非公開情報**";
};
# Then, in the "zone" statement for each zone you wish to dynamically
# update, place an "update-policy" statement granting update permission
# to this key. For example, the following statement grants this key
# permission to update any name within the zone:
update-policy {
grant ddns-key zonesub ANY;
};
# After the keyfile has been placed, the following command will
# execute nsupdate using this key:
nsupdate -k <keyfile>
[root@ace keys]#
TSIGキーの生成は3通りあって、公式サイトの例では「dnssec-keygen」を使っていますが、「ddns-confgen」コマンドの方がわかりやすいと思います。
で、以下のようにkeyファイルを作っておきます。
[root@ace ~]# mkdir /var/named/keys
[root@ace ~]# vi /var/named/keys/ddns-key
[root@ace ~]# cat /var/named/keys/ddns-key
key "ddns-key" {
algorithm hmac-sha256;
secret "***非公開情報***=";
};
[root@ace ~]#
[root@ace ~]# chown -R named:named /var/named/keys
[root@ace ~]# chmod 500 /var/named/keys
[root@ace ~]# chmod 400 /var/named/keys/ddns-key
[root@ace ~]# ls -al /var/named/keys
合計 4
dr-x------ 2 named named 22 2月 5 22:15 .
drwxrwx--T 9 root named 183 2月 5 21:37 ..
-r-------- 1 named named 141 2月 5 22:13 ddns-key
[root@ace ~]#
「/var/named/keys/ddns-key」には秘密情報が入っているので、ファイルのパーティションをnamed以外読めないようにしておきます。
この、TSIGキーを組み込んで、/etc/named.confをDDNS対応に変更します。
[root@ace ~]# vi /etc/named.conf
[root@ace ~]# cat /etc/named.conf
//
// named.conf
//
:
省略
:
options {
:
省略
:
};
logging {
:
省略
:
};
include "/etc/named.root.key";
include "/var/named/keys/ddns-key";
view "internal" {
:
省略
:
zone "_acme-challenge.zeke.ne.jp" {
type master;
file "ddns/_acme-challenge.zeke.ne.jp.zone";
check-names ignore;
allow-query { any; };
update-policy {
grant ddns-key name _acme-challenge.zeke.ne.jp. txt;
};
};
:
省略
:
};
view "external" {
:
省略
:
zone "_acme-challenge.zeke.ne.jp" {
in-view internal;
};
:
省略
:
};
[root@ace ~]#
また、以下のゾーンファイルも作っておきます。
[root@ace ~]# mkdir /var/named/ddns
[root@ace ~]# vi /var/named/ddns/_acme-challenge.zeke.ne.jp.zone
[root@ace ~]# cat /var/named/ddns/_acme-challenge.zeke.ne.jp.zone
$ORIGIN .
$TTL 60 ; 1 minute
_acme-challenge.zeke.ne.jp IN SOA ns.zeke.ne.jp. root.ns.zeke.ne.jp. (
1 ; serial
3600 ; refresh (1 hour)
600 ; retry (10 minutes)
1209600 ; expire (2 weeks)
60 ; minimum (1 minute)
)
IN NS ns.zeke.ne.jp.
[root@ace ~]# chown -R named:named /var/named/ddns
[root@ace ~]# chmod 770 /var/named/ddns/
[root@ace ~]# chmod 660 /var/named/ddns/_acme-challenge.zeke.ne.jp.zone
[root@ace ~]# ls -alR /var/named/ddns/
[root@ace ~]# ls -alR /var/named/ddns/
/var/named/ddns/:
合計 4
drwxrwx--- 2 named named 45 2月 5 20:25 .
drwxrwx--T 9 root named 183 2月 5 20:24 ..
-rw-rw---- 1 named named 225 2月 5 20:25 _acme-challenge.zeke.ne.jp.zone
[root@ace ~]#
「include “/var/named/keys/ddns-key”;」でTSIGキーを追加、「zone “_acme-challenge.zeke.ne.jp” 」ステートメントでDDNSできるゾーンを追加します。
zoneステートメントの中の「update-policy」がDDNSの指定で、 ddns-key の名前のTSIGキーで、_acme-challenge.zeke.ne.jp.名前のTXTレコードだけ変更できるようにしています。
「/var/named/ddns/_acme-challenge.zeke.ne.jp.zone」のゾーンファイルは、自動的に書き込むので、namedユーザで書き込みできるディレクトリ、ファイルにしておきます。
[root@ace ~]# rndc reload
server reload successful
[root@ace ~]# systemctl status named
● named.service - Berkeley Internet Name Domain (DNS)
Loaded: loaded (/usr/lib/systemd/system/named.service; enabled; preset: di>
Active: active (running) since Mon 2024-02-05 20:41:25 JST; 50s ago
Process: 4696 ExecStartPre=/bin/bash -c if [ ! "$DISABLE_ZONE_CHECKING" == >
Process: 4698 ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} $OPTIONS (>
Main PID: 4699 (named)
Tasks: 8 (limit: 23114)
Memory: 45.8M
CPU: 133ms
CGroup: /system.slice/named.service
mq4699 /usr/sbin/named -u named -c /etc/named.conf
2月 05 20:41:25 ace.zeke.ne.jp named[4699]: automatic empty zone: view interna>
2月 05 20:41:25 ace.zeke.ne.jp named[4699]: automatic empty zone: view interna>
2月 05 20:41:25 ace.zeke.ne.jp named[4699]: automatic empty zone: view interna>
2月 05 20:41:25 ace.zeke.ne.jp named[4699]: automatic empty zone: view interna>
2月 05 20:41:25 ace.zeke.ne.jp named[4699]: set up managed keys zone for view >
2月 05 20:41:25 ace.zeke.ne.jp named[4699]: configuring command channel from '>
2月 05 20:41:25 ace.zeke.ne.jp named[4699]: command channel listening on 127.0>
2月 05 20:41:25 ace.zeke.ne.jp named[4699]: configuring command channel from '>
2月 05 20:41:25 ace.zeke.ne.jp named[4699]: command channel listening on ::1#9>
2月 05 20:41:25 ace.zeke.ne.jp systemd[1]: Started Berkeley Internet Name Doma>
[root@ace ~]#
設定ファイルを読み直して、動作確認してみます。
[root@ace keys]# nsupdate -d -k /var/named/keys/ddns-key
Creating key...
Creating key...
namefromtext
keycreate
> server 127.0.0.1
> update add _acme-challenge.zeke.ne.jp. 3600 in txt test
> send
Reply from SOA query:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2513
;; flags: qr aa ra; QUESTION: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; QUESTION SECTION:
;_acme-challenge.zeke.ne.jp. IN SOA
;; ANSWER SECTION:
_acme-challenge.zeke.ne.jp. 60 IN SOA ns.zeke.ne.jp. root.ns.zeke.ne.jp. 9 3600 600 1209600 60
;; AUTHORITY SECTION:
_acme-challenge.zeke.ne.jp. 60 IN NS ns.zeke.ne.jp.
;; TSIG PSEUDOSECTION:
ddns-key. 0 ANY TSIG hmac-sha256. 1707187162 300 32 tqdp0KwiY2bUNXauLNNvIDSA0iW7ZARSZfiiAtvnvp4= 2513 NOERROR 0
Found zone name: _acme-challenge.zeke.ne.jp
The master is: ns.zeke.ne.jp
Sending update to 127.0.0.1#53
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 50419
;; flags:; ZONE: 1, PREREQ: 0, UPDATE: 1, ADDITIONAL: 1
;; UPDATE SECTION:
_acme-challenge.zeke.ne.jp. 3600 IN TXT "test"
;; TSIG PSEUDOSECTION:
ddns-key. 0 ANY TSIG hmac-sha256. 1707187162 300 32 bWCHZZ2fXw8L8y62GYeWQI+/YGfdkJxEIYhZt1zEOeY= 50419 NOERROR 0
Reply from update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 50419
;; flags: qr; ZONE: 1, PREREQ: 0, UPDATE: 0, ADDITIONAL: 1
;; ZONE SECTION:
;_acme-challenge.zeke.ne.jp. IN SOA
;; TSIG PSEUDOSECTION:
ddns-key. 0 ANY TSIG hmac-sha256. 1707187162 300 32 fQJs29efTaagXcNhGCiYG5YlbZGzRhKLtLgZ6+um8RA= 50419 NOERROR 0
> quit
[root@ace keys]#
[root@ace keys]#
[root@ace keys]# dig @127.0.0.1 TXT _acme-challenge.zeke.ne.jp
; <<>> DiG 9.16.23-RH <<>> @127.0.0.1 TXT _acme-challenge.zeke.ne.jp
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62304
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 69a8128ff2c5b64e0100000065c19bf218b788607dd24e62 (good)
;; QUESTION SECTION:
;_acme-challenge.zeke.ne.jp. IN TXT
;; ANSWER SECTION:
_acme-challenge.zeke.ne.jp. 3600 IN TXT "test"
;; Query time: 2 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Feb 06 11:39:46 JST 2024
;; MSG SIZE rcvd: 100
[root@ace keys]#
nsupdateコマンドをデバッグモード&TSIGキーを引数にして立ち上げ、「_acme-challenge.zeke.ne.jp」ホストのTXTレコードに「test」を書き込みます。
「status: NOERROR」になっていれば問題なしです。
digコマンドで、「_acme-challenge.zeke.ne.jp」ホストのTXTレコードを確認すると「test」が入っていますね。
うまく行ったように見えますが、「_acme-challenge.zeke.ne.jp」は内部向けのviewの中なので、インターネット側からは参照できません。これではLet’s Encryptから確認できないので、証明書を発行してもらえません。
先にあげた/etc/named.confに以下のように記述しました。
view "external" {
:
省略
:
zone "_acme-challenge.zeke.ne.jp" {
in-view internal;
};
:
省略
:
};
これは、「外部から_acme-challenge.zeke.ne.jpを参照されたときはinternal viewの同じゾーンを返答して!」という意味です。また、外部から参照できるように、internal view側にはallow-query { any; };を入れる必要があります。
IPv6のアドレス(2001:2c0:cd03:ca00::ace)を外部から参照できるようにして、スマホのキャリア経由で動作を確認しました!
ちゃんと「_acme-challenge.zeke.ne.jp」の内容が表示されていますね。
certbotの設定
長い仕込が終わりました。ようやくcertbotの設定です。
[root@ace ~]# vi /etc/letsencrypt/rfc2136.ini
[root@ace ~]# chmod 640 /etc/letsencrypt/rfc2136.ini
[root@ace ~]# cat /etc/letsencrypt/rfc2136.ini
# Target DNS server (IPv4 or IPv6 address, not a hostname)
dns_rfc2136_server = 127.0.0.1
# Target DNS port
dns_rfc2136_port = 53
# TSIG key name
dns_rfc2136_name = ddns-key
# TSIG key secret
dns_rfc2136_secret = ***非公開情報***
# TSIG key algorithm
dns_rfc2136_algorithm = HMAC-SHA256
# TSIG sign SOA query (optional, default: false)
dns_rfc2136_sign_query = false
[root@ace ~]# ls -al /etc/letsencrypt/
合計 20
drwxr-xr-x 2 root root 40 2月 5 23:02 .
drwxr-xr-x 82 root root 8192 2月 5 22:15 ..
-rw-r--r-- 1 root root 152 5月 23 2023 cli.ini
-rw-r----- 1 root root 396 2月 6 11:46 rfc2136.ini
[root@ace ~]#
設定ファイルは、/var/named/keys/ddns-keyの内容を参考に記述します。ただし、dns_rfc2136_algorithmは大文字でないと認識してくれないようで、小文字で書いちゃうとエラーが出ます。設定ファイルは秘密情報が入っているので、root以外読めないようにしておきます。
[root@ace ~]# certbot certonly --dns-rfc2136 --dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini -d *.zeke.ne.jp -d zeke.ne.jp -m zeke@mail.zeke.ne.jp --agree-tos --test-cert
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y
Account registered.
Requesting a certificate for *.zeke.ne.jp and zeke.ne.jp
Waiting 60 seconds for DNS changes to propagate
Certbot failed to authenticate some domains (authenticator: dns-rfc2136). The Certificate Authority reported these problems:
Domain: zeke.ne.jp
Type: unauthorized
Detail: No TXT record found at _acme-challenge.zeke.ne.jp
Domain: zeke.ne.jp
Type: unauthorized
Detail: No TXT record found at _acme-challenge.zeke.ne.jp
Hint: The Certificate Authority failed to verify the DNS TXT records created by --dns-rfc2136. Ensure the above domains are hosted by this DNS provider, or try increasing --dns-rfc2136-propagation-seconds (currently 60 seconds).
Some challenges have failed.
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.
[root@ace ~]#
試しに、certbotコマンドを実行してみます。ここでは*.zeke.ne.jpのワイルドカードと、zeke.ne.jpのサーバ証明書を要求しています。また、テストのため–test-certオプションを付けています。
一番最初に実行すると、メールアドレスをメーリングリストに登録するか?みたいなメッセージが出てきます。
まだ新しいdnsサーバは公開していないので、 _acme-challenge.zeke.ne.jpのTXTレコードを書き換えてから60秒待ってから諦めて、承認がおりていませんね。
スマホのキャリア経由でTXTレコードが書き換わっていることを確認できたので、ここまでは問題ないと思います。あとはdnsサーバを公開したあとに確認ですね。
また、公開後は以下のシェルをcronに実行させてサーバ証明書を更新します。
[root@myhome ~]# cat /etc/cron.daily/letsencrypt
#!/bin/sh
/usr/bin/certbot renew -q --deploy-hook "systemctl restart httpd ; systemctl restart postfix ; systemctl restart dovecot ; systemctl restart vsftpd"
[root@myhome ~]#
certbot renewコマンドでサーバ証明書を更新したら、–deploy-hookオプションで、各サーバを再起動しています。(–deploy-hookオプションも一度設定したら、省略してもいいのかな?)
また、以下のCAAレコード・ジェネレーターを使って、ゾーンファイルにCAAレコードも入れておきます。
zeke.ne.jp. IN CAA 0 issue "letsencrypt.org"
zeke.ne.jp. IN CAA 0 iodef "mailto:zeke@mail.zeke.ne.jp"
今回はちょっと大変でした。問題なく動いている現行をそのままコピーすればいいのですが、おかしなところはないか調べ直したり、もっと簡単にできる方法を考えていたりとかしていたので。
証明書を操作するコマンドのおぼえ書き
サブドメインをまとめて証明書に入れたいときは-d オプションを複数つける。一番最初のオプションにつけたドメイン名が共通名(CN)になる。
certbot certonly --dns-rfc2136 --dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini -d zeke.ne.jp -d *.zeke.ne.jp -d *.info.zeke.ne.jp -d *.mail.zeke.ne.jp -m zeke@mail.zeke.ne.jp --agree-tos
作成した証明書の中身を確認するときのコマンド
openssl x509 -in /etc/letsencrypt/live/zeke.ne.jp/cert.pem -text
証明書に含めたサブドメインを変更したくて作り直したいときは、以下のコマンドで一度削除してから作成する。そうしないと /etc/letsencrypt/live/zeke.ne.jp-001 のように連番を振られてしまう。(Let’s Encrypt側で覚えているようで、ローカルのファイルを削除してもダメみたい)
certbot delete --cert-name zeke.ne.jp
お勧めのKindle本です!
コメント