2026年6月4日
2026年6月4日
Cloudflare SSLで証明書を自動化する手順|エッジとオリジンの更新を手放す設定
Cloudflareを経由するサイトの証明書は「閲覧者とCloudflareの間(エッジ)」と「Cloudflareとあなたのサーバーの間(オリジン)」の2枚があり、自動化はそれぞれ別に考えます。エッジ側はプロキシを有効にすればCloudflareが発行と更新を自動で行い、オリジン側はCloudflare Origin CA証明書を使うか、Let's EncryptをDNS認証(certbot-dns-cloudflare)で自動更新するのが現実的です。この記事では、2つの方法の選び方、設定手順、更新が止まったときの確認方法までを説明します。
証明書は2枚ある
Cloudflareのプロキシ(DNS画面でオレンジ色の雲のアイコン)を有効にすると、通信は次の2区間に分かれます。
- 閲覧者 → Cloudflare: ブラウザが検証するのはCloudflareが提示する証明書(エッジ証明書)です
- Cloudflare → オリジンサーバー: Cloudflareが検証するのは、サーバーに入れた証明書(オリジン証明書)です
「Cloudflareで証明書を自動化したのに期限切れの警告が出た」という相談の多くは、この2枚を混同していることが原因です。どちらの証明書の話なのかを最初に切り分けます。
エッジ証明書:Universal SSLで自動化される
プロキシを有効にしたホスト名には、Cloudflareが無料のUniversal SSL証明書を自動で発行し、期限前に自動で更新します。利用者側で更新作業をする必要はありません。発行元の認証局(CA)はCloudflareが選び、複数の認証局を使い分けています。
つまずきやすいのは次の点です。
- CAAレコード: ドメインにCAAレコードを設定して特定の認証局だけを許可している場合、Cloudflareが使う認証局が許可されていないと発行や更新ができません。Cloudflare側で必要なCAAを補う仕組みがありますが、手動で厳しく絞っているときは、ダッシュボードのエッジ証明書の状態が有効になっているかを確認してください。
- 対象ホスト名: Universal SSLが対象とするのは、通常はルートドメインと1階層のサブドメイン(
*.example.com)です。a.b.example.comのような深い階層は対象外となり、別の有料機能が必要になる場合があります。 - プロキシを外したホスト名: グレーの雲(DNSのみ)にしたホスト名には、Cloudflareの証明書は使われません。サーバーに直接アクセスされるため、オリジン証明書がブラウザに信頼されるものである必要があります。
機能の名称や有料プランとの切り分けは変わることがあるため、細かい仕様はCloudflareの公式ドキュメントで確認してください(2026年10月現在)。
SSL/TLSの暗号化モードは「フル(厳密)」にする
オリジン証明書を自動化する前に、暗号化モードを確認します。
- フレキシブル: Cloudflare → オリジンが暗号化されない。WordPressでは、サイトのURLがhttpsなのにサーバーにはhttpで届くため、リダイレクトループの原因にもなります
- フル: オリジンとも暗号化するが、証明書の有効性を検証しない
- フル(厳密): オリジン証明書が有効期限内で、ホスト名が一致し、信頼できる発行元のものかを検証する
自動化の目的は「期限切れに気付かず止まる」を防ぐことなので、検証を行うフル(厳密)を前提にします。フル(厳密)でオリジン証明書が無効なとき、閲覧者にはCloudflareのエラー526(無効なSSL証明書)が表示されます。Cloudflareにはモードを自動で選ぶ機能も用意されていますが、どのモードが選ばれているかはダッシュボードで確認しておきます。
オリジン側の方法1:Cloudflare Origin CA証明書
Cloudflareのダッシュボードで発行できるオリジン用の証明書です。有効期間を長く(最長15年)選べるため、更新の手間がほぼ無くなります。
- 長所: 発行が簡単で、更新の頻度が極めて少ない
- 短所: Cloudflareだけが信頼する証明書で、ブラウザは信頼しません。プロキシを一時的に外すと、閲覧者に証明書エラーが表示されます
発行時に作られる秘密鍵は、その画面でしか表示されません。保存したらサーバー上でパーミッションを絞り(chmod 600 など)、Gitなどのリポジトリに入れないようにします。Nginxでの指定は通常の証明書と同じです。
ssl_certificate /etc/ssl/cloudflare/origin.pem;
ssl_certificate_key /etc/ssl/cloudflare/origin.key;
有効期間を長くした場合でも、期限の日付はどこかに記録しておきます。何年も先の更新作業は、担当者が替わって忘れられがちだからです。
オリジン側の方法2:Let’s EncryptをDNS認証で自動更新する
プロキシを外す可能性がある場合や、ブラウザにも信頼される証明書をオリジンに置きたい場合は、Let's Encryptを使います。Cloudflare経由ではHTTP認証も通ることがありますが、リダイレクトやキャッシュ、WAFの設定に左右されるため、CloudflareのDNSにTXTレコードを書き込むDNS-01認証の方が安定します。ワイルドカード証明書もDNS-01でのみ取得できます。
APIトークンを用意する
Cloudflareのダッシュボードで、対象ゾーンに限定し、DNSの編集だけを許可したAPIトークンを作ります。アカウント全体を操作できるグローバルAPIキーは使いません。トークンは認証情報ファイルに書き、所有者以外が読めないようにします。
# /root/.secrets/certbot/cloudflare.ini
dns_cloudflare_api_token = your-api-token
sudo chmod 600 /root/.secrets/certbot/cloudflare.ini
certbotとプラグインを入れて取得する
certbotをsnapで入れている場合は、DNSプラグインもsnapで追加します(パッケージ名や手順はOSと配布形態で異なるため、certbotの公式手順を確認してください)。
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/certbot/cloudflare.ini \
--dns-cloudflare-propagation-seconds 60 \
-d example.com -d '*.example.com' \
--deploy-hook "systemctl reload nginx"
--deploy-hook は更新に成功したときだけ実行されるので、新しい証明書をWebサーバーに読み込ませる処理を書いておきます。これが無いと、ファイルは更新されたのに古い証明書を配信し続ける、という状態になります。
自動更新を確認する
snap版のcertbotは、更新用のタイマーを自動で登録します。登録されているか、更新が実際に通るかを確認します。
systemctl list-timers | grep certbot
sudo certbot renew --dry-run
--dry-run が成功すれば、本番の更新も同じ手順で行われます。
更新が止まったときの確認方法
まず、どちらの証明書が問題かを分けます。
# 閲覧者が見ている証明書(エッジ)
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -issuer -enddate
# オリジンの証明書(Cloudflareを通さずサーバーに直接つなぐ)
echo | openssl s_client -connect 203.0.113.10:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -issuer -enddate
203.0.113.10 はオリジンサーバーのIPアドレスに置き換えます。原因になりやすい順に確認します。
- 更新後にWebサーバーを再読み込みしていない: ファイルの期限は新しいのに配信中の証明書が古い場合です。
--deploy-hookを確認します - APIトークンの権限や期限: トークンを削除・再作成した、対象ゾーンが違う、などで
--dry-runが認証エラーになります。/var/log/letsencrypt/letsencrypt.logに詳細が残ります - DNSの伝播待ちが短い: TXTレコードが見える前に検証が始まると失敗します。
--dns-cloudflare-propagation-secondsを延ばします - CAAレコード: Let's Encryptが許可されていないと発行できません
Let's Encryptは有効期限の通知メールを2025年に終了しているため、期限切れを知らせてくれる仕組みは自分で用意します。上の openssl のコマンドを定期実行して残り日数を見るか、外部の監視サービスを使います。
まとめ
- Cloudflare経由の証明書はエッジとオリジンの2枚で、自動化は別々に考える
- エッジ証明書はUniversal SSLで自動発行・自動更新される。CAAレコードと対象ホスト名に注意
- 暗号化モードはフル(厳密)にし、オリジン証明書の期限切れに気付ける状態にする
- オリジンは、Cloudflare専用でよければOrigin CA、ブラウザにも信頼させたいならLet's EncryptのDNS-01(APIトークンは最小権限)
- 更新後の再読み込みと、期限の監視までを含めて自動化とする