2026年5月20日

2026年5月20日

WordPressのDDoS攻撃対策をする方法(Cloudflare活用)

はじめに

DDoS(分散型サービス妨害)攻撃は、大量のリクエストを送りつけてサーバーをダウンさせる攻撃です。WordPressサイトはボットによる自動攻撃のターゲットになりやすく、Cloudflare等のCDN・WAFと組み合わせた多層防御が有効です。

症状・原因

  • サイトが突然アクセス不能になり、サーバーのCPU・メモリが100%になっている
  • アクセスログに同一IPや特定のUser-Agentからの大量リクエストが記録されている
  • wp-login.phpxmlrpc.phpへの大量アクセスでサーバーが応答不能になった
  • 通常の数十〜数百倍のトラフィックが発生している

解決手順

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

# 現在のアクセス状況を確認
# Apache: リアルタイムのリクエスト数
tail -f /var/log/apache2/access.log | pv -l -i 1 > /dev/null

# アクセス元IPのトップ20を確認
awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -rn | head -20

# 特定のエンドポイントへのアクセスを確認
grep "wp-login.php\|xmlrpc.php\|wp-json" /var/log/apache2/access.log | \
    awk '{print $1}' | sort | uniq -c | sort -rn | head -20

# 現在の接続数を確認
ss -s
netstat -an | grep ESTABLISHED | wc -l

# Nginx: アクティブな接続数
nginx -V 2>&1 | grep -o 'worker_connections=[0-9]*'

ステップ2:Cloudflareを設定してDDoSを防ぐ

# Cloudflare の無料プランでもDDoS対策が可能
# ① ドメインをCloudflareに登録してNSを変更

# ② Cloudflare ダッシュボードで設定
# Security → DDoS → HTTP DDoS attack protection を「High」に設定
# Security → Settings → Security Level を「High」に設定
# Under Attack モード(攻撃中はONにする): Security Level → "I'm Under Attack!"

# ③ レート制限ルール(Cloudflare Free プランでも設定可能)
# Security → WAF → Rate limiting rules
# パス: /wp-login.php
# リクエスト: 5回/分 超過でチャレンジ
# パス: /xmlrpc.php
# リクエスト: 1回/分 超過でブロック

# ④ WordPress 専用 WAF ルール(Managed Rules)
# Security → WAF → Managed rules
# Cloudflare WordPress Ruleset を有効化
// functions.php: Cloudflare の本物のIPを取得するための設定
// (Cloudflareを通すと $SERVER['REMOTE_ADDR']がCloudflareのIPになるため)

add_action('init', function(): void {
    // Cloudflare の IP アドレスを信頼
    $cloudflare_ips = [
        '103.21.244.0/22', '103.22.200.0/22', '103.31.4.0/22',
        '104.16.0.0/13', '104.24.0.0/14', '108.162.192.0/18',
        '131.0.72.0/22', '141.101.64.0/18', '162.158.0.0/15',
        '172.64.0.0/13', '173.245.48.0/20', '188.114.96.0/20',
        '190.93.240.0/20', '197.234.240.0/22', '198.41.128.0/17',
    ];

    if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
        $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
    }
});

ステップ3:サーバー側でレート制限を設定する

# .htaccess: wp-login.php へのアクセスをレート制限
# mod_ratelimit または mod_evasive が必要

# ① wp-login.php と xmlrpc.php への特定IPからの制限
<FilesMatch "^(wp-login\.php|xmlrpc\.php)$">
    Order Deny,Allow
    Deny from all
    # 許可するIPを追加
    Allow from 203.0.113.1
    Allow from 198.51.100.0/24
</FilesMatch>
# Nginx: レート制限を設定
# /etc/nginx/nginx.conf の http {} ブロックに追加

# リクエストゾーンを定義
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
limit_req_zone $binary_remote_addr zone=general:10m rate=30r/s;

server {
    # wp-login.php: 1分間に5リクエストまで
    location = /wp-login.php {
        limit_req zone=login burst=2 nodelay;
        limit_req_status 429;
        # ... PHP処理 ...
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    # xmlrpc.php: 完全にブロック
    location = /xmlrpc.php {
        deny all;
        access_log off;
    }

    # 全体: 秒間30リクエストまで
    location / {
        limit_req zone=general burst=60 nodelay;
    }
}

ステップ4:Fail2ban でボットIPを自動BANする

# Fail2ban のインストールと設定
sudo apt install -y fail2ban

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

# jail.local に WordPress ルールを追加
cat >> /etc/fail2ban/jail.local << 'EOF'
[wordpress]
enabled  = true
filter   = wordpress
logpath  = /var/log/nginx/access.log
maxretry = 10
findtime = 60
bantime  = 3600
action   = iptables-multiport[name=wordpress, port="http,https"]
EOF

sudo systemctl restart fail2ban

# BAN されているIPを確認
sudo fail2ban-client status wordpress

ステップ5:WordPress 側でボットリクエストを軽量化する

// functions.php: DDoS時のWordPress負荷を軽減

// ① ハートビートAPIを制限(管理画面の自動保存頻度を下げる)
add_filter('heartbeat_settings', function(array $settings): array {
    $settings['interval'] = 60; // デフォルト15秒 → 60秒に
    return $settings;
});

// ② フロントエンドでハートビートを無効化
add_action('init', function(): void {
    if (!is_admin()) {
        wp_deregister_script('heartbeat');
    }
});

// ③ 不要なリクエストをブロック(User-Agentフィルタリング)
add_action('init', function(): void {
    $ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
    $blocked_uas = ['python-requests', 'Go-http-client', 'libwww-perl', 'curl/'];

    foreach ($blocked_uas as $blocked) {
        if (str_contains($ua, $blocked)) {
            http_response_code(403);
            exit;
        }
    }
}, 1);

注意事項

  • 攻撃中に「I'm Under Attack!」モードを有効化すると全訪問者にJavaScriptチャレンジが表示されます。攻撃が収まったら通常モードに戻してください
  • Nginx のlimit_req_zoneburst値を小さくしすぎると正常なユーザーもブロックされます。まずはアクセスログでトラフィックパターンを分析してから適切な値を設定してください
  • User-Agentでのブロックは回避が容易です。正当なSEOクローラー(Googlebot等)を誤ってブロックしないよう、ブロック対象は明らかに悪意のあるUAのみに限定してください

まとめ

DDoS対策は①アクセスログで攻撃元IPとターゲットURLを特定、②CloudflareをNS変更で導入しDDoS保護を「High」に設定、③Nginxのlimit_req_zonewp-login.phpを1分5リクエスト制限、④Fail2banでwp-login.phpへの大量アクセスIPを自動BAN(3600秒)、⑤WP Heartbeatを制限してWordPress自体の負荷を軽減します。

お気軽にご相談ください

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