Open9

プライベートネットワーク内でACEME DNS01 challengeを実現する

あごしあごし

DNS-01 challengeで必要となるコンポーネント

  • PKI (hashicorp Vaultを使う)
  • DNS (powerDNSで建てる)
  • ACMEクライアント (Certbotを利用。今後はLegoにしようと思っている。)

上のコンポーネント使って、証明書を取得することはできた。DNSにTXTレコードを登録するところは手動になってしまっているので、DNSのAPIを使って自動登録できるようにしたい。
必須ではないがDNSSECを有効にして、セキュアに登録したい。

あごしあごし

powerdnsのDNSSEC有効化方法。

# vi /etc/pdns/pdns.conf
## 以下を追記。バックエンドがpostgresqlの場合。
gpgsql-dnssec=yes

# systemctl restart pdns
# pdnsutil secure-zone <<zone名>>

クライアント側は特に設定は不要っぽい。
本当にsecureになっているか確認したい。

あごしあごし

PowerDNS api有効化

とりあえずapiを有効化する。

 # vi /etc/pdns/pdns.conf
api=yes
api-key=<<任意の文字列を設定>>

# systemctl restart pdns

confファイルにAPI key書くの良くない。hashicorp vaultから取得する様にできないかな。
現在APIちゃんと使えているのか確認どうする?

あごしあごし

API使うにはpdns.confのwebserver系パラメータを変更する必要あった。

# vi /etc/pdns/pdns.conf
webserver=yes
// 外部からのリクエストを受信するには0.0.0.0か、DNSサーバの物理IPを設定
webserver-address=0.0.0.0
// デフォルトはlocalhostのみになっている。許可するネットワークアドレスを設定。
webserver-allow-from=192.168.0.0/24
あごしあごし

clientにlegoをインストールする。

https://go-acme.github.io/lego/installation/index.html
almalinuxだとsnapでインストール。まずはsnapを入れる。

snapdをインストールする。

# dnf install -y epel-release
# dnf install -y epel-next-release
# ln -s /var/lib/snapd/snap /snap
 echo 'export PATH=$PATH:/var/lib/snapd/snap/bin' > /etc/profile.d/snap.sh
# systemctl enable --now snapd.service snapd.socket
Created symlink /etc/systemd/system/multi-user.target.wants/snapd.service → /usr/lib/systemd/system/snapd.service.
Created symlink /etc/systemd/system/sockets.target.wants/snapd.socket → /usr/lib/systemd/system/snapd.socket.

legoインストール

# snap install lego
あごしあごし

legoで証明書を取得できない問題。

# PDNS_API_URL=http://<<DNSサーバFQDN>>:8081 PDNS_API_KEY=<<API KEY>> lego --email <<mail address>> --dns pdns --domains <<ターゲットサーバのFQDN>> --server https://<<Hashicorp Vaultのエンドポイント>> run

2024/11/05 22:22:12 [INFO] [] acme: Waiting for DNS record propagation.
2024/11/05 22:22:14 [INFO] [] acme: Cleaning DNS-01 challenge
2024/11/05 22:22:14 [INFO] retry due to: acme: error: 400 :: POST :: https://vault01.uws.lan:8200/v1/pki_int/acme/authorization/0de76562-b8bb-a015-d070-4fae79668193 :: urn:ietf:params:acme:error:badNonce :: invalid or reused nonce: The client sent an unacceptable anti-replay nonce
2024/11/05 22:22:15 [INFO] Deactivating auth: 
2024/11/05 22:22:15 Could not obtain certificates:
        error: one or more domains had a problem:
[] propagation: time limit exceeded: last error: [zone=] could not determine authoritative nameservers

DNSレコード(TXTレコード)として登録されていることは確認済み。
legoが登録したDNSレコードは手元のWindowsでも引けない。
curlで同じ内容を登録すると手元のWindowsで引ける。

あごしあごし

legoではどうしても問題解決できない。

https://pypi.org/project/certbot-dns-powerdns/
certbotにpowerdns pluginあったのでインストール。

cert取得に成功した。

# certbot --authenticator 'dns-powerdns' --dns-powerdns-credentials ./pdns-credentials.ini certonly --preferred-challenges dns --server https://<<vault FQDN>>:<<vault port>>/v1/pki_int/acme/directory -m <<e-mail address>> --agree-tos -d <<domain name(common name)>>

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Renewing an existing certificate for <<domain name(common name)>>
Waiting 60 seconds for DNS changes to propagate

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/<<domain name>>/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/<<domain name>>/privkey.pem
This certificate expires on 2024-12-08.
These files will be updated when the certificate renews.

NEXT STEPS:
- The certificate will need to be renewed before it expires. Certbot can automatically renew the certificate in the background, but you may need to take steps to enable that functionality. See https://certbot.org/renewal-setup for instructions.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -