SSD Nodes Learn
ガイド Matt Connor著者 Matt Connor ・更新日 2026-07-24

Certbotでワイルドカード証明書をDNS-01チャレンジで取得する方法

Let's Encryptのワイルドカード証明書取得にはDNS-01チャレンジが必須です。TXTレコードによるドメイン所有権の証明方法や、更新を自動化するために必要なCertbot DNS pluginの導入手順を解説します。手動更新の失敗を防ぎ、APIを利用して自動更新を実現する設定方法を確認しましょう。

Why a wildcard certificate needs DNS-01

A wildcard certificate covers every first-level subdomain of a domain: *.example.com matches app.example.com, blog.example.com, and any other name one label deep. Let's Encrypt issues wildcard certificates only through the DNS-01 challenge, so Certbot has to prove control of the domain's DNS by publishing a TXT record at _acme-challenge.example.com. The HTTP-01 challenge cannot qualify, because serving a token file proves control of one hostname, the one the validation server fetched the file from. A wildcard is a claim about every possible name under the domain, and the only public record that speaks for the whole namespace is DNS itself.

That one requirement decides everything else on this page. To pass DNS-01 you must be able to create TXT records in the domain's zone, either by hand or through your DNS provider's API (application programming interface). The by-hand route works once and then fails at renewal, for a concrete reason shown below. The API route, through a Certbot DNS plugin, renews unattended, and it is the setup you should end with.

This is the wildcard chapter of our Certbot guides. Ordinary single-hostname certificates, the web server configuration and the port 80 rules are covered in Certbot with nginx on Ubuntu 24.04 and Certbot with Apache on Ubuntu 24.04.

_acme-challenge TXT record の仕組み

Certbot が *.example.com をリクエストすると、Let's Encrypt はランダムなトークンを返します。Certbot はそのトークンを ACME (automatic certificate management environment) アカウントキーと組み合わせ、SHA-256 でハッシュ化して、短いテキスト値を作成します。その値は _acme-challenge.example.com に TXT レコードとして登録されている必要があります。その後、Let's Encrypt は自身のインフラからドメインの権威ネームサーバーにクエリを送信します。読み取ったレコードが期待される値と一致すれば、ドメインの管理権限が証明されたことになります。ゾーンの管理権限は、その配下にあるすべての名前の管理権限として認められます。

失敗の主な原因は以下の2点です。

  • 同一の証明書に対して example.com*.example.com をリクエストする場合、これらは2つの個別のチャレンジとなります。両方の TXT レコードは同じ名前 _acme-challenge.example.com に配置されます。両方のレコードが同時に存在しなければなりません。2つ目のレコードを追加するのは正しい方法ですが、1つ目を2つ目で上書きすると、1つ目のチャレンジが失敗します。
  • バリデーションは権威サーバーを読み取りますが、プロバイダーのコントロールパネルで新しいレコードが反映されるまでに1分以上かかる場合があります。バリデーションを実行する前に、外部から確認してください。
dig +short TXT _acme-challenge.example.com @1.1.1.1

出力された値が Certbot の要求したものと一致すれば、バリデーションは成功します。何も表示されない場合は、待機してから再度実行してください。

動作確認:マニュアルモード

マニュアルモードでは、DNSの編集を手動で行います。自動化する前に仕組みを理解するのに最適な方法です。

sudo certbot certonly --manual --preferred-challenges dns -d example.com -d '*.example.com'

ワイルドカードを引用符で囲むことで、シェルが * をファイル名パターンとして扱うのを防ぎます。Certbotは、以下の指示を表示して一時停止します。

Please deploy a DNS TXT record under the name:
_acme-challenge.example.com.
with the following value:
Jx9mQ2wLr8vTn5cKp0aYdG3hB7fZs4eN1oiRuXqMk6E

DNSプロバイダーの管理パネルで、そのTXTレコードを作成してください。上記の dig コマンドでレコードが確認できたら、Enterキーを押してください。この実行では、ベースドメインとワイルドカードの両方が要求されるため、Certbotは2回プロンプトを表示します。証明書の発行が完了するまで、両方のレコードを保持してください。成功すると、以下のメッセージが表示されます。

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem

manual mode が自動更新できない理由

更新のたびに新しい token が発行されるため、TXT 値は毎回変化します。今日貼り付けたレコードは、60 日後には使用できません。Certbot の更新タイマーは 1 日に 2 回、自動で実行されます。その際、新しい値を貼り付ける操作は行われないため、手動で発行した証明書は以下のエラーで更新に失敗します。

Failed to renew certificate example.com with error: The manual plugin is not
working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with
--manual-auth-hook when using the manual plugin non-interactively.')

