2026年9月22日

2026年9月22日

WordPressのログイン試行回数を制限する方法・ブルートフォース攻撃対策

はじめに

「WordPressのログインページに大量のアクセスがある」「見覚えのないIPからのログイン試行が多い」——ブルートフォース攻撃(パスワード総当たり攻撃)はWordPressへの最も一般的な攻撃手法のひとつです。ログイン試行回数を制限して防御しましょう。

症状・原因

WordPressはデフォルトでログイン試行回数に制限がないため、攻撃者は/wp-login.phpに対して自動化されたツールで何千回もパスワードを試し続けることができます。適切な制限設定がなければ、弱いパスワードのアカウントが乗っ取られるリスクがあります。

解決手順

ステップ1:現在のログイン失敗状況を確認する

# Nginxのアクセスログでwp-login.phpへのアクセスを確認
grep "POST /wp-login.php" /var/log/nginx/access.log \
  | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

# Apacheの場合
grep "POST.*wp-login.php" /var/log/apache2/access.log \
  | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

# WordPressのデバッグログを確認
wp eval '
$entries = file("/var/log/wordpress/debug.log");
$fails = array_filter($entries, fn($l) => strpos($l, "incorrect password") !== false);
echo count($fails) . " failed logins found\n";
'

ステップ2:Limit Login Attemptsプラグインを設定する

# Limit Login Attempts Reloadedをインストール
wp plugin install limit-login-attempts-reloaded --activate

# 設定を確認
wp option get limit_login_options
管理画面 → 設定 → Limit Login Attempts
→ ログイン失敗の許容回数: 3回
→ ロックアウト時間: 20分
→ 連続ロックアウト後の待機時間: 24時間
→ IPアドレスをログに記録: ON
→ メール通知: ON(4回ロックアウトごとに通知)

ステップ3:functions.phpで独自のログイン制限を実装する

// ログイン失敗回数をトランジェントで管理
add_filter( 'wp_authenticate_user', function( $user, $password ) {
    if ( is_wp_error( $user ) ) return $user;

    $ip      = $_SERVER['REMOTE_ADDR'];
    $key     = 'login_fails_' . md5( $ip );
    $fails   = (int) get_transient( $key );
    $limit   = 5; // 5回まで許可

    if ( $fails >= $limit ) {
        return new WP_Error(
            'too_many_attempts',
            '試行回数が多すぎます。20分後に再試行してください。'
        );
    }

    return $user;
}, 10, 2 );

// ログイン失敗時にカウントアップ
add_action( 'wp_login_failed', function( $username ) {
    $ip  = $_SERVER['REMOTE_ADDR'];
    $key = 'login_fails_' . md5( $ip );
    $n   = (int) get_transient( $key ) + 1;
    set_transient( $key, $n, 20 * MINUTE_IN_SECONDS ); // 20分間
} );

// ログイン成功時にリセット
add_action( 'wp_login', function() {
    $ip  = $_SERVER['REMOTE_ADDR'];
    $key = 'login_fails_' . md5( $ip );
    delete_transient( $key );
} );

ステップ4:NginxでIPレベルの制限を設定する

# /etc/nginx/conf.d/wp-login-limit.conf
limit_req_zone $binary_remote_addr zone=wp_login:10m rate=1r/s;

server {
    # ...

    location = /wp-login.php {
        limit_req zone=wp_login burst=3 nodelay;
        limit_req_status 429;

        # 特定IPのみ許可する場合
        # allow 203.0.113.1;  # 自社IPを許可
        # deny all;

        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}
# Nginx設定を再読み込み
sudo nginx -t && sudo systemctl reload nginx

ステップ5:攻撃IPをfail2banで自動ブロックする

# fail2banのWordPress用フィルターを作成
sudo cat > /etc/fail2ban/filter.d/wordpress.conf << 'EOF'
[Definition]
failregex = ^<HOST> .* "POST .*wp-login.php
ignoreregex =
EOF

# jail設定に追加
sudo cat >> /etc/fail2ban/jail.local << 'EOF'
[wordpress]
enabled  = true
filter   = wordpress
logpath  = /var/log/nginx/access.log
maxretry = 5
bantime  = 3600
findtime = 600
EOF

sudo systemctl restart fail2ban

# ブロック中のIPを確認
sudo fail2ban-client status wordpress

注意事項

  • ロックアウト設定が厳しすぎると、自分自身がログインできなくなる場合があります。管理者IPを許可リストに追加しておくことを推奨します。
  • CloudflareなどのCDNを経由している場合、$_SERVER['REMOTE_ADDR']には実際の攻撃者IPではなくCDNのIPが入ります。HTTP_CF_CONNECTING_IPなどのヘッダーを使用してください。
  • ログイン試行制限と同時に、強力なパスワードポリシーと二要素認証(2FA)の導入も強くお勧めします。

まとめ

ログイン試行制限は「現状確認→プラグイン設定→独自実装→Nginx制限→fail2ban自動ブロック」の多層防御で実装します。WP-CLIで定期的にログを確認し、新しい攻撃パターンに対応しましょう。関連記事:WordPressのログインURLを変更する方法、WordPressのXMLRPCを無効化する方法。

お気軽にご相談ください

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