2026年5月20日
2026年5月20日
WordPressのCloudflare WAFを設定する方法
はじめに
Cloudflare WAFはWordPressサイトへのリクエストをエッジサーバーでフィルタリングし、攻撃がオリジンサーバーに到達する前にブロックします。無料プランでも基本的なWAF機能が利用でき、有料プランではWordPress専用のマネージドルールセットを利用できます。
症状・原因
- サーバー側でのWAF設定(ModSecurity等)が難しい共有ホスティングを使っている
- Cloudflareを既に導入しているがWAFの設定ができていない
- 特定の攻撃パターン(wp-login.phpブルートフォース等)をサーバーの手前でブロックしたい
- IPベースでなくリクエスト内容でフィルタリングしたい
解決手順
ステップ1:Cloudflare の現在のセキュリティ設定を確認する
# Cloudflare API でゾーン情報を確認
# ZONE_ID と API_TOKEN は Cloudflare ダッシュボードで取得
ZONE_ID="your_zone_id"
API_TOKEN="your_api_token"
# 現在のWAF設定を確認
curl -s -X GET \
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/firewall/waf/packages" \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" | python3 -m json.tool
# セキュリティレベルを確認
curl -s -X GET \
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/settings/security_level" \
-H "Authorization: Bearer ${API_TOKEN}" | python3 -m json.tool
ステップ2:Cloudflare カスタムWAFルールを設定する
# Cloudflare ダッシュボード → Security → WAF → Custom rules で設定
# ① wp-login.php へのブルートフォースを制限(GUIで設定)
# ルール名: Protect WordPress Login
# 条件: URI Path equals "/wp-login.php"
# AND Request Method equals "POST"
# アクション: Managed Challenge(人間確認)
# 注意: 自分のIPはBypassルールで除外する
# ② xmlrpc.php を完全ブロック
# ルール名: Block xmlrpc.php
# 条件: URI Path equals "/xmlrpc.php"
# アクション: Block
# ③ 管理画面を自社IPのみ許可
# ルール名: Protect wp-admin
# 条件: URI Path contains "/wp-admin"
# AND NOT IP Source Address in {your.ip.address}
# アクション: Block
# Cloudflare API でカスタムルールを作成
curl -s -X POST \
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/firewall/rules" \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"filter": {
"expression": "(http.request.uri.path eq \"/xmlrpc.php\")",
"paused": false
},
"action": "block",
"description": "Block xmlrpc.php"
}'
ステップ3:WordPress マネージドルールセットを有効化する(有料プラン)
# Cloudflare Pro以上: WordPress 専用マネージドルールセットを有効化
# ダッシュボード → Security → WAF → Managed rules
# → Cloudflare Managed Ruleset を ON
# → Cloudflare WordPress Ruleset を ON
# API で WordPress マネージドルールセットを有効化
curl -s -X PUT \
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/firewall/waf/packages/PACKAGE_ID/groups/GROUP_ID" \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"mode": "on"}'
# マネージドルールが含む保護:
# - WordPress コアの既知の脆弱性
# - WooCommerce の脆弱性
# - 人気プラグインの CVE
# - ブルートフォース対策
ステップ4:レート制限ルールを設定する
# Cloudflare ダッシュボード → Security → WAF → Rate limiting rules
# ① wp-login.php: 1分間に5回超えたらチャレンジ
# ルール名: Login Rate Limit
# 条件: URI Path equals "/wp-login.php"
# 特性: IP (クライアントIPでカウント)
# 閾値: 5リクエスト / 60秒
# アクション: Managed Challenge
# ② wp-json API: DDoS対策
# ルール名: REST API Rate Limit
# 条件: URI Path starts with "/wp-json"
# 閾値: 100リクエスト / 60秒
# アクション: Block
# ③ サイト全体: 大量リクエストをブロック
# 閾値: 1000リクエスト / 60秒
# アクション: Block
# API でレート制限を設定
curl -s -X POST \
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/rate_limits" \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"match": {
"request": {"url_pattern": "*/wp-login.php*", "methods": ["POST"]}
},
"threshold": 5,
"period": 60,
"action": {"mode": "challenge", "timeout": 600}
}'
ステップ5:WordPress と Cloudflare を統合する
// functions.php: Cloudflare の本物のIPを取得
add_action('init', function(): void {
// Cloudflare から送られる本物のクライアントIP
if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
}
}, 1);
// Cloudflare の IP レンジかどうかを確認
function is_cloudflare_ip(string $ip): bool {
$cloudflare_ranges = [
'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',
];
foreach ($cloudflare_ranges as $range) {
[$subnet, $bits] = explode('/', $range);
$ip_long = ip2long($ip);
$subnet_long = ip2long($subnet);
$mask = -1 << (32 - (int)$bits);
if (($ip_long & $mask) === ($subnet_long & $mask)) {
return true;
}
}
return false;
}
# Cloudflare が有効かどうかを確認
curl -sI https://example.com/ | grep -i "cf-ray\|server: cloudflare"
# CF-Ray ヘッダーが返れば Cloudflare 経由
# ファイアウォールのイベントログを確認
# Cloudflare ダッシュボード → Security → Events
# ブロック・チャレンジされたリクエストを確認
注意事項
- Cloudflareの無料プランではカスタムWAFルールが5つまでです。最も重要な
xmlrpc.phpのブロックとwp-login.phpのレート制限を優先してください - 管理画面(wp-admin)をIPでブロックする場合、外出先から管理できなくなります。完全IPブロックより「Managed Challenge」(CAPTCHA)アクションの方が運用しやすい場合があります
- Cloudflareの「I'm Under Attack!」モードは全訪問者にJavaScriptチャレンジを表示するため、攻撃を受けていない通常時は使用しないでください。レート制限とWAFルールで段階的に対応してください
まとめ
Cloudflare WAFの設定は①CF-Rayヘッダー確認でCloudflare経由を確認、②カスタムルールでxmlrpc.phpをBlock・wp-login.phpにManaged Challenge、③WordPress管理画面を自社IPのみ許可、④レート制限でwp-login.phpは5回/分・wp-jsonは100回/分、⑤HTTP_CF_CONNECTING_IPでPHP側に本物のクライアントIPを渡します。