DNS プロバイダーの API を呼び出す --manual-auth-hook スクリプトを作成すれば、この要件を満たせます。しかし、その場合は DNS プラグインを自作することになります。manual mode は、フローの学習や、DNS の自動化がまだできないドメインでの単発の作業に使用してください。Let's Encrypt は有効期限の通知メールを送信しなくなったため、90 日目よりかなり前にリマインダーを設定してください。それ以外の用途には、プラグインを使用してください。

The plugin route: certbot-dns-cloudflare on Ubuntu 24.04

DNS pluginは、DNSプロバイダーのAPI認証情報を保持します。証明書の発行時および更新時に、TXTレコードの操作を自動で行います。ここでは、多くのユーザーが必要とし、Ubuntuのパッケージとして提供されているCloudflareを例に説明します。

Ubuntu 24.04では、Certbotのガイドに従い apt パッケージの使用を推奨します。Cloudflareの場合も同様です。

sudo apt update
sudo apt install certbot python3-certbot-dns-cloudflare

バージョンに関する補足です。24.04のアーカイブでは、このpluginは version 2.0.0、Certbotは version 2.9.0 として提供されます。apt policy python3-certbot-dns-cloudflare で自身のバージョンを確認してください。このバージョンの違いに問題はありません。24.04の python3-cloudflare ライブラリは version 2.11.1 であり、pluginがトークンをサポートするために必要な version 2.3.1 を満たしているため、Scoped API Tokenが使用可能です。古いUbuntuリリースでは、このライブラリが古いためにトークンが使用できず、apt pluginが Global API Keyの使用を強制するという警告がオンラインで見られることがありますが、24.04ではこれらは該当しません。

Cloudflareのダッシュボードで、Global API Keyではなく、Scoped API Tokenを作成してください。My Profile > API Tokens > Create Token の順に進み、Permissionを Zone / DNS / Edit の1つのみに設定し、対象のzoneに限定します。作成したトークンは、rootのみが読み取れるファイルに保存してください。

sudo mkdir -p /root/.secrets
sudo tee /root/.secrets/cloudflare.ini > /dev/null <<'EOF'
dns_cloudflare_api_token = paste_your_scoped_token_here
EOF
sudo chmod 600 /root/.secrets/cloudflare.ini

Certbotはファイルの権限をチェックします。他のユーザーが読み取れる状態の場合、Unsafe permissions on credentials configuration file に関する警告が表示されます。以下のコマンドで発行を開始します。

sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
  -d example.com -d '*.example.com'

pluginはAPI経由でTXTレコードを作成し、伝播を待機した後、バリデーションを実行し、最後にレコードを削除します。Zoneのネームサーバーの変更反映が遅い場合は、--dns-cloudflare-propagation-seconds 60 で待機時間を増やしてください。証明書は /etc/letsencrypt/live/example.com/ に保存されます。nginxやApacheの設定では、ベースガイドの指示通りに fullchain.pemprivkey.pem を指定し、deploy hookを設定してください。

プロバイダーの plugin が apt に存在しない場合

24.04 の archive では、Cloudflare、Route 53、DigitalOcean、および汎用的な RFC 2136 インターフェースなど、限られたプロバイダーの plugin のみがパッケージ化されています。一覧を確認するには apt search certbot-dns を実行してください。対象のプロバイダーがない場合、当サイトの「apt優先」という原則とは異なる対応が必要です。代わりに snap から Certbot と plugin をインストールしてください。その際、/etc/letsencrypt の更新タイマーが競合しないよう、先に apt 版の Certbot を削除してください。

sudo apt remove certbot python3-certbot-dns-cloudflare
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-yourprovider

snap 版の plugin は snap 版の Certbot にのみ接続します。apt 版の Certbot を拡張することはできません。そのため、両方のインストールを共存させてはいけません。また、DNS ホストが API を提供していない場合は、API を持つプロバイダーへ DNS を移管するか、独自の name server を運用して rfc2136 plugin をそちらに向ける必要があります。

更新:60日後ではなく、今すぐテストする

Certbotは、authenticator = dns-cloudflareや認証情報のパスを含む、各証明書の発行情報を/etc/letsencrypt/renewal/example.com.confに記録します。これにより、標準の1日2回のタイマー実行によって、ユーザーの操作なしで更新が行われます。以下の手順で、staging environmentを使用したテストを行ってください。

sudo certbot renew --dry-run

