2026年8月26日

2026年8月26日

WordPressをGoogle Cloud Armorで守るセキュリティポリシー設定手順

Google Cloud上のWordPressは、外部アプリケーションロードバランサーのバックエンドサービスにCloud Armorのセキュリティポリシーを付けることで、ログイン画面への総当たり、XML-RPCの悪用、SQLインジェクションなどをサーバーに届く前に遮断できます。この記事では、WordPress向けのルール設計(許可・レート制限・WAF・既定ルールの順序)、gcloud コマンドでの作成手順、管理画面の誤検知を避ける方法、プレビューモードでの検証手順を説明します。

Cloud Armorはロードバランサーの前段で動く仕組みのため、Compute EngineのVMに直接グローバルIPでアクセスさせている構成では効果がありません。ロードバランサー経由の構成になっていることが前提です。ルールの誤りでサイト全体や管理画面が閉じてしまうこともあるため、最初は後述のプレビューモードで動作を確かめてから有効にしてください。

Cloud Armorのセキュリティポリシーの基本

セキュリティポリシーは「優先度(数値)」「条件」「アクション」を持つルールの集まりです。リクエストは優先度の数値が小さいルールから順に評価され、最初に一致したルールのアクションが適用されます。どのルールにも一致しなかった場合は、最も低い優先度(2147483647)の既定ルールが適用されます。

主なアクションは次のとおりです。

  • allow / deny:許可、または403・404・502などのステータスで拒否します。
  • throttle:一定時間内のリクエスト数を超えた分だけ拒否します。
  • rate-based-ban:しきい値を超えた送信元を一定時間まるごと遮断します。
  • redirect:reCAPTCHAによる確認ページなどへ誘導します(利用には追加の設定が必要です)。

条件には、送信元IPの範囲のほか、request.path や request.headers を使った式(CEL形式のカスタムルール言語)と、OWASP Core Rule Setをもとにした事前構成WAFルールが使えます。

WordPress向けのルール設計

WordPressでは、次の順序でルールを並べると意図が分かりやすく、誤検知が出たときも調整しやすくなります。

優先度の例 役割 内容
100 管理者の許可 社内や自宅の固定IPからの /wp-admin/・/wp-login.php・/wp-json/ を許可
200 XML-RPCの遮断 使っていなければ /xmlrpc.php を拒否
300 ログインの総当たり対策 /wp-login.php に rate-based-ban
1000番台 WAF SQLインジェクション・XSSなどの事前構成ルール
2147483647 既定 許可

管理者IPの許可ルールをWAFより前に置くのは、WordPressの管理画面ではHTMLやJavaScriptを含む本文を保存するため、WAFルールが攻撃と判定しやすいからです。固定IPがない場合は、管理画面へのアクセスだけを別の経路(Identity-Aware Proxy、VPN経由など)にする方法も検討します。

手順1:ポリシーを作成してバックエンドに付ける

以下のコマンドは例です。ポリシー名やバックエンドサービス名は自分の環境に置き換え、Cloud Shellなど gcloud が使える環境で実行してください。

# セキュリティポリシーを作成
gcloud compute security-policies create wp-policy \
    --description="WordPress security policy"

# 外部アプリケーションロードバランサーのバックエンドサービスに適用
gcloud compute backend-services update wp-backend \
    --security-policy=wp-policy \
    --global

作成直後のポリシーには「すべて許可」の既定ルールだけが入っているので、この時点ではサイトの動作は変わりません。

手順2:管理者IPの許可とXML-RPCの遮断

# 管理者の固定IPからの管理画面・ログイン・REST APIへのアクセスを優先して許可(203.0.113.10 は例)
gcloud compute security-policies rules create 100 \
    --security-policy=wp-policy \
    --expression="inIpRange(origin.ip, '203.0.113.10/32') && (request.path.startsWith('/wp-admin/') || request.path.startsWith('/wp-login.php') || request.path.startsWith('/wp-json/'))" \
    --action=allow \
    --description="admin office IP"

# XML-RPC を使っていない場合は拒否
gcloud compute security-policies rules create 200 \
    --security-policy=wp-policy \
    --expression="request.path.startsWith('/xmlrpc.php')" \
    --action=deny-403 \
    --description="block xmlrpc"

XML-RPCは、Jetpackや一部のスマートフォンアプリ、外部ブログ投稿ツールが使っていることがあります。遮断する前に、こうした連携を使っていないかを確認してください。

手順3:ログイン画面にレート制限をかける

# /wp-login.php へのPOSTを同じIPから60秒に10回まで、超えたら10分間遮断
gcloud compute security-policies rules create 300 \
    --security-policy=wp-policy \
    --expression="request.path.startsWith('/wp-login.php') && request.method == 'POST'" \
    --action=rate-based-ban \
    --rate-limit-threshold-count=10 \
    --rate-limit-threshold-interval-sec=60 \
    --ban-duration-sec=600 \
    --conform-action=allow \
    --exceed-action=deny-429 \
    --enforce-on-key=IP

