2026年6月30日
2026年6月30日
WordPressマルチサイトのサブドメインが403を返すときのNginx設定の見直し方
サブドメイン型のマルチサイトで、メインサイトは開けるのに site1.example.com のような子サイトだけ「403 Forbidden」になる場合、多くはNginxがそのリクエストをWordPressまで届けていないことが原因です。具体的には、server_name にサブドメインが含まれていない、index や try_files の指定が足りない、ファイルの権限が合っていない、のいずれかがよく見られます。この記事では、エラーログからどれに当たるかを見分け、Nginxの設定を直す手順を説明します。
なお、Nginxの設定ファイルを編集するには、VPSや専用サーバーなど、サーバーの管理者権限が必要です。共用のレンタルサーバーでは通常Nginxの設定を直接変更できないため、サーバー会社の管理画面でワイルドカードのサブドメイン設定ができるかを確認するか、サポートに問い合わせてください(管理画面のメニュー名はサーバー会社ごとに異なります)。
まず403を返しているのが誰かを確かめる
同じ403でも、Nginx、WordPress、手前のWAFやCDNのどれが返しているかで対処が変わります。curl で応答ヘッダーと本文をまとめて見ると見分けられます。
curl -si https://site1.example.com/ | head -n 30
- 本文が「403 Forbidden」の見出しと
nginxの文字だけの簡素なページで、X-Powered-ByなどPHPを示すヘッダーが無い: Nginxが返しています(server_tokensの設定によってはバージョンも表示されます)。この記事の対象です。 - WordPressのデザインのページや、「この操作を行う権限がありません」のような文言が出る: WordPress(PHP)まで届いています。ユーザー権限やプラグインの問題です。
- CDNやWAFの名前が入った独自のエラーページ: Nginxより手前で止められています。そのサービスやサーバー会社のWAF設定を確認します。
Nginxが返している場合は、エラーログを見ながら子サイトのURLを開き直します。ログの場所は環境によりますが、/var/log/nginx/error.log が一般的です。
sudo tail -f /var/log/nginx/error.log
出てくるメッセージによって、以下の原因のどれに当たるかが分かります。
原因1: server_name にサブドメインが含まれていない
ログに directory index of "/var/www/html/" is forbidden のように、WordPressとは別のフォルダー名が出ている場合は、リクエストがWordPress用のserverブロックに届かず、既定のserverブロックで処理されています。サブドメイン型のマルチサイトでは、server_name にワイルドカードを含める必要があります。
現在どのserverブロックがどの名前を受け持っているかは、読み込まれている設定全体を表示して確認します。
sudo nginx -T | grep -n "server_name"
WordPress用のserverブロックを次のように直します。HTTPS用の443番のserverブロックにも、同じ server_name を書くことを忘れないでください。80番だけ直して、HTTPSでは既定のserverブロックに落ちている、という見落としがよくあります。HTTPSで子サイトを使うには、ワイルドカード証明書か、子サイトごとの証明書も必要です。
server {
listen 443 ssl;
server_name example.com *.example.com;
root /var/www/example.com;
index index.php;
# ssl_certificate などの設定は省略
}
DNSにワイルドカードのレコード(*.example.com)が無い場合は、403ではなく名前解決のエラーになります。403が返っているなら、DNSはサーバーまで届いています。
原因2: index と try_files の指定が足りない
ログに出ているフォルダーがWordPressのフォルダーなのに directory index of ... is forbidden が出ている場合は、index に index.php が入っていないか、try_files がWordPressに処理を渡していません。try_files $uri $uri/ =404; のままだと、フォルダーへのアクセスで表示するファイルが見つからず403になります。
WordPress.orgのNginx向けドキュメントにあるとおり、サブドメイン型のマルチサイトでは、通常のWordPressと同じく、存在しないパスを index.php に渡す設定で動作します。サブディレクトリー型のような追加の書き換えルールは不要です。
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php-fpm.sock;
}
fastcgi_pass のソケットのパスは、PHPのバージョンやディストリビューションによって異なります。PHP-FPMの設定ファイルにある listen の値と同じものを指定してください。
原因3: ファイルやフォルダーの権限が合っていない
ログに (13: Permission denied) が含まれている場合は、Nginxの実行ユーザー(www-data や nginx など)がファイルを読めていません。子サイトだけで起きるときは、子サイト用のアップロードフォルダー wp-content/uploads/sites/ 以下が、別のユーザーの権限で作られていることがあります。パスの途中のどのフォルダーで止まっているかは namei で確認できます。
namei -l /var/www/example.com/wp-content/uploads/sites/2
フォルダーは755、ファイルは644を目安にし、所有者をPHP-FPMの実行ユーザーにそろえます。SELinuxが有効なRHEL系のサーバーでは、権限が正しくてもコンテキストの違いで拒否されることがあります。ls -Z でコンテキストを確認し、配置場所に合わせて restorecon で戻すのが一般的です。
原因4: deny のルールが子サイトに当たっている
ログに access forbidden by rule が出ている場合は、設定内の deny に一致しています。メインサイト用に書いたIPアドレス制限や、wp-admin へのアクセス制限が、同じserverブロックの子サイトにも適用されているケースが典型です。sudo nginx -T の出力で deny と allow を検索し、どの location に一致しているかを確認します。制限は残したまま、許可するIPアドレスを追加するなど、目的に合う形に直します。
設定を反映する前に
設定ファイルを編集する前に、元のファイルをコピーしてバックアップを取ります。可能なら、本番と同じ構成のステージング環境で先に確認してください。編集後は、反映の前に文法チェックを行います。
sudo nginx -t
sudo systemctl reload nginx
設定に誤りがある場合、reload では新しい設定が読み込まれず古い設定のまま動き続けますが、restart では起動できずにメインサイトも含めて止まります。どちらの場合も、先に nginx -t で確認するのが安全です。syntax is ok と test is successful が出たことを確かめてから reload してください。反映後は、メインサイトと子サイトの両方をHTTPとHTTPSで開き、エラーログに新しいメッセージが出ていないかを確認します。ここでの内容は、NginxとWordPressのドキュメントをもとにしています(2026年10月現在)。
まとめ
curl -siで、403を返しているのがNginx・WordPress・WAFのどれかを最初に見分ける- エラーログの文言で原因を絞る(別フォルダーなら
server_name、Permission deniedなら権限、forbidden by ruleならdeny) - サブドメイン型では
server_name example.com *.example.com;を80番と443番の両方に書く index index.php;とtry_files $uri $uri/ /index.php?$args;があれば、追加の書き換えルールは不要- 反映前に
nginx -tで文法を確認し、共用サーバーではサーバー会社の設定や窓口を使う