2026年5月20日
2026年5月20日
wp-login.phpへのアクセスを制限する方法:IP制限・Basic認証・Nginx・試行回数制限
WordPress のログイン画面 wp-login.php は、どのサイトでも同じ場所にあるため、ボットによるパスワードの総当たりの標的になります。アクセスログに、知らない IP アドレスからの POST /wp-login.php が大量に並んでいることも珍しくありません。
この記事では、wp-login.php へのアクセスを制限する方法を、効果と手間の違いが分かるように並べて説明します。
対策の比較
| 方法 | 向いている場合 | 効果 |
|---|---|---|
| IPアドレスで制限 | 管理者の接続元IPが決まっている | 許可したIP以外はログイン画面に届かない |
| Basic認証を追加 | 接続元IPが変わる | WordPress のパスワードの前にもう1つ認証が入る |
| ログインURLを変更(プラグイン) | サーバーの設定を触れない | 既定のURLを狙うボットを避けられる |
| ログイン失敗回数の制限 | どの環境でも | 総当たりの速度を落とせる |
IP制限と Basic認証はサーバーで止めるため、WordPress(PHP)が動く前に遮断でき、サーバーの負荷も減ります。
設定する前の注意
- 作業前に
.htaccessや Nginx の設定ファイルをバックアップしてください。記述を誤ると、サイト全体が「500 Internal Server Error」になることがあります。 - IP制限では、自分の今の接続元IPを確認してから設定します。自宅の回線などで IP が変わると、自分も締め出されます。締め出されたら、FTP やサーバーのファイルマネージャーで設定を元に戻します。
- Cloudflare などのCDN・プロキシを経由している場合、サーバーから見える接続元はプロキシの IP になり、IP制限が意図どおりに動きません。この場合は Cloudflareでwp-login.phpへのアクセスを制限する方法 を参照してください。
- パスワード保護した投稿のパスワード入力も
wp-login.php?action=postpassに送られます。IP制限や Basic認証をかけると、一般の訪問者はパスワード保護ページを開けなくなります。
方法1:.htaccessでIPアドレスを制限する(Apache 2.4)
WordPress のフォルダー(wp-login.php と同じ場所)にある .htaccess に追記します。WordPress が書き込む # BEGIN WordPress から # END WordPress の間ではなく、その外(上)に書きます。
# wp-login.php へのアクセスを指定したIPアドレスだけに許可する
<Files "wp-login.php">
Require ip 203.0.113.1 198.51.100.0/24
</Files>
203.0.113.1は1つのIPアドレス、198.51.100.0/24はオフィスなどのアドレス範囲の例です。自分の環境の値に置き換えます。- Apache の設定では、行の途中に
#でコメントを書くことはできません。コメントは独立した行に書きます。 - 古い記事でよく見る
Order Deny,Allow/Deny from all/Allow fromは Apache 2.2 の書き方です。Apache 2.4 ではmod_access_compatが無効だとエラーになるため、Requireを使います。
設定後、許可していない回線(スマートフォンのモバイル回線など)から https://example.com/wp-login.php を開き、「403 Forbidden」になることを確認します。
方法2:Basic認証をかける(Apache)
接続元IPが決まらない場合は、wp-login.php に Basic認証をかけます。ブラウザーのIDとパスワードの入力を通らないと、ログイン画面が表示されません。
まず、パスワードファイルを作ります。公開ディレクトリ(ブラウザーから見える場所)の外に置きます。
# Ubuntu / Debian では apache2-utils パッケージに含まれる
htpasswd -c /home/user/.htpasswd admin-user
-c はファイルを新しく作るオプションです。2人目以降を追加するときは -c を付けずに実行します(付けると既存の内容が消えます)。
.htaccess に次を追記します。AuthUserFile はサーバー上のフルパス(/ から始まるパス)で書きます。
<Files "wp-login.php">
AuthType Basic
AuthName "Restricted"
AuthUserFile /home/user/.htpasswd
Require valid-user
</Files>
Basic認証のIDとパスワードは暗号化されずに送られるため、サイトが HTTPS になっていることが前提です。レンタルサーバーでは、コントロールパネルからアクセス制限(Basic認証)を設定できる場合もあります。詳しくは .htaccessでパスワード保護をかける方法 を参照してください。
方法3:Nginxで制限する
Nginx では、location ごとに allow と deny を書きます。注意点は、制限用の location の中にも PHP を実行する設定を書くことです。Nginx は1つのリクエストに1つの location しか使わないため、location = /wp-login.php に allow / deny だけを書くと、PHP が実行されず、ファイルがダウンロードされたり表示されなかったりします。
PHP の設定は、サーバーの既存の location ~ \.php$ { ... } の中身と同じものを書きます。以下は Ubuntu 24.04(PHP 8.3、PHP-FPM)の例です。
# server { ... } の中に書く
location = /wp-login.php {
allow 203.0.113.1;
allow 198.51.100.0/24;
deny all;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
/wp-admin/ も制限する場合は、^~ を付けた location の中に PHP の設定を入れ子にします。^~ が無いと、/wp-admin/ の中の PHP ファイルは既存の location ~ \.php$ のほうで処理され、制限がかかりません。
location ^~ /wp-admin/ {
allow 203.0.113.1;
deny all;
# フロント側の機能が使う admin-ajax.php は誰でも使えるようにする
location = /wp-admin/admin-ajax.php {
allow all;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
}
admin-ajax.php は、ログインしていない訪問者向けの機能(フォームの送信や「もっと見る」の読み込みなど)でもテーマやプラグインが使うため、制限から外します。同じ理由で、フロントから admin-post.php を使うプラグインがある場合は、そちらも除外が必要です。
設定を書いたら、文法を確認してから反映します。
sudo nginx -t
sudo systemctl reload nginx
Basic認証を使う場合は NginxでBasic認証を設定する方法 を参照してください。
方法4:ログインURLを変更する(WPS Hide Login)
サーバーの設定を変えられない場合は、ログイン画面のURLを変えるプラグインが使えます。代表的なものが「WPS Hide Login」です(2026年11月時点で wordpress.org の公式ディレクトリに公開されています)。
- 「プラグイン」→「新規追加」で「WPS Hide Login」を検索してインストールし、有効化する
- 「設定」→「WPS Hide Login」で、新しいログインURL(例:
my-login)を入力して保存する - ログアウトし、
https://example.com/my-loginでログインできることを確認する
変更後は、ログインしていない状態で wp-login.php や /wp-admin/ を開いてもログイン画面は表示されません。
- 新しいURLは控えておいてください。忘れた場合は、データベースの
wp_optionsテーブルのwhl_pageの値で確認するか、FTP でwp-content/plugins/wps-hide-loginフォルダーを削除すると元のwp-login.phpでログインできます(プラグイン公式ページの案内)。 - ページキャッシュのプラグインを使っている場合は、新しいログインURLをキャッシュの対象外にします。
- URLを隠すだけなので、ボットのアクセスがあれば WordPress(PHP)は動きます。サーバーの負荷を減らしたい場合は、方法1〜3のほうが効果があります。
方法5:ログイン失敗回数を制限する(コード)
一定回数ログインに失敗した IP アドレスからのログインを、しばらく受け付けないようにします。次のコードは「15分以内に5回失敗したら、15分間ログインを止める」例です。
wp-content/mu-plugins/login-limit.php というファイルを作って保存すると、テーマを変えても動き続けます(mu-plugins フォルダーが無ければ作ります)。
<?php
/**
* Plugin Name: Login attempt limit
*/
function wpdr_login_limit_key() {
$ip = isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : '';
return 'wpdr_login_fail_' . md5( $ip );
}
// ログインに失敗するたびに回数を数える(15分で消える)
add_action( 'wp_login_failed', function () {
$key = wpdr_login_limit_key();
$count = (int) get_transient( $key );
set_transient( $key, $count + 1, 15 * MINUTE_IN_SECONDS );
} );
// 失敗が5回以上ならログインを受け付けない
add_filter( 'authenticate', function ( $user ) {
if ( (int) get_transient( wpdr_login_limit_key() ) >= 5 ) {
return new WP_Error(
'too_many_attempts',
'ログインの失敗が続いたため、しばらく時間をおいてから再度お試しください。'
);
}
return $user;
}, 99 );
wp_login_failedはログイン失敗時に WordPress が実行するアクションです。止めている間の試行も失敗として数えるため、試行を続ける接続元はその間ずっと止まります。- XML-RPC(
xmlrpc.php)経由のログインも同じauthenticateフィルターを通るため、この制限がかかります。 - CDN やリバースプロキシの後ろでは
REMOTE_ADDRがプロキシの IP になり、全員がまとめて止まります。その環境では使わないでください。
プラグインで行う方法や詳しい考え方は、プラグインなしでログイン試行回数を制限する方法 と ログイン試行回数の制限 を参照してください。
あわせて確認したいこと
- xmlrpc.php: XML-RPC でもログインを試せます。Jetpack や外部のブログ投稿アプリなどで使っていなければ、サーバーでアクセスを止める方法があります。
- パスワードと2段階認証: どの方法も、推測されにくいパスワードの代わりにはなりません。管理者アカウントには長いパスワードを使い、2段階認証のプラグインの導入も検討してください。
まとめ
接続元IPが決まっているなら、サーバーでのIP制限が最も手間なく効果があります。IPが決まらない場合は Basic認証を、サーバーの設定を触れない場合はログインURLの変更とログイン失敗回数の制限を組み合わせます。どの方法でも、設定後に「許可していない環境からは開けない」「自分はログインできる」の両方を確認してください。