しきい値は、正規の利用者が何度かパスワードを間違えても遮断されない程度に設定します。会員サイトなどで多くの利用者が同じ社内ネットワーク(同じIP)からログインする場合は、値を大きめにするか、キーをIP以外にすることを検討します。ログイン画面の保護はCloud Armorだけに頼らず、強いパスワードや二要素認証、WordPress側のログイン試行制限と組み合わせるのが基本です。

手順4:事前構成WAFルールを追加する

# SQLインジェクション対策(感度1から始める)
gcloud compute security-policies rules create 1000 \
    --security-policy=wp-policy \
    --expression="evaluatePreconfiguredWaf('sqli-v33-stable', {'sensitivity': 1})" \
    --action=deny-403 \
    --preview

# クロスサイトスクリプティング対策
gcloud compute security-policies rules create 1010 \
    --security-policy=wp-policy \
    --expression="evaluatePreconfiguredWaf('xss-v33-stable', {'sensitivity': 1})" \
    --action=deny-403 \
    --preview

感度(sensitivity)は数値が大きいほど多くのシグネチャが有効になり、検知範囲が広がる代わりに誤検知も増えます。WordPressでは感度1から始め、ログを見ながら上げていく進め方が無難です。ルール名に含まれる版(v33 はCore Rule Set 3.3系)は更新されることがあるため(2026年10月現在)、公式ドキュメントで利用可能なルール名を確認してから指定してください。このほかにも、ローカルファイルインクルージョン(lfi)やリモートコード実行(rce)、スキャナー検知などのルールセットが用意されています。

手順5:プレビューモードとログで誤検知を確認する

手順4で付けた --preview は、ルールに一致しても実際には遮断せず、ログに「遮断していたはず」と記録するモードです。この状態で数日運用し、通常の閲覧・コメント投稿・管理画面での編集・プラグインの動作で誤検知が出ないかを確認します。

# ポリシーのログを詳細レベルにする(誤検知の調査時)
gcloud compute security-policies update wp-policy --log-level=VERBOSE

ログはCloud Loggingでロードバランサーのリクエストログとして確認できます。どのルールに一致したか、どのシグネチャが反応したかが記録されるので、誤検知があれば次のいずれかで対処します。

  • 管理画面やREST API(ブロックエディターは /wp-json/ 経由で保存します)の誤検知なら、管理者IPの許可ルールで先に通す。
  • 特定のシグネチャだけが誤検知するなら、opt_out_rule_ids でそのシグネチャを除外する。
  • 特定のパラメータだけが原因なら、リクエストフィールドの除外設定を使う。

問題がなければ、プレビューを外して有効にします。

gcloud compute security-policies rules update 1000 \
    --security-policy=wp-policy \
    --no-preview

WordPress側で合わせて行う設定

ロードバランサーを経由すると、WordPressから見た送信元IPはロードバランサーのものになります。アクセスログやセキュリティプラグインで正しい利用者のIPを扱うには、X-Forwarded-For ヘッダーを参照するよう設定します。このヘッダーは偽装できるため、ロードバランサー以外からVMへ直接届く経路をファイアウォールで閉じておくことが前提です。Google Cloudのロードバランサーとヘルスチェックの送信元IP範囲だけを許可するVPCファイアウォールルールを設定してください。

また、ロードバランサーでHTTPSを終端している場合、WordPressがHTTPSで表示されていることを認識できず、リダイレクトが繰り返されることがあります。その場合は wp-config.php で X-Forwarded-Proto を見てHTTPSと判定する処理を入れます。

// wp-config.php(「編集が必要なのはここまで」の行より前に記述)
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
    $_SERVER['HTTPS'] = 'on';
}

Cloud Armorのルールを誤って厳しくしすぎ、自分が管理画面に入れなくなった場合でも、gcloud やGoogle Cloudコンソールから該当ルールを削除・プレビュー化すれば元に戻せます。ルール変更の前に gcloud compute security-policies export で現在の設定をファイルに書き出しておくと、比較や復元が楽になります。

まとめ

  • Cloud Armorは外部アプリケーションロードバランサーのバックエンドサービスに付けて使います。VMへの直接アクセスは閉じておきます。
  • ルールは「管理者の許可 → XML-RPCの遮断 → ログインのレート制限 → WAF → 既定の許可」の順に並べると管理しやすくなります。
  • 事前構成WAFルールは感度を低めにし、--preview とログで誤検知を確認してから有効にします。
  • ブロックエディターの保存(REST API)や管理画面の操作は誤検知されやすいため、許可ルールや除外設定で調整します。
  • 送信元IPやHTTPS判定など、ロードバランサー経由になったことに伴うWordPress側の設定も合わせて行います。

お気軽にご相談ください

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