CentOS8で構築する自宅サーバ:dnsサーバの構築 その2 Let’s Encryptで証明書を取得!

CentOS8dnsサーバパソコン自宅サーバ

10年以上前から、格安サーバ証明書を使っていましたが、最近は無料で手に入るんですね!しかも憧れのワイルドカード証明書さえも無料です!

Let’s Encryptでサーバ証明書を取得するには難易度があります。

  1. Webサーバ経由→簡単!
  2. クラウドやレンタルサーバのdns経由→ちょっと難しい
  3. 自宅サーバのdns経由→超絶難しい!

ワイルドカードのサーバ証明書はdns経由でないと取得できません。頑張って設定してみましょう!

サーバ証明書を取得するには、そのドメインの所有者であることを証明しなくてはなりません。

例えば、以前の格安サーバ証明書を取得するためには「admin@ドメイン名」のメールアドレスで、メールを受け取ることが条件でした。

Let’s Encryptでdnsサーバ経由でサーバ証明書を取得するためには「_acme-challenge.ドメイン名」のホストに、指示された内容のTXTレコードを書き込めることが条件になります。

また、証明書の有効期限は90日と短くなっています。そのつど手動で更新するのは大変なので、ツールを使って自動化します。

certbotのインストール

[root@ace ~]# dnf install certbot
メタデータの期限切れの最終確認: 0:03:49 時間前の 2020年02月20日 21時14分42秒 に 実施しました。
依存関係が解決しました。
================================================================================
 パッケージ                Arch   バージョン                    Repo      サイズ
================================================================================
インストール:
 certbot                   noarch 1.1.0-1.el8                   epel       45 k
依存関係のインストール:
 python3-distro            noarch 1.4.0-2.module_el8.1.0+245+c39af44f
                                                                AppStream  37 k
 python3-pip               noarch 9.0.3-15.el8                  AppStream  19 k
 python3-pyasn1            noarch 0.3.7-6.el8                   AppStream 126 k
 python3-pytz              noarch 2017.2-9.el8                  AppStream  54 k
 python36                  x86_64 3.6.8-2.module_el8.1.0+245+c39af44f
                                                                AppStream  19 k
 python3-chardet           noarch 3.0.4-7.el8                   BaseOS    195 k
 python3-pysocks           noarch 1.6.8-3.el8                   BaseOS     34 k
 python3-requests          noarch 2.20.0-2.1.el8_1              BaseOS    123 k
 python3-setuptools        noarch 39.2.0-5.el8                  BaseOS    162 k
 python3-urllib3           noarch 1.24.2-2.el8                  BaseOS    176 k
 python3-acme              noarch 1.1.0-1.el8                   epel       80 k
 python3-certbot           noarch 1.1.0-1.el8                   epel      330 k
 python3-configargparse    noarch 0.14.0-5.el8                  epel       36 k
 python3-josepy            noarch 1.2.0-5.el8                   epel       95 k
 python3-ndg_httpsclient   noarch 0.5.1-4.el8                   epel       53 k
 python3-parsedatetime     noarch 2.5-1.el8                     epel       79 k
 python3-pyrfc3339         noarch 1.1-1.el8                     epel       19 k
 python3-requests-toolbelt noarch 0.9.1-4.el8                   epel       91 k
 python3-zope-component    noarch 4.3.0-8.el8                   epel      313 k
 python3-zope-event        noarch 4.2.0-12.el8                  epel      210 k
 python3-zope-interface    x86_64 4.6.0-1.el8                   epel      158 k
弱い依存関係のインストール:
 python-josepy-doc         noarch 1.2.0-5.el8                   epel       21 k
モジュールストリームの有効化:
 python36                         3.6

トランザクションの概要
================================================================================
インストール  23 パッケージ

