2026年5月20日

2026年5月20日

WordPressのブルートフォース攻撃対策の完全ガイド

はじめに

ブルートフォース攻撃とは、パスワードを自動的に総当たりで試し続ける攻撃です。WordPressのデフォルト設定ではログイン試行回数に制限がないため、対策なしではいつか突破される可能性があります。複数の防御層を組み合わせることで強固に防御できます。

症状・原因

  • サーバーログにwp-login.phpへの大量アクセスが記録されている
  • Wordfenceから「ブルートフォース攻撃を検出しました」という通知が届く
  • 管理画面へのログインが遅くなった(攻撃によるサーバー負荷)
  • 不明なIPアドレスからのログイン失敗メールが大量に届く

解決手順

ステップ1:攻撃の現状を確認する

# wp-login.php への POST リクエスト数を確認
grep "POST /wp-login.php" /var/log/apache2/access.log | \
    awk '{print $1}' | sort | uniq -c | sort -rn | head -20

# 直近1時間の攻撃元IPを特定
grep "POST /wp-login.php" /var/log/apache2/access.log | \
    awk -v date="$(date -d '1 hour ago' '+%d/%b/%Y:%H')" \
    '$0 ~ date {print $1}' | sort | uniq -c | sort -rn | head -10

# WordPress のログイン失敗を確認
wp db query "
SELECT meta_value as ip, COUNT(*) as attempts
FROM wp_usermeta
WHERE meta_key LIKE '%login_attempts%'
GROUP BY meta_value
ORDER BY attempts DESC
LIMIT 20" 2>/dev/null || echo "ログイン試行プラグインが必要です"

ステップ2:ログイン試行回数を制限する(プラグイン不要)

// functions.php: ログイン失敗をカウントしてIPをブロック
add_filter('authenticate', function($user, string $username, string $password) {
    if (empty($username) || empty($password)) return $user;

    $ip = $_SERVER['REMOTE_ADDR'] ?? '';
    $transient_key = 'login_attempts_' . md5($ip);
    $attempts = (int) get_transient($transient_key);

    // 5回失敗したら15分ブロック
    if ($attempts >= 5) {
        return new WP_Error(
            'too_many_attempts',
            sprintf(
                'ログイン試行回数が上限に達しました。%d分後に再試行してください。',
                15
            )
        );
    }

    return $user;
}, 30, 3);

// ログイン失敗時にカウントアップ
add_action('wp_login_failed', function(string $username): void {
    $ip = $_SERVER['REMOTE_ADDR'] ?? '';
    $transient_key = 'login_attempts_' . md5($ip);
    $attempts = (int) get_transient($transient_key);
    set_transient($transient_key, $attempts + 1, 15 * MINUTE_IN_SECONDS);
});

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

ステップ3:wp-login.phpへのアクセスを制限する

# .htaccess: 特定IPのみwp-login.phpへのアクセスを許可
<Files wp-login.php>
    Order Deny,Allow
    Deny from all
    # 自分のIPアドレスのみ許可
    Allow from 203.0.113.1
    Allow from 198.51.100.0/24
</Files>
# .htaccess: ログイン試行を多く行うIPをブロック
# (Fail2banと組み合わせて使用)
<Files wp-login.php>
    # Basic認証を追加してWAFの前に止める
    AuthType Basic
    AuthName "Restricted"
    AuthUserFile /etc/apache2/.htpasswd
    Require valid-user
</Files>
# .htpasswd ファイルを作成
sudo htpasswd -c /etc/apache2/.htpasswd wp_admin
# パスワードを入力

# WordPress の管理画面でBasic認証を無視させる設定
# wp-config.php に追加:
# define('WPLOGIN_BASIC_AUTH', true);
# Nginx: wp-login.php のアクセス制限
location = /wp-login.php {
    # レートリミット(1秒に1リクエスト、バースト3まで許可)
    limit_req zone=one burst=3 nodelay;

    # IPによるアクセス制限
    allow 203.0.113.1;
    deny all;

    fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

# Nginx.conf の http ブロックに追加
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

ステップ4:二段階認証(2FA)を導入する

# Two Factor プラグインをインストール
wp plugin install two-factor --activate

# または WP 2FA
wp plugin install wp-2fa --activate
// functions.php: 管理者のみ2FAを必須にする
add_action('wp_login', function(string $user_login, WP_User $user): void {
    if (!in_array('administrator', $user->roles, true)) return;

    // Two Factor プラグインが有効かつ2FA未設定の場合
    if (class_exists('Two_Factor_Core')
        && !Two_Factor_Core::is_user_using_two_factor($user->ID)) {
        // 2FA設定ページにリダイレクト
        wp_redirect(admin_url('profile.php#two-factor-options'));
        exit;
    }
}, 10, 2);

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

# Fail2ban をインストール
sudo apt install -y fail2ban

# WordPress ログイン失敗を検知するフィルターを作成
cat > /etc/fail2ban/filter.d/wordpress.conf << 'EOF'
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
ignoreregex =
EOF

# Fail2ban の jail 設定
cat >> /etc/fail2ban/jail.local << 'EOF'
[wordpress]
enabled = true
filter = wordpress
logpath = /var/log/apache2/access.log
maxretry = 5
findtime = 300
bantime = 3600
EOF

# Fail2ban を再起動
sudo systemctl restart fail2ban

# ブロック状態を確認
sudo fail2ban-client status wordpress

注意事項

  • wp-login.phpのIPアドレス制限は、動的IPアドレスを使用している場合に自分自身もロックアウトされる可能性があります。設定前に必ずバックアップの管理者アクセス方法を確保してください
  • ログイン試行制限はWordPressのトランジェントAPIを使用するため、キャッシュプラグインをフラッシュするとロックが解除されます。本格的な対策にはFail2banやサーバーレベルの制限を推奨します
  • Cloudflareを使用している場合、REMOTE_ADDRにはCloudflareのIPが入ります。HTTP_CF_CONNECTING_IPを使用してください

まとめ

ブルートフォース対策は①grep "POST /wp-login.php"で攻撃実態を確認、②authenticateフィルターとwp_login_failedアクションでIP単位のログイン試行回数を制限、③.htaccessでwp-login.phpへのアクセスをIP制限またはBasic認証で保護、④two-factorプラグインで管理者に2FAを必須化、⑤Fail2banで繰り返し失敗するIPを自動バンする、の5層防御が効果的です。

お気軽にご相談ください

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