2026年5月20日
2026年5月20日
WordPress の管理画面を IP アドレスで制限する方法|Apache 2.4・Nginx の設定と注意点
WordPress の管理画面(/wp-admin/)とログイン画面(/wp-login.php)は、初期状態ではだれでも開けます。管理する人の接続元が決まっているなら、Web サーバーの設定でその IP アドレスからだけ開けるようにすると、パスワードの総当たりや管理画面を狙うリクエストを WordPress に届く前に止められます。
この記事では、次の順に説明します。
- Apache 2.4 の
.htaccessで制限する - Nginx で制限する
- 制限から外すファイル(
admin-ajax.phpなど)と、外す理由 - IPv6、CDN・リバースプロキシ、固定 IP が無い場合の注意
- 動作の確認と、自分が締め出されたときの戻し方
始める前に確認すること
自分の IP アドレス: ふだん管理画面を開く回線の IP アドレスを調べます。IPv6 で接続していることもあるので、両方を確認します。
curl -4 https://ifconfig.me # IPv4 アドレス
curl -6 https://ifconfig.me # IPv6 アドレス(IPv6 が無い回線ではエラーになる)
- 固定 IP かどうか: 家庭用の回線は IP アドレスが変わることが多く、変わるたびに設定を書き換える必要があります。固定 IP が無い場合は、後述の「固定 IP が無い場合」を先に読んでください。
- 戻す手段: 設定を誤ると自分も管理画面に入れなくなります。FTP・SFTP・SSH、またはレンタルサーバーのファイルマネージャーで
.htaccessを編集できることを確かめておきます。
方法 1: Apache 2.4 の .htaccess で制限する
Apache 2.4 では、アクセス制御に Require を使います。古い記事に多い Order deny,allow / Deny from all / Allow from は Apache 2.2 の書き方で、2.4 では互換モジュール(mod_access_compat)が無いと動きません。
/wp-admin/ を制限する
wp-admin ディレクトリに .htaccess を作ります(WordPress 本体の wp-admin には通常 .htaccess はありません)。IP アドレスは自分のものに置き換えてください。
# /wp-admin/.htaccess
# 許可した IP アドレスからだけ開けるようにする(複数の Require ip はどれか 1 つに一致すれば許可)
Require ip 203.0.113.10
Require ip 198.51.100.0/24
Require ip 2001:db8:1234::/48
# サイトの公開側の機能が呼び出すファイルは、だれでも呼べるようにする
<FilesMatch "^(admin-ajax|admin-post)\.php$">
Require all granted
</FilesMatch>
admin-ajax.phpは、テーマやプラグインが公開ページから呼び出すことがあります(無限スクロール、フォーム送信、いいねボタンなど)。制限するとそれらが動かなくなるので外します。admin-post.phpは、プラグインが公開ページのフォームの送信先に使うことがあります。使っていなければ外す必要はありませんが、外しても WordPress 側でログインと権限の確認は行われます。.htaccessでRequireを使うには、サーバーの設定でAllowOverrideにAuthConfig(またはAll)が許可されている必要があります。許可されていないと.htaccessのRequireは無視されるか、500 エラーになります。
wp-login.php も制限する
/wp-admin/ だけを制限しても、ログイン画面の wp-login.php はサイトのルートにあるので、だれでも開けて総当たりもできます。管理画面を守る目的なら、wp-login.php も同じ IP アドレスに絞ります。
WordPress のルートにある .htaccess に追記します。# BEGIN WordPress と # END WordPress の間は WordPress がパーマリンクの保存時に書き換えるので、その外側(たとえば # BEGIN WordPress より上)に書きます。
# WordPress のルートの .htaccess(# BEGIN WordPress より上)
<Files "wp-login.php">
Require ip 203.0.113.10
Require ip 198.51.100.0/24
Require ip 2001:db8:1234::/48
</Files>
wp-login.php を制限すると、許可した IP アドレス以外からは次の操作もできなくなります。サイトの使い方に合わせて判断してください。
- パスワード保護した投稿のパスワード入力(送信先が
wp-login.php?action=postpass) - ユーザー登録やパスワードの再設定(会員登録を受け付けているサイト)
xmlrpc.php も外部からのログイン試行に使われます。使っていなければ止める方法を「WordPress の XML-RPC を無効にする方法」で説明しています。
方法 2: Nginx で制限する
Nginx では allow と deny を location に書きます。注意点は、location ^~ /wp-admin/ のように前方一致を優先させると、location ~ \.php$ の正規表現が使われなくなることです。そのままでは wp-admin の PHP が PHP-FPM に渡らないので、location の中に PHP の処理を入れ子で書きます。
# server ブロックの中に書く。fastcgi_pass は環境に合わせる
# 公開側の機能が呼び出すファイル(完全一致は最優先で使われる)
location = /wp-admin/admin-ajax.php {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
# 管理画面
location ^~ /wp-admin/ {
allow 203.0.113.10;
allow 198.51.100.0/24;
allow 2001:db8:1234::/48;
deny all;
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
}
# ログイン画面
location = /wp-login.php {
allow 203.0.113.10;
allow 198.51.100.0/24;
allow 2001:db8:1234::/48;
deny all;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
allowとdenyは上から順に評価され、最初に一致したものが使われます。deny all;は最後に書きます。- 入れ子の
location ~ \.php$には、外側のallow/denyが引き継がれます。 admin-post.phpも外す場合は、admin-ajax.phpと同じ形のlocation = /wp-admin/admin-post.phpを足します。fastcgi_passのソケットのパスは、すでにあるlocation ~ \.php$の設定に合わせます。Debian・Ubuntu でsnippets/fastcgi-php.confを使っている場合はそれをincludeしてもかまいません。
書き換えたら、文法を確認してから読み込み直します。
sudo nginx -t && sudo systemctl reload nginx
Nginx の基本的な設定は「Nginx で Basic 認証と IP 制限を組み合わせる方法」でも扱っています。
制限するときの注意
IPv6 で接続している場合
回線が IPv6 に対応していると、ブラウザーは IPv6 で接続することがあります。IPv4 アドレスだけを許可していると、自分が 403 になります。curl -6 で IPv6 アドレスが表示された場合は、IPv6 のアドレス(またはプロバイダーから割り当てられた範囲)も許可に加えます。
CDN やリバースプロキシを通している場合
Cloudflare などの CDN やリバースプロキシを前に置いていると、Web サーバーから見える接続元は CDN やプロキシの IP アドレスになります。そのままでは IP アドレスによる制限が働きません。先に、Apache は mod_remoteip、Nginx は real_ip_header と set_real_ip_from で、信頼するプロキシから届いた X-Forwarded-For などのヘッダーから実際の IP アドレスを復元する設定をしてから制限します。
サーバー自身からのリクエスト
WordPress はサイトヘルスの検査などで、サーバー自身に HTTP リクエスト(ループバックリクエスト)を送ります。制限を入れたあとに「ツール → サイトヘルス」でループバックリクエストのエラーが出る場合は、サーバー自身の IP アドレス(127.0.0.1 やサーバーのグローバル IP アドレス)も許可に加えます。
wp-cron.php や REST API
wp-cron.php はサイトのルートにあり、/wp-admin/ の制限の影響を受けません。ブロックエディターが使う REST API(/wp-json/)も /wp-admin/ の外なので、この制限では止まりません。
固定 IP が無い場合
IP アドレスが変わる回線では、次のどれかを検討します。
- 固定 IP の VPN を使い、管理画面は VPN に接続してから開く
- IP アドレスではなく Basic 認証で
/wp-admin/とwp-login.phpを守る(「WordPress の管理画面に Basic 認証をかける方法」) - ログインの試行回数を制限する(「ログイン試行回数を制限する方法」)
レンタルサーバーによっては、管理画面への国外からのアクセスを制限する機能をコントロールパネルで用意していることがあります。.htaccess と二重に設定すると原因の切り分けが難しくなるので、どちらで制限しているかを記録しておきます。
動作を確認する
許可した回線と、許可していない回線(スマートフォンのモバイル回線など)の両方で確かめます。
# 許可した回線から: ログインしていなければ 302(wp-login.php への転送)
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-admin/
# 許可していない回線から: 403 になれば制限できている
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-admin/
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-login.php
# admin-ajax.php: 400 なら WordPress まで届いている(action を付けていないため)。403 なら外し忘れ
curl -s -o /dev/null -w "%{http_code}\n" -X POST https://example.com/wp-admin/admin-ajax.php
公開ページの問い合わせフォームや、テーマの「もっと見る」ボタンなど、admin-ajax.php を使う機能も、許可していない回線から一度操作してみます。
アクセスログでは、ログイン画面への POST がどこから来ているかを数えられます(Apache・Nginx の標準のログ形式の場合)。
# wp-login.php への POST が多い接続元(上位 20 件)
grep 'POST /wp-login.php' /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20
# 制限で 403 にした件数
awk '$9 == 403 && $7 ~ /^\/(wp-admin|wp-login\.php)/' /var/log/nginx/access.log | wc -l
Apache の場合はログのパスを /var/log/apache2/access.log(Debian・Ubuntu)や /var/log/httpd/access_log(RHEL 系)に読み替えます。
締め出されたときの戻し方
自分の IP アドレスが変わった、IPv6 を許可し忘れた、などで管理画面が 403 になったときは、FTP・SFTP・SSH やレンタルサーバーのファイルマネージャーで次のように戻します。
- Apache:
/wp-admin/.htaccessの名前を変える(例:.htaccess.off)か、Require ipの行に新しい IP アドレスを足す。ルートの.htaccessの<Files "wp-login.php">の部分も同じように直す - Nginx: 設定ファイルの
allowに新しい IP アドレスを足し、sudo nginx -tのあとsudo systemctl reload nginx
管理画面の 403 エラーの原因の切り分けは「wp-admin で 403 エラーが出るときの対処法」も参考にしてください。
IP 制限と合わせて行うとよい設定
IP アドレスの制限は「だれが管理画面を開けるか」を絞る設定で、ログインしたあとの被害を小さくするものではありません。wp-config.php で次の定数を設定すると、管理画面からテーマやプラグインのファイルを編集する機能を止められます。
<?php
// wp-config.php の「編集が必要なのはここまでです」より上に書く
define( 'DISALLOW_FILE_EDIT', true ); // テーマ・プラグインのファイルエディターを無効にする
DISALLOW_FILE_MODS を true にすると、管理画面からのプラグインやテーマの追加・更新、WordPress 本体の更新もできなくなります。更新を WP-CLI や別の手段で行う運用でなければ、設定しないほうが更新漏れを防げます。
まとめ
- Apache 2.4 では
/wp-admin/.htaccessにRequire ipを書き、admin-ajax.php(必要ならadmin-post.php)をRequire all grantedで外します。Order/Deny/Allowは Apache 2.2 の書き方です。 - 管理画面を守るなら、ルートの
wp-login.phpも同じ IP アドレスに絞ります。 - Nginx では
location ^~ /wp-admin/の中に PHP の処理を入れ子で書かないと、PHP-FPM に渡りません。 - IPv6、CDN・リバースプロキシ、サーバー自身からのリクエストを考えて許可する IP アドレスを決め、許可していない回線から 403 になることを確かめます。
参考: Apache HTTP Server 2.4 – アクセス制御、Apache – mod_authz_core(Require)、nginx – ngx_http_access_module、WordPress – Brute Force Attacks、WordPress – Hardening WordPress