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 の公式ディレクトリに公開されています)。

  1. 「プラグイン」→「新規追加」で「WPS Hide Login」を検索してインストールし、有効化する
  2. 「設定」→「WPS Hide Login」で、新しいログインURL(例: my-login)を入力して保存する
  3. ログアウトし、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の変更とログイン失敗回数の制限を組み合わせます。どの方法でも、設定後に「許可していない環境からは開けない」「自分はログインできる」の両方を確認してください。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