HTTPS の運用にコントロールパネルは必要ありません。Certbot や acme.sh を使えば、Nginx 上のどのサイトにも Let's Encrypt の無料証明書を取得でき、Cloudflare DNS API を使って *.example.com のようなワイルドカード証明書を発行し、自動で更新することもできます。この記事では、Debian/Ubuntu と Rocky Linux/AlmaLinux での両ツールの使い方、Nginx の HTTPS 設定、Cloudflare プロキシ配下のサイト、そして更新が本当に機能しているかの確認方法を解説します。
dig +short example.com で確認できます。Certbot は証明書を取得したうえで、HTTP から HTTPS へのリダイレクトも含めて Nginx の server ブロックを自動で編集してくれます。
# Debian / Ubuntu
apt update
apt install -y certbot python3-certbot-nginx
# Rocky Linux / AlmaLinux (EPEL)
dnf install -y epel-release
dnf install -y certbot python3-certbot-nginx
# Request and install a certificate for the domain and www
certbot --nginx -d example.com -d www.example.com \
--agree-tos -m [email protected] --redirect
# Renewal is scheduled automatically; confirm the timer and run a test renewal
systemctl list-timers | grep -i certbot
certbot renew --dry-run
証明書は /etc/letsencrypt/live/example.com/ に保存されます。Nginx の設定ファイルを書き換えられたくない場合は certbot certonly --nginx -d example.com を使い、後述の「Nginx の HTTPS 設定」のように証明書のパスを自分で追加してください。
acme.sh は cron ジョブとして動作する単一のシェルスクリプトです。既定の認証局(CA)は ZeroSSL なので、必要に応じて Let's Encrypt に切り替えてください。
# Install (creates ~/.acme.sh and a daily cron job)
curl https://get.acme.sh | sh -s [email protected]
source ~/.bashrc
# Use Let's Encrypt as the default CA
acme.sh --set-default-ca --server letsencrypt
# Issue using your site's web root (HTTP-01 validation)
acme.sh --issue -d example.com -d www.example.com -w /var/www/example
# Install the certificate where Nginx expects it and reload Nginx on every renewal
mkdir -p /etc/nginx/ssl
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--reloadcmd "systemctl reload nginx"
Nginx から ~/.acme.sh 内のファイルを直接参照してはいけません。必ず --install-cert を使ってください。このオプションはファイルをコピーし、更新のたびにリロードコマンドを実行します。
ワイルドカード証明書(*.example.com)の取得には DNS 認証が必要です。ドメインで Cloudflare DNS を使っている場合は、Cloudflare ダッシュボードの My Profile → API Tokens で「Edit zone DNS」テンプレートを使って API トークンを作成し、対象を必要なゾーンだけに限定します。
# acme.sh: dns_cf reads the token from the environment and saves it for renewals
export CF_Token="your-cloudflare-api-token"
export CF_Zone_ID="your-zone-id" # shown on the domain's Overview page in Cloudflare
acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'
# Certbot alternative
apt install -y python3-certbot-dns-cloudflare
mkdir -p ~/.secrets && chmod 700 ~/.secrets
echo 'dns_cloudflare_api_token = your-cloudflare-api-token' > ~/.secrets/cloudflare.ini
chmod 600 ~/.secrets/cloudflare.ini
certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
-d example.com -d '*.example.com'
DNS 認証はポート 80 が閉じている場合や、サイトにまだアクセスできない場合でも使えるため、内部サービスや構築直後のサーバーにも便利です。
certonly や acme.sh で証明書を発行した場合は、HTTPS 用の server ブロックを自分で追加します。証明書のパスは使用したツールに合わせて変更してください。
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on; # Nginx 1.25.1+; older versions: "listen 443 ssl http2;"
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # acme.sh: /etc/nginx/ssl/example.com.crt
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # acme.sh: /etc/nginx/ssl/example.com.key
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:SSL:10m;
root /var/www/example;
index index.html index.php;
}
nginx -t && systemctl reload nginx
オレンジ色の雲(プロキシ)を有効にしていても、Cloudflare が /.well-known/acme-challenge/ へのリクエストをサーバーに転送するため、通常は HTTP 認証もそのまま使えます。オリジンに有効な証明書を設定したら、Cloudflare の SSL/TLS 暗号化モードを Full (strict) にしてください。「Flexible」ではサーバーまでの通信が暗号化されず、リダイレクトループの原因にもなりがちです。DNS 認証を使う方法もあり、サイトを常に Cloudflare 経由でのみ配信するなら無料の Cloudflare Origin Certificate も利用できます。訪問者が Cloudflare を経由せずにアクセスするのを防ぐには、オリジン IP を隠す方法を参照してください。
# Expiry date of the certificate your site actually serves
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
# Certbot: all certificates and their expiry
certbot certificates
# acme.sh: list certificates and force a test renewal
acme.sh --list
acme.sh --renew -d example.com --force
ポート 80 がブロックされている、DNS レコードが別の場所を指している、または別の server ブロックがそのドメインに応答している可能性があります。ファイアウォールを確認し、dig +short example.com を実行したうえで、Nginx の設定で /.well-known/acme-challenge/ がリダイレクトや拒否の対象になっていないことを確認してください。それでも解決しない場合は DNS 認証に切り替えます。
Let's Encrypt では、同じドメイン名に対して 1 週間に発行できる証明書の数に上限があります。試行錯誤している間は --dry-run(Certbot)や --staging(acme.sh)を使い、設定が正しく動作してから本番の証明書を取得してください。
はい。各ドメイン名をそれぞれ -d オプションで追加します。ワイルドカードが対象とするのは 1 階層だけなので、*.example.com は shop.example.com には一致しますが、a.shop.example.com や example.com 自体には一致しません。ルートドメインは別途追加してください。
上記の手順で解決しない場合は、サポートチケットを送信して IMIDC の 24 時間 365 日対応テクニカルサポートへご連絡ください。サーバー IP、OS バージョン、ドメイン名、実行したコマンド、エラー全文を添えていただくと、より迅速に調査できます。