ダウンロードサイズの合計: 2.4 M
インストール済みのサイズ: 8.9 M
これでよろしいですか? [y/N]: y
:
省略
:
インストール済み:
  certbot-1.1.0-1.el8.noarch
  python-josepy-doc-1.2.0-5.el8.noarch
  python3-distro-1.4.0-2.module_el8.1.0+245+c39af44f.noarch
  python3-pip-9.0.3-15.el8.noarch
  python3-pyasn1-0.3.7-6.el8.noarch
  python3-pytz-2017.2-9.el8.noarch
  python36-3.6.8-2.module_el8.1.0+245+c39af44f.x86_64
  python3-chardet-3.0.4-7.el8.noarch
  python3-pysocks-1.6.8-3.el8.noarch
  python3-requests-2.20.0-2.1.el8_1.noarch
  python3-setuptools-39.2.0-5.el8.noarch
  python3-urllib3-1.24.2-2.el8.noarch
  python3-acme-1.1.0-1.el8.noarch
  python3-certbot-1.1.0-1.el8.noarch
  python3-configargparse-0.14.0-5.el8.noarch
  python3-josepy-1.2.0-5.el8.noarch
  python3-ndg_httpsclient-0.5.1-4.el8.noarch
  python3-parsedatetime-2.5-1.el8.noarch
  python3-pyrfc3339-1.1-1.el8.noarch
  python3-requests-toolbelt-0.9.1-4.el8.noarch
  python3-zope-component-4.3.0-8.el8.noarch
  python3-zope-event-4.2.0-12.el8.noarch
  python3-zope-interface-4.6.0-1.el8.x86_64

完了しました!
[root@ace ~]#

certbotはLet’s Encryptのサーバ証明書を発行するときに使うツールです。

これだけだと、証明書の更新を自動化できません。もう一つプラグインを追加します。

[root@ace ~]# pip3 install certbot-dns-rfc2136
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead.
Collecting certbot-dns-rfc2136
  Downloading https://files.pythonhosted.org/packages/ad/69/c625a788f11d23a89604ce4b2cabe5e1390ecc1cb9cbd672890e30c4c807/certbot_dns_rfc2136-1.2.0-py2.py3-none-any.whl
Requirement already satisfied: setuptools in /usr/lib/python3.6/site-packages (from certbot-dns-rfc2136)
Collecting mock (from certbot-dns-rfc2136)
  Downloading https://files.pythonhosted.org/packages/30/6a/9bde648117ec7087c89a45de0a8b25aba21d54d3defd08cb24eacded875f/mock-4.0.1-py3-none-any.whl
Requirement already satisfied: certbot>=1.1.0 in /usr/lib/python3.6/site-packages (from certbot-dns-rfc2136)
Collecting dnspython (from certbot-dns-rfc2136)
  Downloading https://files.pythonhosted.org/packages/ec/d3/3aa0e7213ef72b8585747aa0e271a9523e713813b9a20177ebe1e939deb0/dnspython-1.16.0-py2.py3-none-any.whl (188kB)
    100% |????????????????????????????????| 194kB 2.1MB/s
Requirement already satisfied: acme>=0.29.0 in /usr/lib/python3.6/site-packages (from certbot-dns-rfc2136)
:
省略
:
Installing collected packages: mock, dnspython, certbot-dns-rfc2136
Successfully installed certbot-dns-rfc2136-1.2.0 dnspython-1.16.0 mock-4.0.1
[root@ace ~]#

certbot_dns_rfc2136は、「_acme-challenge.ドメイン名」に対して、TSIGキーを使ってTXTレコードを動的更新(DynamicDNS)してくれるプラグインになります。説明書はこちら

DDNSゾーンの追加

DDNSの設定をする前にcertbot_dns_rfc2136のドキュメントにも書いてありますが、TSIGキーを作っておきましょう。

[root@ace ~]# ddns-confgen -k certbot-key -r /dev/urandom
# 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 "certbot-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 certbot-key zonesub ANY;
};

# After the keyfile has been placed, the following command will
# execute nsupdate using this key:
nsupdate -k <keyfile>
[root@ace ~]#

TSIGキーの生成は3通りあって、公式サイトの例では「dnssec-keygen」を使っていますが、「ddns-confgen」コマンドの方がわかりやすいと思います。

で、以下のようにkeyファイルを作っておきます。

[root@ace ~]# mkdir /var/named/keys
[root@ace ~]# vi /var/named/keys/certbot-key
[root@ace ~]# cat /var/named/keys/certbot-key
key "certbot-key" {
        algorithm hmac-sha256;
        secret "***非公開情報***=";
};

[root@ace ~]#
[root@ace ~]# chown -R named:named /var/named/keys
[root@ace ~]# chmod 600 /var/named/keys
[root@ace ~]# chmod 400 /var/named/keys/certbot-key
[root@ace ~]# ls -al /var/named/keys
合計 4
drwx------ 2 named named  25  2月 21 22:26 .
drwxrwx--T 9 root  named 190  2月 21 23:28 ..
-r-------- 1 named named 104  2月 21 22:26 certbot-key
[root@ace ~]#

