それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

certbot でドメインのDNSプラグインで、ドメイン毎DNS-01をし複数ドメイン証明書を1枚にまとめたい。

dnsプラグインを複数使いたい。

たとえば、次のような証明書を発行要求したいとする。

cert domain
commonName example.tld
subjectAltName DNS:example.tld, DNS:example.biz,DNS:second.tld

ただし、DNSの管理先はそれぞれ別のDNSサーバになっているとする。

Base Domain DNS
example.tld cloudflare
example.biz my_own
second.tld cloudflare

この場合でも、Let'sEncryptのDNS-01チャレンジは、証明書発行が行える。

DNS-01チャレンジを手作業でTXTレコードを書き込みに行く必要がある。

certbotプラグインで自動化を断念。

プラグインが3つ必要になる。

Base Domain DNS plugin User
example.tld cloudflare Cloudflare Plugin takuya
example.biz my_own MyOwn Plugin my own
second.tld cloudflare Cloudflare Plugin another user

複数個プラグインだとcertbotへの指定方法は不明だった。複数のプラグインを使ったCertbotでのDNS-01チャレンジは出来なかった。

つまり自動化出来なかったのである。

certbot は非対応である。(たぶん)

https://certbot-dns-cloudflare.readthedocs.io/en/stable/

マニュアルを読む限り、CertbotDNS毎にプラグインを指定するのは難しそうである。(2023-02-20現在 )

Cloudflareが複数アカウントになった場合、証明書の発行に対応できないっぽい

対応策。自分でプラグインを書く。

なら、certbotプラグインプラグインを自分で作れば良い。プラグインを呼び出すプラグインがあれば良い。異なるDNSサーバに管理された複数ドメインを更新するプラグインを掛けば良いのである。

書いた。

python で書いてもcertbot への依存が残る。

コマンドを呼び出すsystemdを管理するのがもう嫌。systemd がデフォルトでcertbot をインストールするのでそれを拡張して書き直すのは大変だし。

でも途中で捨てた。

ゼロからsystemdを書いて管理するとpythonのvenv が大変だし。疲れたのよ。

作った証明書を各Dockerインスタンスに配布したり、仮想マシンに埋め込んだりが大変だし。SSHで転送するのはcertbot がroot権限要求するし。PKCS12にまとめるコードも書いたり、シェルスクリプトが肥大化していく。

WEBアプリにしよう。

で、思い切って、pythonを捨てて、php完全にライブラリ動作するように書いた。

これなら、php 出来た管理画面を持つアプリケーションに埋め込むことができる。つまり、OPNSenseやOpenMediaValutやnextcloudのようなPHPアプリケーションへ証明書発行と自動更新機能を作り込む事が可能になるはずだ。

使い方。

php の composeer でインストールして

composer require takuya/php-letencrypt-acme-dns

DNS毎のプラグインを有効化する。

<?php
// set dns plugin per Domain.
$pkey='priv_key_pem';
$mail = 'your_email@gmail.com' ;
$cli = new LetsEncryptAcmeDNS($pkey , $mail);
$dns_plugin_1 = new CloudflareDNSPlugin( 'token1', 'example.tld' );
$dns_plugin_2 = new CloudflareDNSPlugin( 'token2', 'example.biz' );
$cli->setDnsPlugin( $dns_plugin_1, 'example.tld' );
$cli->setDnsPlugin( $dns_plugin_2, 'example.biz' );

証明書を発行する

$result= $cli->orderNewCert();

複数アカウントに分かれたCloudflare。

これで、「複数アカウントに分かれたCloudflareのドメイン」を使った「複数ドメインをSANに纏めた1枚の証明書」の発行に対応できた。

ああ、しんどかった。

レポジトリ

つくったレポジトリ

https://github.com/takuya/php-letencrypt-acme-dns