テストが成功すれば、認証情報が有効であり、検証がエンドツーエンドで完了することを意味します。60日後の実際の更新も、これと同じ手順で行われます。今日、以下の2点を確認しておくことを推奨します。

  1. ディスク上の証明書が更新されても、web serverをreloadするまで反映されません。nginxまたはApacheのガイドに従って、deploy hookを設定してください。
  2. 認証情報ファイルは厳重に管理してください。このファイルを読み取れるユーザーは、DNS zoneを編集できます。これは、メールの転送や、独自のDNS-01 challengeのパスを操作するのに十分な権限です。/root配下ではmode 600に設定し、tokenの範囲を1つのzoneに限定してください。また、漏洩の疑いがある場合は、速やかにrotateしてください。

ワイルドカードが不要なケース

ワイルドカードは、多数のサブドメインや、予測できないサブドメインを扱う際に有効です。それ以外のケースでは、デフォルトとして使用すべきではありません。

  • 特定の1つのサブドメイン、または少数の既知のサブドメインの場合:通常のSAN (subject alternative name) 証明書の方がシンプルです。certbot --nginx -d example.com -d www.example.com -d app.example.com は HTTP-01 を使用して最大 100 個の名前をカバーします。また、サーバー上に DNS API の認証情報を保持する必要がありません。
  • ワイルドカードは、正確に1つのラベルに一致します。*.example.comexample.com をカバーできないため、上記のコマンドでは両方を要求しています。また、a.b.example.com もカバーしません。これには *.b.example.com が必要です。
  • すべてのサブドメインは、1つの秘密鍵を使用します。その鍵を保持するマシンが侵害されると、ワイルドカードがカバーするすべての名前が同時に影響を受けます。
  • Traefik がコンテナの TLS (transport layer security) を終端する場合、Certbot は一切不要です。Traefik が DNS-01 を使用してワイルドカード証明書を直接リクエストする 場合、同じ種類のプロバイダー・トークンを使用します。

ワイルドカードが真に有用なケース:証明書を再発行するよりも速く作成される、顧客別またはアプリ別のサブドメイン。および、WireGuard VPN 経由でのみ到達可能なサービスなど、公開ポート 80 を持たない内部ホスト。DNS-01 は証明書を取得するホストに接続しないため、完全にプライベートなマシンでも公開された信頼できる証明書を保持できます。

FAQ

HTTP-01 で Certbot は wildcard certificate を発行できますか?

いいえ。HTTP-01 は単一の hostname の所有権を証明する仕組みです。検証サーバーが指定された名前から token file を取得するためです。wildcard はドメイン内のすべての名前をカバーするため、Let's Encrypt は DNS-01 challenge を要求します。--nginx--apache--webroot--standalone の authenticator はすべて HTTP ベースです。唯一の方法は、手動または DNS plugin を使用して _acme-challenge.example.com に TXT record を配置することです。

wildcard certificate は root domain をカバーしますか?

いいえ。wildcard は正確に 1 つの label にのみ一致します。そのため、*.example.comwww.example.com をカバーしますが、bare な example.coma.b.example.com はカバーしません。-d example.com -d '*.example.com' を使用して、1 つの certificate に両方の名前を含めてリクエストしてください。これにより 2 つの challenge が作成されます。両方の TXT record は同じ _acme-challenge.example.com 名に配置されるため、1 つ目の record を削除せずに 2 つ目を追加してください。

なぜ wildcard certificate は自動更新されませんか?

--manual で発行されたためです。更新のたびに新しい TXT 値が必要です。unattended timer はその値を貼り付けることができないため、更新は An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively エラーで停止します。certbot-dns-cloudflare などの DNS plugin を使用して certificate を再発行するか、プロバイダーの API 経由で record を編集する --manual-auth-hook--manual-cleanup-hook スクリプトを用意してください。

_acme-challenge TXT record が反映されるまでどのくらいかかりますか?

DNS provider によって異なります。数秒から数分かかる場合があります。検証は zone の authoritative servers を読み取ります。手動実行を継続する前に、dig +short TXT _acme-challenge.example.com @1.1.1.1 で確認し、期待される値が表示されるまで待機してください。plugin を使用している場合、検証時に record が見つからないというエラーが出たときは、--dns-cloudflare-propagation-seconds 60 などの propagation option を使用して、組み込みの待機時間を増やしてください。

wildcard certificate は通常の certificate よりもセキュリティが低いですか?

暗号技術は同一です。違いは運用面にあります。1 つの private key がすべての subdomain をカバーするため、漏洩時の影響範囲が広くなります。また、automation に必要な DNS API 認証情報は、サーバー上に保存される機密情報です。既知の少数の subdomain のみを運用する場合は、SAN certificate を使用することで両方の問題を回避できます。本ガイドでは、まさにその場合に wildcard を使用しないよう推奨しています。