業界・業務から探す
導入目的・課題から探す
データ・AIについて学ぶ
News
Hakkyについて
ウェビナーコラム
◆トップ【Hakkyの社内Wiki】Strapi
クラウドとオンプレの違いAIシステム導入時におすすめのクラウドシステムスクレイピングのためのプロキシサーバのAPI
AI

執筆者:Handbook編集部

TerraformでのCloud Armor構成例

Terraform での Cloud Armor 構成例

Cloud Armor は Google 製のクラウド型 WAF (Web Application Firewall) です。

本記事では Cloud Armor を Terraform で構成する例とセキュリティポリシーの設定方法を説明します。

Cloud Armor の基本的な情報をお探しの場合は、こちらをご参考ください。

Terraform での構成例

Terraform は、HashiCorp 社が提供するコンピュータやネットワークの構築を自動化するツールです。

本章では、次のような構成を Terraform で Cloud Armor に関連する各セキュリティの対策をどのように設定するか確認していきます。

ディレクトリ構成

下記構成で作成します。

.
|- main.tf
|- load_balancing.tf
|- cloud_run.tf
|- cloud_armor.tf
|- myCredentials.json

myCredentials.json は Terraform を操作するサービスアカウントのシークレットキーになります。

本確認では Terraform を操作するサービスアカウントに【Cloud Run 管理者】の権限を与えた状態で確認を行なっております。

main.tf (入出力やプロバイダー設定)

細かい操作などで google,google-beta プロバイダーが必要になるため、provider ブロックはそれぞれ設定しております。

実行時に入力した方が扱いやすいデータに関しては変数として取り扱っております。

  • name: インスタンスにつける名前
  • project-id: 構成を作る GCP のプロジェクト ID。プロジェクト名ではないので注意
  • ssl: ssl 認証を有効にするか
  • domain: ドメイン名
  • region: リージョン名
# Input
variable "name" {}
variable "project_id" {}
variable "ssl" {}
variable "domain" {}
variable "region" {}

# Output
output "lb_ip" {
  value = module.lb-http.external_ip
}

# Provider
provider "google" {
  credentials = file("myCredentials.json")
  project     = var.project_id
  region      = var.region
}

provider "google-beta" {
  credentials = file("myCredentials.json")
  project     = var.project_id
  region      = var.region
}

load_balancing.tf  (ロードバランサーの設定)

Cloud Armor は Load Blancing にアタッチする関係で、Load Balancing とバックエンドのリソースが必要になります。

ここでは、構成例を参考にロードバランサーの設定を行なっております。

# Load Balancing
module "lb-http" {
  source  = "GoogleCloudPlatform/lb-http/google//modules/serverless_negs"
  version = "~> 6.2.0"
  name    = "${var.name}-lb"
  project = var.project_id

  ssl                             = var.ssl
  managed_ssl_certificate_domains = [var.domain]
  https_redirect                  = var.ssl

  backends = {
    default = {
      description = null
      groups = [
        {
          group = google_compute_region_network_endpoint_group.serverless_neg.id
        }
      ]
      enable_cdn              = false
      security_policy         = google_compute_security_policy.default.id # セキュリティポリシーの設定はこちらで行っております。
      custom_request_headers  = null
      custom_response_headers = null

      iap_config = {
        enable               = false
        oauth2_client_id     = ""
        oauth2_client_secret = ""
      }
      log_config = {
        enable      = true
        sample_rate = null
      }
    }
  }
}

# Serverless NEG
resource "google_compute_region_network_endpoint_group" "serverless_neg" {
  provider              = google-beta
  name                  = "serverless-neg"
  network_endpoint_type = "SERVERLESS"
  region                = var.region
  cloud_run {
    service = google_cloud_run_service.default.name
  }
}

cloud_run.tf (バックエンドサービスの設定)

バックエンドのサービスとして、CloudRun の Hello コンテナを一つ作成します。

なお、こちらの Cloud Run のコンテナは誰でもアクセスできる状態にしておりますが、そのように設定するにはサービスアカウントに run.services.setIamPolicy 権限が必要になります。

# Cloud Run
resource "google_cloud_run_service" "default" {
  name     = "${var.name}-cloudrun"
  location = var.region
  project  = var.project_id

  template {
    spec {
      containers {
        image = "gcr.io/cloudrun/hello"
      }
    }
  }
}

resource "google_cloud_run_service_iam_member" "public-access" {
  location = google_cloud_run_service.default.location
  project  = google_cloud_run_service.default.project
  service  = google_cloud_run_service.default.name
  role     = "roles/run.invoker"
  member   = "allUsers"
}

cloud_armor.tf (セキュリティポリシーの作成)

本章の肝にあたるロードバランサーにアタッチするセキュリティポリシーを設定します。

ルールとしては、デフォルトで誰でも通信可能という状態から、OWASP10 大リスクを軽減する事前設定ルールを設定しております。

なお、コメントにもありますが、一つのルールに expression に含められる条件が5つまでなので、10 大リスクのルール設定は分割して設定しております。

こちらの項目の設定方法の詳細については後述いたします。

