443ポートを塞いだまま Let’s Encrypt 更新
ここ最近、ストーカーのような海外アクセスが多く、
サーバーの 443 ポートを「日本+検索ボット限定」に絞り込んでいました。
ところが、思わぬ副作用が。
Let’s Encrypt(certbot)で証明書を更新しようとしたところ、
Timeout during connect (likely firewall problem)
というエラー。
原因は 認証サーバーが海外から 443 にアクセスしてくるのに、こちらで塞いでいたため。
試行錯誤の記録
preferred-challenges = http を設定してみた
→ でも /.well-known/acme-challenge/ が https にリダイレクトされてしまうため、やはり失敗。
ログに outbound1.letsencrypt.org のアクセスを発見!
→ これで「確かに来ているのに 301 リダイレクトされてる」ことが判明。
RewriteCond で acme-challenge を例外扱い に修正
RewriteEngine On
Let’s Encrypt 用は例外
RewriteCond %{REQUEST_URI} ^/.well-known/acme-challenge/ [NC]
RewriteRule ^ - [L]
それ以外は HTTPS 強制 & 正規ドメイン以外拒否
RewriteCond %{HTTP_HOST} !^(www.|pacific.)?sky.0t0.jp$ [NC,OR]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ %{REQUEST_URI} [R=301,L]
結果
dry-run で無事に通過!
実際の更新でもエラー無し
sendmail や Web サーバーも証明書更新後に自動リロードする仕組みなので安心
そして気づいたのは、preferred-challenges = http は実は不要だったこと。
webroot で .well-known/acme-challenge/ が適切に処理されるなら、certbot は自動的に http-01 を選んでくれるのです。
まとめ
・443 を塞いでも問題なし
・80 を世界に開ける代わりに acme-challenge だけ例外にすればOK
・certbot は自動で http-01 を使ってくれるので、余計な設定は不要
結果的に、
「海外ストーカー対策は維持しつつ、証明書更新も安定」
という理想の形になりました(笑)