Let's Encryptの設定メモ

作成日:2019.01.27
更新日:2024.07.13

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 に赤字の部分を追加する。

/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 のサブドメインに対するネームサーバーの定義を追加する(赤字の部分)。

zone/jp.nminoru.defs、zone/jp.nminoru-intra.defs:
$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 とする。

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 には毎回変わるランダムな文字列が入る。

/etc/letsencrypt/dns-01-auth.sh
#! /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
/etc/letsencrypt/dns-01-clean.sh
#! /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

成功すれば以下のようなメッセージが表示される。

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 ができる。

コメント

コメントを書き込む

TOP    掲示板    戻る
Written by NAKAMURA Minoru, Email: nminoru atmark nminoru dot jp, Twitter:@nminoru_jp