# Cloud Armor Resource
resource "google_compute_security_policy" "default" {
  name    = "${var.name}-sequrity-policy"
  project = var.project_id

  # OWASP TOP10 Risk ※割り当てが5つまでなので分割しています。
  rule {
    action      = "deny(403)"
    description = "OWASP TOP10 Risk (1)"
    preview     = false
    priority    = 1000

    match {
      expr {
        expression = <<-EOT
                        evaluatePreconfiguredExpr("sqli-v33-stable")
                        || evaluatePreconfiguredExpr("xss-v33-stable")
                        || evaluatePreconfiguredExpr("lfi-v33-stable")
                        || evaluatePreconfiguredExpr("rfi-v33-stable")
                        || evaluatePreconfiguredExpr("rce-v33-stable")
        EOT
      }
    }
  }

  rule {
    action      = "deny(403)"
    description = "OWASP TOP10 Risk (2)"
    preview     = false
    priority    = 1100

    match {
      expr {
        expression = <<-EOT
                        evaluatePreconfiguredExpr("methodenforcement-v33-stable")
                        || evaluatePreconfiguredExpr("scannerdetection-v33-stable")
                        || evaluatePreconfiguredExpr("protocolattack-v33-stable")
                        || evaluatePreconfiguredExpr("php-v33-stable")
                        || evaluatePreconfiguredExpr("sessionfixation-v33-stable")
        EOT
      }
    }
  }

  # Default
  rule {
    action      = "allow"
    description = "default rule"
    preview     = false
    priority    = 2147483647

    match {
      versioned_expr = "SRC_IPS_V1"
      config {
        src_ip_ranges = ["*"]
      }
    }
  }
}

Terraform でセキュリティポリシーの設定方法の詳細

.tf ファイルで設定する場合、構成としては下記のようにルールを追記していく形でセキュリティポリシーを作成していきます。

なお、デフォルトにあたる 優先度が 2147483647 の基本ルールは必ず作る必要があります。

resource "google_compute_security_policy" "name" {
  name = "<セキュリティポリシーの名前>"

  rule{
    # ルールを設定する
  }
  rule{
    # 別のルール
  }
  ...and more ...
}

コンソールでルールを作成する際は基本ルールと詳細ルールがありましたが、Terraform ではどのように設定するのが見ていきましょう。

基本ルールを設定したい場合

主な利用例:ホワイトリストやブラックリストで IP を制限したい場合など

基本ルールを設定する場合、次の項目が必要になります。

  • action: ルールと一致したら許可するか拒否するかを設定します。
    • "allow": 許可
    • "dany(XXX)": 拒否、XXX には 403,404,502 のいずれかの数字が入ります
    • その他の設定項目についてはこちら
  • priority: 優先度を 0 ~ 2147483646 の間で設定します。数字が低いほど優先されます。
  • match: 一致するルールを設定します。基本ルールで設定する場合、versioned_expr と config が必須になります。
    • versioned_expr: 事前定義されたルール式を設定します。こちらの例を見る限り"SRC_IPS_V1"を設定する形で動作するようです。
    • config: versioned_expr を設定した場合必須になります。
      • src_ip_ranges: ip の範囲を設定します。["*"]の場合、すべての IP が対象になります。

下記設定例は、ホワイトリスト形式で 9.9.9.0/24 の IP を許可したルールになります。

rule {
  action = "allow"
  priority = "1000"
  match {
    versioned_expr = "SRC_IPS_V1"
    config {
      src_ip_ranges = ["9.9.9.0/24"]
    }
  }
}

rule {
    action   = "deny(404)"
    priority = "2147483647"
    match {
      versioned_expr = "SRC_IPS_V1"
      config {
        src_ip_ranges = ["*"]
      }
    }
  }

詳細ルールを設定したい場合

主な利用例:「OWASP10 大リスク」を軽減する事前設定ルールなどを設定したいとき

詳細ルールを設定する場合、次の項目が必要になります。

  • action: 一致したら許可するか拒否するかを設定します。基本ルールと同様です
  • priority: 優先度を 0 ~ 2147483646 の間で設定します。こちらも基本ルールと同様です
  • match: 一致するルールを設定します。詳細ルールで設定する場合、expr で設定する必要があります。

ポイントは expression に一致した式が当てはまるので、こちらに必要な条件を記載していく形を取ることになるかと思います。

ただし、指定する場合も割り当て上限などがありますので、うまくデプロイできない場合はこちらをご確認ください。

下記設定例は OWASP10 大リスクを軽減する事前設定の一部の設定例になります。

rule {
    action      = "deny(403)"
    priority    = 1000

    match {
      expr {
        expression = <<-EOT
                        evaluatePreconfiguredExpr("sqli-v33-stable")
                        || evaluatePreconfiguredExpr("xss-v33-stable")
                        || evaluatePreconfiguredExpr("lfi-v33-stable")
                        || evaluatePreconfiguredExpr("rfi-v33-stable")
                        || evaluatePreconfiguredExpr("rce-v33-stable")
        EOT
      }
    }
  }

# defaultは省略

Terraform での各対策

DDoS 対策

デフォルトで Managed Protection にて DDoS 攻撃の保護が働いていますが、

Adaptive Protection を有効にすることで L7DDoS 攻撃に対してアラートを生成できるようになります。

Terraform で Adaptive Protection を有効にするには下記のように設定します。

resource "google_compute_security_policy" "default" {
  provider = google-beta # beta版の機能のため設定が必須です。
  name     = "${var.name}-sequrity-policy"
  adaptive_protection_config {
    layer_7_ddos_defense_config {
      enable = true
    }
  }
  # 以下略

SQL インジェクション

expression にevaluatePreconfiguredExpr("sqli-<varsion>")を設定することで SQL インジェクションに対して検知するようになります、

詳しい設定方法は前述の詳細ルールを設定したい場合をご覧ください。

高度なルールでのアクセス制限

詳細ルールを設定したい場合をご覧ください。

参考

info
備考

Hakky ではエンジニアを募集中です!まずは話してみたいなどでも構いませんので、ぜひお気軽に採用ページからお問い合わせくださいませ。

2025年06月15日に最終更新
読み込み中...