Certbot の HTTP-01 認証では、認証サーバーが http://<ドメイン>/.well-known/acme-challenge/<トークン> へアクセスしてドメインの所有権を確認します。
- Certbot の動作:
-w /path/to/webrootで指定された場所に一時検証ファイルを作成 - Web サーバーの動作: ポート 80 に来たリクエストをバーチャルホストの
DocumentRoot内から探索
作成時・更新時に指定した Webroot と、実際にポート 80 を受け持つ DocumentRoot のパスが一致していない場合、Let’s Encrypt 側からファイルが見つからず 404 Not Found または 403 Forbidden で更新が失敗します。
1.現在のバーチャルホストのルーティングを確認する
Apache がポート 80 へのアクセスをどの設定ファイル・どのドキュメントルートで処理しているかを可視化します。
sudo apache2ctl -S
port 80 namevhost の一覧を確認し、該当ドメインのリクエストを処理しているファイル(またはデフォルトの受け皿)を特定します。
2.ポート 80 の受け皿を /var/www/html に一本化する
個別サイトの設定ファイルごとに異なるパスを設定すると管理ミスの原因になります。個別設定(app.conf など)から <VirtualHost *:80> ブロックを削除し、デフォルト設定ファイルで全ドメインの HTTP アクセスを一括処理します。
/etc/apache2/sites-available/000-default.conf を編集します。
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
<Directory /var/www/html>
Options None
AllowOverride None
Require all granted
</Directory>
RewriteEngine On
# Let's Encrypt の認証ファイルへのアクセスはそのまま通す
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
# それ以外の通常アクセスはすべて HTTPS へリダイレクト
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>
3.個別設定ファイル(443番のみ)を整理する
各サービスの個別設定(例: /etc/apache2/sites-enabled/app.conf)は、HTTPS(ポート 443)の設定のみを記述する構成に統一します。
<VirtualHost *:443>
ServerName app.work
DocumentRoot /home/app/web/public
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/app.work/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/app.work/privkey.pem
<Directory /home/app/web/public>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
4.共通 Webroot ディレクトリの権限を整備する
Certbot がファイルを配置し、Apache が外部へ配信できるようディレクトリとパーミッションを整えます。
sudo mkdir -p /var/www/html/.well-known/acme-challenge
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html
5.Apache をリロードして設定を反映する
構文エラーがないことを確認した上で、Apache に設定を再読み込みさせます。
sudo apache2ctl configtest
sudo systemctl reload apache2
6.共通 Webroot を指定してドライランを実行する
Certbot の更新設定を共通ディレクトリ(/var/www/html)で上書き検証します。
sudo certbot certonly --webroot -w /var/www/html -d app.work --dry-run
The dry run was successful と表示されれば、以後の自動更新(certbot.timer / certbot renew)でも同一の共通パスが参照され、パス不一致によるエラーが恒久的に防止されます。

コメント