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側の設定も合わせて行います。