小さなブログ

GeminiのためのLet’s Encrypt

(2025.04 更新)

GeminiカプセルことGeminiプロトコル用サイトを公開するために、HTTPポートを開けずに「Let’s Encrypt」のTLS用証明書を得た方法の記録です。環境はUbuntuで、Snap導入済み。細かい用語の説明は省きます。

Certbotを準備

Let’s Encryptの証明書を得る一連の手続きを「ACMEプロトコル」といいます。それを行う公式のACMEクライアントが「Certbot」です。次のコマンドでインストールします。

$ sudo snap install --classic certbot

参考:Certbot Instructions: Web Hosting Product on Linux(snap)

ちなみに、CertbotはAPTでもインストールできるものの、大抵はバージョンが古く、後述するCertbotプラグインの導入にも問題があるため避けます(一度やって失敗した。適切なリポジトリを設定すればいいのだろうけど……)。

チャレンジと課題

ACMEプロトコルにおいて、あるドメインの証明書を得るには、要求する者がそのドメインの管理者であることをまず認めてもらわねばなりません。これを「チャレンジ」といい、複数の方法が用意されています。

Certbotがデフォルトで試みるのは、当該ドメインのウェブサーバーを利用する「HTTPチャレンジ」です。HTTPのウェブサイトをHTTPS化したい、との最も一般的な需要に対応しているのでしょう。

参考:Challenge Types: HTTP-01 challenge

しかしながら、Geminiカプセルの運営を目的とする場合には、同じドメインでウェブサーバーが稼働しているとは限りません。無用なアクセスやリスクを避けるため、むしろHTTPポートは閉じていたい。これが個人的な課題です。

DNSチャレンジ

そこで、HTTPチャレンジの代わりに「DNSチャレンジ」を行うことにします。

参考:Challenge Types: DNS-01 challenge

DNSチャレンジの流れはこうです。

DNS設定に慣れてさえいれば簡単です。この場合、ウェブサーバーはもちろん不要というか無関係。

DNSチャレンジによる証明書取得を対話的に行うには、次のCertbotコマンドを使います。

$ sudo certbot certonly --domain DOMAIN --preferred-challenges dns --manual

参考:Certbot: User Guide

オプションの意味は察しがつくでしょう。「certonly」は証明書取得のみ(自動的に配備しない)、「--domain」は対象ドメイン名、「--preferred-challenges」はチャレンジ方法、「--manual」は対話的な手動実行を指示します。

実行すると、このたびDNSに登録すべきトークン、TXTレコードの名前と値が表示され、待ち状態になります。DNSにそれを登録し、(時間を適当においてから)対話を先に進めると、CertbotがDNSの確認を始め、間違いなければ証明書が発行されます。

Let’s Encryptに関する手続きはこれだけ。あとは、生成された証明書ファイルと鍵ファイルをGeminiサーバーに設定してやれば完了です。

証明書の更新

Let’s Encryptの証明書には有効期限があります。有効期限が切れる前に、再び上のコマンドで証明書を取得しなくてはなりません。数か月に一度のこととはいえ、やはり少々面倒ですね。

しかし自動化するとなると、DNSチャレンジをどうするかが問題になります。ありがたいことに、代表的なDNSプロバイダーに対する自動処理プログラムが「Certbotプラグイン」としていくつか用意されています。詳しくはウェブ上のCertbot公式ドキュメントを参照のこと。

対Cloudflareの例

うちではCloudflareのDNSを使っており、そのために実際にした手順を一例として示します。

参考:Welcome to certbot-dns-cloudflare’s documentation!

まず、Cloudflare用のCertbotプラグインをインストールします。

$ sudo snap set certbot trust-plugin-with-root=ok
$ sudo snap install certbot-dns-cloudflare
$ sudo snap connect certbot:plugin certbot-dns-cloudflare

次に、専用の設定ファイルを作ります。パス・ファイル名は任意ですが、ここでは「~/.secret/certbot/cloudflare.ini」としました。中身は下記のような、Cloudflare APIトークンを指定するだけのテキスト。ファイルのパーミッションは600にします。

# CertbotがDNS設定に使うCloudflare APIトークン
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567

指定すべきAPIトークンは、Cloudflareのダッシュボードで作成できます。その際、対象ドメインのDNSを操作する権限(Zone:DNS:Edit)を与えること。

これで準備完了。次のコマンドを実行すれば、自動DNSチャレンジによる証明書の取得・更新ができます。

$ sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.secret/certbot/cloudflare.ini --domain DOMAIN --non-interactive

「--dns-cloudflare」はCloudflare用Certbotプラグインの使用、「--dns-cloudflare-credentials」はそのための設定ファイルを指示します。「--non-interactive」により、ユーザーの選択を待つことなく、証明書の有効期限が近いときだけ実際の処理が走ります。有効期限に関係なく仮試行するには、これに「--dry-run」を加えます。

結果に問題なければcronに登録します。念のため、ログや証明書をときどき確認するとよいでしょう。

#note