2026年5月20日
2026年5月20日
WordPressのログインページ(wp-login.php)をIPアドレスで制限する方法
WordPress のログインページ(wp-login.php)は、だれでも開けるため、パスワードを総当たりで試す攻撃の的になります。決まった IP アドレスからだけ開けるようにすると、それ以外の接続元からのログイン試行を、WordPress が動く前に Web サーバーの段階で止められます。
この記事では、Apache(.htaccess)と Nginx で wp-login.php を IP アドレス制限する手順を説明します。設定を間違えると自分もログインできなくなるため、作業の前に、FTP・SFTP、SSH、レンタルサーバーのファイルマネージャーのどれかで設定ファイルを戻せることを確かめておきます。
向いている環境
- 管理画面に入る人の接続元 IP アドレスが決まっている(会社の固定 IP、VPN の出口など)
- ログインするのは運営者だけで、会員登録やコメント投稿のためのログインを外部の人に使わせていない
wp-login.php は、ログインのほか、ログアウト、パスワードの再設定、ユーザー登録、パスワード保護したページのパスワード入力にも使われます。制限すると、許可していない接続元からはこれらもできなくなります。
手順1: 自分の IP アドレスを確認する
管理画面を開くパソコンで次を実行します。ブラウザーで IP アドレスを表示するサービスを開いて確かめてもかまいません。
# IPv4 のアドレス
curl -s https://api.ipify.org
# IPv6 で接続している場合のアドレス(IPv6 が使える回線では IPv6 が返る)
curl -s https://api64.ipify.org
回線が IPv6 に対応していると、サーバーへの接続が IPv6 になることがあります。その場合は IPv6 のアドレス(またはプレフィックス)も許可します。
手順2(Apache): .htaccess で wp-login.php を制限する
WordPress のルート(wp-login.php がある場所)の .htaccess に、次を追加します。WordPress が書き換える # BEGIN WordPress 〜 # END WordPress の外(上)に書きます。
# wp-login.php を許可した IP アドレスからだけ開けるようにする(Apache 2.4)
<Files wp-login.php>
Require ip 203.0.113.10 198.51.100.0/24 2001:db8:1234::/48
</Files>
Require ipには、IP アドレスを空白区切りで並べます。198.51.100.0/24のような CIDR 表記や、IPv6 のアドレスも書けます。例の値は自分のものに置き換えます。.htaccessでは、行の途中にコメントを書けません。Require ip 203.0.113.10 # 自宅のように書くと、#以降も値として読まれ、500 エラーになります。コメントは行の先頭に#を付けて別の行に書きます。<Directory>は.htaccessの中では使えません(サーバー全体の設定ファイル用です)。書くと 500 エラーになります。Order Deny,Allow・Deny from all・Allow from …は Apache 2.2 の書き方です。Apache 2.4 では互換モジュールが有効なときだけ動き、Requireと混ぜると意図しない結果になりやすいため、新しく書くときはRequireを使います。.htaccessでRequireを使うには、サーバー側でAllowOverride AuthConfig(またはAll)が許可されている必要があります。許可されていないと 500 エラーになります。
管理画面(/wp-admin/)も制限したい場合は、wp-admin フォルダーに別の .htaccess を置きます。サイトの表側の機能が使う admin-ajax.php と admin-post.php を除外する必要があり、その書き方は「wp-adminを.htaccessでIP制限する方法」で説明しています。
手順2(Nginx): location で wp-login.php を制限する
Nginx は .htaccess を読まないため、サーバーの設定ファイル(Ubuntu なら /etc/nginx/sites-available/ の中のサイトの設定)に書きます。location = /wp-login.php は完全一致のため、ここに一致したリクエストは、PHP を処理するいつもの location ~ \.php$ には進みません。そのため、このブロックの中にも PHP を渡す設定を書きます。
location = /wp-login.php {
allow 203.0.113.10;
allow 198.51.100.0/24;
allow 2001:db8:1234::/48;
deny all;
# 既存の location ~ \.php$ と同じ PHP の設定を書く(Ubuntu の PHP 8.3 の例)
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
allowとdenyは上から順に調べられ、最初に一致した行が使われます。deny all;は最後に書きます。fastcgi_passの値(ソケットのパスや PHP のバージョン)は、同じ設定ファイルのlocation ~ \.php$に書かれているものに合わせます。PHP の設定を書き忘れると、wp-login.phpが実行されずにファイルとしてダウンロードされることがあります。
書いたら、設定の文法を確かめてから読み込み直します。
sudo nginx -t
sudo systemctl reload nginx
Nginx で Basic 認証と組み合わせる方法は「NginxでBasic認証とIPアドレス制限を組み合わせる方法」で説明しています。
手順3: 動作を確認する
許可していない接続元(スマートフォンのモバイル回線など)から開き、403 Forbidden になることを確認します。
# 許可していない接続元から実行して 403 になること
curl -I https://example.com/wp-login.php
許可した接続元のブラウザーでは、いつもどおりログイン画面が表示され、ログインできることを確認します。
xmlrpc.php も確認する
WordPress には、wp-login.php を通らずにユーザー名とパスワードを受け付ける xmlrpc.php があります。wp-login.php だけを制限しても、こちらへのパスワード試行は止まりません。
XML-RPC を使っていない場合は、次のように止めます。Jetpack や、XML-RPC で投稿する外部のアプリを使っている場合は、それらが動かなくなるため止めません。
# .htaccess(Apache 2.4)
<Files xmlrpc.php>
Require all denied
</Files>
# Nginx
location = /xmlrpc.php {
deny all;
}
Cloudflare などを通している場合
Cloudflare やロードバランサーを通すと、Web サーバーから見た接続元は中継サーバーの IP アドレスになります。このままでは、自分の IP アドレスを許可しても一致しません。中継サーバーが渡すヘッダーから、本来の接続元の IP アドレスを復元する設定が必要です。
- Apache: mod_remoteip を使い、サーバーの設定ファイルに
RemoteIPHeader CF-Connecting-IPと、RemoteIPTrustedProxyで Cloudflare の IP アドレスの範囲を書く - Nginx:
set_real_ip_fromで Cloudflare の IP アドレスの範囲を並べ、real_ip_header CF-Connecting-IP;を書く
Cloudflare の IP アドレスの範囲は Cloudflare の公式ページで公開されています。レンタルサーバーではこの設定を自分で変えられないことが多いため、Cloudflare 側のアクセス制御(WAF のカスタムルールなど)で /wp-login.php を制限する方法が現実的です。
IP アドレスが変わる回線の場合
家庭の回線やモバイル回線は、接続元の IP アドレスが変わります。変わるたびに締め出されるため、IP アドレス制限は向きません。次の方法を検討します。
- ログインページに Basic 認証をかける(IP アドレスに関係なく、ID とパスワードで二重に守る)。手順は「WordPressのBASIC認証で管理画面を二重保護する方法」
- VPN を用意し、VPN の出口の IP アドレスだけを許可する
- ログインの試行回数を制限する。手順は「WordPressのログイン試行回数を制限する方法」
- 二段階認証を入れる
締め出されたときの戻し方
IP アドレスが変わったり、設定を書き間違えたりして 403 や 500 になった場合は、次のように戻します。WordPress のパスワードを変えても解決しません(Web サーバーの段階で止まっているため)。
- Apache: FTP・SFTP かファイルマネージャーで
.htaccessを開き、追加した<Files wp-login.php>〜</Files>を削除する - Nginx: SSH でサーバーに入り、追加した
location = /wp-login.phpのブロックを削除して、sudo nginx -tのあとsudo systemctl reload nginxを実行する
ログインできたら、今の IP アドレスを確かめて許可する値を書き直し、設定を戻します。
まとめ
- Apache 2.4 では、ルートの
.htaccessに<Files wp-login.php>とRequire ipを書く(行の途中にコメントを書かない、<Directory>は使わない) - Nginx では、
location = /wp-login.phpにallow・denyと PHP の設定を書き、nginx -tで確かめてから読み込み直す xmlrpc.phpは別の入口なので、使っていなければ止める- Cloudflare などの中継を通す場合は、本来の接続元の IP アドレスを復元する設定が必要
- 締め出されたら、FTP や SSH で追加した設定を削除して戻す