🔒

GitHub Webhook 用エンドポイントを Cloud Armor で保護する

に公開

結論

GitHub Webhook 用エンドポイントを Cloud Armor で保護し、GitHub からのリクエストのみを許可する方法を紹介します。

やること:

  1. GitHub Meta API (https://api.github.com/meta) から GitHub Webhook 配信用 IP アドレスを取得
  2. Cloud Armor のセキュリティポリシーで GitHub の IP アドレスのみ許可

取得コマンド:

curl -s https://api.github.com/meta | jq -r '.hooks[]'

現在(2025/11/16)の Webhook 用 IP アドレス(IPv4):

  • 192.30.252.0/22
  • 185.199.108.0/22
  • 140.82.112.0/20
  • 143.55.64.0/20

それでは、詳しくみていきましょう(`・ω・´)ゞ

はじめに

GitHub Webhook を受け取るサービスを構築していると「GitHub からのリクエストのみを受け付けたい」というセキュリティ要件が出てきました。
私のケースでは、Atlantis を導入したときにこの問題が発生しました 🫨
Atlantis の Webhook エンドポイントはインターネットに公開する必要がありますが、公開されたエンドポイントは攻撃の対象になりやすいため、適切な保護が必要です。

そこで本記事では、GitHub Webhook 配信用の IP アドレスを取得し、Cloud Armor でその IP アドレスからのアクセスのみを許可する方法を紹介します。

前提知識

GitHub の IP アドレス情報

GitHub は、Webhook 配信やその他のサービスで使用する IP アドレスレンジを公開しています。これらの情報は Meta API (https://api.github.com/meta) から取得できます。

Meta API からは、様々な GitHub サービスで使用される IP アドレスが取得できますが、今回必要なのは hooks フィールドに含まれる Webhook 配信用の IP アドレスです。

Cloud Armor とは

Cloud Armor は GCP が提供するネットワークセキュリティサービスで、DDoS 攻撃からの保護や IP アドレスベースのアクセス制御を提供します。Load Balancer や Cloud Run などと統合して使用できます。

参考:

GitHub Webhook 配信用 IP アドレスを取得する

Meta API から取得する

ここではシンプルに curl コマンドで API を叩いて IP アドレスを取得します。

curl -s https://api.github.com/meta | jq -r '.hooks[]'

実行すると、以下のような CIDR 形式の IP アドレスレンジが取得できます。

192.30.252.0/22
185.199.108.0/22
140.82.112.0/20
143.55.64.0/20
2a0a:a440::/29
2606:50c0::/32

参考:

Cloud Armor で GitHub IP のみ許可する

取得した IP アドレスレンジを使って、Cloud Armor のセキュリティポリシーを設定します。
これにより、GitHub の IP アドレスからのリクエストのみを許可し、その他のアクセスは拒否します。

Terraform での設定例

resource "google_compute_security_policy" "webhook_policy" {
  name = "github-webhook-policy"

  # デフォルトはすべて拒否
  rule {
    action   = "deny(403)"
    priority = "2147483647"
    match {
      versioned_expr = "SRC_IPS_V1"
      config {
        src_ip_ranges = ["*"]
      }
    }
    description = "Default deny all"
  }

  # GitHub の Webhook IP アドレスのみ許可
  rule {
    action   = "allow"
    priority = "1000"
    match {
      versioned_expr = "SRC_IPS_V1"
      config {
        src_ip_ranges = [
          "192.30.252.0/22",
          "185.199.108.0/22",
          "140.82.112.0/20",
          "143.55.64.0/20",
          "2a0a:a440::/29",
          "2606:50c0::/32",
        ]
      }
    }
    description = "Allow GitHub Webhook IPs"
  }
}

この設定により、GitHub の IP アドレスからのリクエストは許可され、それ以外のリクエストは 403 エラーで拒否されます。

参考:

余談:GKE で BackendConfig を使ってポリシーを適用する

私のケースでは GKE で Atlantis を動かしているため、BackendConfig を使ってセキュリティポリシーを Service にアタッチしました。

BackendConfig の定義:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: atlantis-backend-config
  namespace: atlantis
spec:
  securityPolicy:
    name: "github-webhook-policy"  # 上記 Terraform で作成したポリシー名

Service にアタッチ:

apiVersion: v1
kind: Service
metadata:
  name: atlantis
  namespace: atlantis
  annotations:
    cloud.google.com/backend-config: '{"default": "atlantis-backend-config"}'

この設定により、Ingress → Load Balancer → Service の経路で Cloud Armor のセキュリティポリシーが適用され、GitHub の IP アドレスからのリクエストのみが Atlantis に到達できるようになります。
※ 実際には Kustomize でパッチとして適用しています。

参考:

おわりに

GitHub Webhook 用エンドポイントを Cloud Armor で保護し、GitHub の IP アドレスからのリクエストのみを許可する方法を紹介しました。
GitHub Webhook を受け取るサービスを構築・運用している方のお役に立てば幸いです🤞

参考文献

Discussion