「/var/named/keys/certbot-key」には秘密情報が入っているので、ファイルのパーティションをnamed以外読めないようにしておきます。

この、TSGキーを組み込んで、/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/certbot-key";

view "internal" {
:
省略
:
        zone "_acme-challenge.zeke.ne.jp" {
                type master;
                file "dynamic-dns/_acme-challenge.zeke.ne.jp.zone";
                allow-transfer { localhost; localnets; };
                check-names ignore;
                update-policy {
                        grant certbot-key name _acme-challenge.zeke.ne.jp. TXT;
                };
        };
:
省略
:
};

view "external" {
:
省略
:
};

[root@ace ~]#

また、以下のゾーンファイルも作っておきます。

[root@ace ~]# mkdir /var/named/dynamic-dns
[root@ace ~]# vi /var/named/dynamic-dns/_acme-challenge.zeke.ne.jp.zone
[root@ace ~]# cat /var/named/dynamic-dns/_acme-challenge.zeke.ne.jp.zone
@               IN      SOA ns.zeke.ne.jp. root.ns.zeke.ne.jp. (
                                6          ; 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/dynamic-dns
[root@ace ~]# chmod 770 /var/named/dynamic-dns/
[root@ace ~]# chmod 640 /var/named/dynamic-dns/_acme-challenge.zeke.ne.jp.zone
[root@ace ~]# ls -alR /var/named/dynamic-dns/
/var/named/dynamic-dns/:
合計 4
drwxrwx--- 2 named named  45  2月 22 00:01 .
drwxrwx--T 9 root  named 183  2月 22 00:01 ..
-rw-r--r-- 1 named named 291  2月 22 00:01 _acme-challenge.zeke.ne.jp.zone
[root@ace ~]#

「include “/var/named/keys/certbot-key”;」でTSGキーを追加、「zone “_acme-challenge.zeke.ne.jp” 」ステートメントでDDNSできるゾーンを追加します。

zoneステートメントの中の「update-policy」がDDNSの指定で、 certbot-key の名前のTSGキーで、_acme-challenge.zeke.ne.jp.名前のTXTレコードだけ変更できるようにしています。

「/var/named/dynamic-dns/_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; vendor prese>
   Active: active (running) since Sat 2020-02-22 00:13:21 JST; 8s ago
  Process: 1676 ExecStop=/bin/sh -c /usr/sbin/rndc stop > /dev/null 2>&1 || /bi>
  Process: 1714 ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} $OPTIONS (co>
  Process: 1710 ExecStartPre=/bin/bash -c if [ ! "$DISABLE_ZONE_CHECKING" == "y>
 Main PID: 1716 (named)
    Tasks: 4 (limit: 25027)
   Memory: 147.6M
   CGroup: /system.slice/named.service
           mq1716 /usr/sbin/named -u named -c /etc/named.conf

 2月 22 00:13:21 ace.lo.zeke.ne.jp named[1716]: automatic empty zone: view inte>
 2月 22 00:13:21 ace.lo.zeke.ne.jp named[1716]: automatic empty zone: view inte>
 2月 22 00:13:21 ace.lo.zeke.ne.jp named[1716]: none:103: 'max-cache-size 90%' >
 2月 22 00:13:21 ace.lo.zeke.ne.jp named[1716]: set up managed keys zone for vi>
 2月 22 00:13:21 ace.lo.zeke.ne.jp named[1716]: none:103: 'max-cache-size 90%' >
 2月 22 00:13:21 ace.lo.zeke.ne.jp named[1716]: configuring command channel fro>
 2月 22 00:13:21 ace.lo.zeke.ne.jp named[1716]: command channel listening on 12>
 2月 22 00:13:21 ace.lo.zeke.ne.jp named[1716]: configuring command channel fro>
 2月 22 00:13:21 ace.lo.zeke.ne.jp named[1716]: command channel listening on ::>
 2月 22 00:13:21 ace.lo.zeke.ne.jp systemd[1]: Started Berkeley Internet Name D>
[root@ace ~]#

設定ファイルを読み直して、動作確認してみます。

[root@ace ~]# nsupdate -d -k /var/named/keys/certbot-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:  35281
;; flags: qr aa ra; QUESTION: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 3
;; 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.

;; ADDITIONAL SECTION:
ns.ZEKE.NE.JP.          3600    IN      A       192.168.1.4
ns.ZEKE.NE.JP.          3600    IN      AAAA    2001:2c0:cd03:ca00::4

;; TSIG PSEUDOSECTION:
certbot-key.            0       ANY     TSIG    hmac-sha256. 1582298120 300 32 b0Xov8pfj6kBnH/FPHFpHw1EUm/gf5ZX1XZyhTy3QEg= 35281 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:  50794
;; flags:; ZONE: 1, PREREQ: 0, UPDATE: 1, ADDITIONAL: 1
;; UPDATE SECTION:
_acme-challenge.zeke.ne.jp. 3600 IN     TXT     "test"

;; TSIG PSEUDOSECTION:
certbot-key.            0       ANY     TSIG    hmac-sha256. 1582298120 300 32 Zw4c/HMgj0hhIjFVrIfMtYsN5lf+0pk4dbwK4sarnPA= 50794 NOERROR 0


Reply from update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id:  50794
;; flags: qr; ZONE: 1, PREREQ: 0, UPDATE: 0, ADDITIONAL: 1
;; ZONE SECTION:
;_acme-challenge.zeke.ne.jp.    IN      SOA

;; TSIG PSEUDOSECTION:
certbot-key.            0       ANY     TSIG    hmac-sha256. 1582298120 300 32 zst7PJ/B0lEcpCHVeI9zva+YqfQFvIHmo2AmVYwXFaU= 50794 NOERROR 0

> quit
[root@ace ~]#
[root@ace ~]#
[root@ace ~]# dig @127.0.0.1 TXT _acme-challenge.zeke.ne.jp

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el8 <<>> @127.0.0.1 TXT _acme-challenge.zeke.ne.jp
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48196
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 3

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 1029dacb2aae4021fcdb3bea5e4ff4124b5e29c61b96da2e (good)
;; QUESTION SECTION:
;_acme-challenge.zeke.ne.jp.    IN      TXT

;; ANSWER SECTION:
_acme-challenge.zeke.ne.jp. 3600 IN     TXT     "test"

;; AUTHORITY SECTION:
_acme-challenge.zeke.ne.jp. 60  IN      NS      ns.zeke.ne.jp.

;; ADDITIONAL SECTION:
ns.zeke.ne.jp.          3600    IN      A       192.168.1.4
ns.zeke.ne.jp.          3600    IN      AAAA    2001:2c0:cd03:ca00::4

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: 土  2月 22 00:15:30 JST 2020
;; MSG SIZE  rcvd: 190

[root@ace ~]#

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から確認できないので、証明書を発行してもらえません。

TSIGキーでviewの壁を突き破る

外部から「_acme-challenge.zeke.ne.jp」を参照できるようにするのが、かなり難しかったです。これができないために、内部用と外部用の2台構成に変更した人もいるとか。

自分が、参照したのは

内部viewの「_acme-challenge.zeke.ne.jp」ゾーンをプライマリに、外部viewのゾーンをセカンダリにして、TSIGキーを使ったゾーン転送を行うというテクニックです。

通常はバックアップや負荷分散のために別のサーバにゾーン転送するので、自分自身へのゾーン転送なんて目からウロコでした。

ゾーン転送を行うために、certbot-keyと同様に、ddns-confgenコマンドを使って、externalという名前のTSIGキーを作ります。

[root@ace ~]# cat /var/named/keys/external
key "external" {
        algorithm hmac-sha256;
        secret "***非公開情報***=";
};

[root@ace ~]# ls -al /var/named/keys
合計 8
drwx------ 2 named named  41  2月 22 02:00 .
drwxrwx--T 9 root  named 190  2月 22 02:42 ..
-r-------- 1 named named 104  2月 21 22:26 certbot-key
-r-------- 1 named named 101  2月 22 02:00 external
[root@ace ~]#

「_acme-challenge.zeke.ne.jp」ゾーンを外部view側にも作って、更新がすぐに反映されるようにnotifyを発行するようにします。その際、ちょっと格好をつけて、IPv4(127.0.0.1)からIPv6(::1)に変更しています。

[root@ace ~]# cat /etc/named.conf
//
// named.conf
//
:
省略
:
options {
:
省略
:
};

logging {
:
省略
:
};

include "/etc/named.root.key";

include "/var/named/keys/certbot-key";

include "/var/named/keys/external";

view "internal" {

//      match-clients { !key external; localhost; localnets; };
        match-clients { !key external; localhost; };
:
省略
:
        server ::1 {
                /* Deliver notify messages to external view. */
                keys { external; };
        };

        zone "_acme-challenge.zeke.ne.jp" {
                type master;
                file "dynamic-dns/_acme-challenge.zeke.ne.jp.zone";
                allow-transfer { localhost; localnets; };
                check-names ignore;
                also-notify { ::1; };
                update-policy {
                        grant certbot-key name _acme-challenge.zeke.ne.jp. TXT;
                };
        };
:
省略
:
};

view "external" {

        match-clients { key external; any; };
:
省略
:        zone "_acme-challenge.zeke.ne.jp" {
                type slave;
                file "slaves/_acme-challenge.zeke.ne.jp.zone";
                masters { ::1; };
        };

};

[root@ace ~]#

このように、ちょっと複雑になってしまいましたが、TSIGキーを使ったゾーン転送を組み込みました。

と、ここまでは、1年前に調べた時の設定で、現行のdnsサーバはこれで動いています。

設定ファイルを見直して、最新化

先の参考リンクをよく見てみると

「bind 9.10以上だったらin-viewが使えるよ!」って書いてあります。1年前は書いてなかったけどなぁ。in-viewを使って書き直したものがこちらです。

※4月11日追記 外部から参照できるように、internal viewのzone “_acme-challenge.zeke.ne.jp”にallow-query { any; };を入れないとだめでした!

[root@ace ~]# cat /etc/named.conf
//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//

options {
        listen-on port 53 { any; };
        listen-on-v6 port 53 { any; };
        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";
        secroots-file   "/var/named/data/named.secroots";
        recursing-file  "/var/named/data/named.recursing";
        allow-query     { any; };

        /*
         - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
         - If you are building a RECURSIVE (caching) DNS server, you need to enable
           recursion.
         - If your recursive DNS server has a public IP address, you MUST enable access
           control to limit queries to your legitimate users. Failing to do so will
           cause your server to become part of large scale DNS amplification
           attacks. Implementing BCP38 within your network would greatly
           reduce such attack surface
        */
        recursion no;

        dnssec-enable yes;
        dnssec-validation yes;

        managed-keys-directory "/var/named/dynamic";

        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";

        /* https://fedoraproject.org/wiki/Changes/CryptoPolicy */
        include "/etc/crypto-policies/back-ends/bind.config";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
        channel query-log {
                file "/var/log/named/query.log";
                severity info;
                print-category yes;
                print-severity yes;
                print-time yes;
        };
        channel update-log {
                file "/var/log/named/update.log";
                severity info;
                print-category yes;
                print-severity yes;
                print-time yes;
        };
        channel default-log {
                file "/var/log/named/default.log";
                severity info;
                print-category yes;
                print-severity yes;
                print-time yes;
        };
        category queries      { query-log; };
        category update       { update-log; };
        category lame-servers { null; };
        category default      { default-log; };
};

include "/etc/named.root.key";

include "/var/named/keys/certbot-key";

view "internal" {

//      match-clients     { localhost; localnets; };
        match-clients     { localhost; };
        allow-query       { localhost; localnets; };
        allow-recursion   { localhost; localnets; };
        allow-query-cache { localhost; localnets; };
        allow-transfer    { localhost; localnets; };
        recursion yes;

        zone "." IN {
                type hint;
                file "named.ca";
        };

        zone "zeke.ne.jp" {
                type master;
                file "internal/zeke.ne.jp.zone";
        };

        zone "_acme-challenge.zeke.ne.jp" {
                type master;
                file "dynamic-dns/_acme-challenge.zeke.ne.jp.zone";
                check-names ignore;
                allow-query { any; };
                update-policy {
                        grant certbot-key name _acme-challenge.zeke.ne.jp. TXT;
                };
        };

        zone "lo.zeke.ne.jp" {
                type master;
                file "internal/lo.zeke.ne.jp.zone";
        };

        zone "0.0.a.c.3.0.d.c.0.c.2.0.1.0.0.2.ip6.arpa" {
                type master;
                file "internal/lo.zeke.ne.jp.rev6";
        };

        zone "1.168.192.in-addr.arpa" {
                type master;
                file "internal/lo.zeke.ne.jp.rev";
        };

view "external" {

        match-clients     { any; };
        allow-query       { any; };
        allow-recursion   { none; };
        allow-query-cache { none; };
        allow-transfer    { none; };
        recursion no;

        zone "zeke.ne.jp" {
                type master;
                file "external/zeke.ne.jp.zone";
        };

        zone "_acme-challenge.zeke.ne.jp" {
                in-view internal;
        };

[root@ace ~]#

むちゃくちゃ簡単になりました!不要になったkeyファイルやslaveファイル、ゾーン転送のログファイルを消しておきます。

まだ、インターネットから参照できないので、内部vewからlocalnetsを外して、windowsパソコンから確認してみます。

[root@ace ~]# nsupdate -k /var/named/keys/certbot-key
> server 127.0.0.1
> update add _acme-challenge.zeke.ne.jp. 3600 in txt test2
> send
> quit
[root@ace ~]#

サーバで、TXTレコードを書き換えてみると

Windowsパソコンから、書き換わっていることが確認できました!

certbotの設定

長い仕込が終わりました。ようやくcertbotの設定です。

[root@ace ~]# vi /etc/letsencrypt/rfc2136.ini
[root@ace ~]# cat /etc/letsencrypt/rfc2136.ini
# Target DNS server
dns_rfc2136_server = localhost
# Target DNS port
dns_rfc2136_port = 53
# TSIG key name
dns_rfc2136_name = certbot-key
# TSIG key secret
dns_rfc2136_secret = ***非公開情報***=
# TSIG key algorithm
dns_rfc2136_algorithm = HMAC-SHA256

[root@ace ~]# ls -al /etc/letsencrypt/
合計 16
drwxr-xr-x  7 root root  100  2月 22 02:54 .
drwxr-xr-x 79 root root 8192  2月 22 03:09 ..
drwx------  3 root root   50  2月 22 01:42 accounts
drwxr-xr-x  2 root root  258  2月 22 02:53 csr
drwx------  2 root root  258  2月 22 02:53 keys
drwxr-xr-x  2 root root    6  2月 22 01:42 renewal
drwxr-xr-x  5 root root   43  2月 22 01:42 renewal-hooks
-rw-------  1 root root  280  2月 22 02:53 rfc2136.ini
[root@ace ~]#

設定ファイルは、/var/named/keys/certbot-keyの内容を参考に記述します。ただし、dns_rfc2136_algorithmは大文字でないと認識してくれないようで、小文字で書いちゃうとエラーが出ます。設定ファイルは秘密情報が入っているので、root以外読めないようにしておきます。

[root@ace ~]# certbot certonly --dns-rfc2136 --dns-rfc2136-credentials /etc/lets
encrypt/rfc2136.ini -d *.zeke.ne.jp -d zeke.ne.jp -m zeke@mail.zeke.ne.jp  --agr
ee-tos --test-cert
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator dns-rfc2136, Installer None
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for zeke.ne.jp
dns-01 challenge for zeke.ne.jp
Waiting 60 seconds for DNS changes to propagate
Waiting for verification...
Challenge failed for domain zeke.ne.jp
Challenge failed for domain zeke.ne.jp
dns-01 challenge for zeke.ne.jp
dns-01 challenge for zeke.ne.jp
Cleaning up challenges
Some challenges have failed.

IMPORTANT NOTES:
 - The following errors were reported by the server:

   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

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address.
[root@ace ~]#

試しに、certbotコマンドを実行してみます。ここでは*.zeke.ne.jpのワイルドカードと、zeke.ne.jpのサーバ証明書を要求しています。また、テストのため–test-certオプションを付けています。

一番最初に実行すると、メールアドレスをメーリングリストに登録するか?みたいなメッセージが出てきます。このときは何回かやったあとなので、黙って実行してくれます。

まだ新しいdnsサーバは公開していないので、 _acme-challenge.zeke.ne.jpのTXTレコードを書き換えてから60秒待ってから諦めて、承認がおりていませんね。

外部view側のWindowsパソコンで確認すると、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"

今回はちょっと大変でした。問題なく動いている現行をそのままコピーすればいいのですが、おかしなところはないか調べ直したり、もっと簡単にできる方法を考えていたりとかしていたので。

お勧めのKindle本です!

コメント