GCP VPCファイアウォールで「誰を守り、誰を繋ぐか」:ターゲット指定方式の極意
こんにちは。数々の修羅場をくぐり抜けてきたシニアSREの私です。
本番環境のリリース前夜、何気なく投入したVPCファイアウォールルールが原因で、マイクロサービス間の通信が全滅した――。そんな冷や汗をかくような経験、あなたはありませんか?「とりあえず 0.0.0.0/0 を開けておけ」という悪魔のささやきに屈した結果、セキュリティ監査で真っ赤な警告を受ける。あるいは、インスタンスが増減するたびにファイアウォールのIPアドレスリストを手動で書き換えるという、無限地獄のような運用を強いられる。
GCP(Google Cloud)のVPCファイアウォールは非常に強力ですが、その真価を引き出せるかどうかは「ターゲットの絞り込み方」を完全に理解しているかにかかっています。
今回は、実務の現場で必ず直面する「ターゲットタグ」「ターゲットサービスアカウント」「ターゲットネットワーク(VPC内)」の3つの指定方式について、パケットの挙動から実際のIAM・Terraformのコードまで、泥臭い知見を交えて徹底的に解説します。
—
1. なぜ「IPアドレス指定」だけでは現場が回らないのか
クラウドネイティブな世界では、仮想マシンのIPアドレスは「エフェメラル(一時的)」なものです。オートスケーリングによってインスタンスがスケールアウト・インすれば、10.128.0.x のような内部IPは刻一刻と変わります。
ここに静的なIPアドレスベースのファイアウォールルールを適用しようとすると、次のような破綻が生じます。
- インスタンスが立ち上がるたびにIP変わり、ルールが追いつかない。
- 「どのインスタンスが何の役割を持っているか」がIPからは判別できず、ルールが肥大化・ブラックボックス化する。
ここでGCPが提供する「論理的なターゲット指定(ラベルやアイデンティティによる絞り込み)」の出番です。IPの動的な変化を抽象化し、インフラのライフサイクルからファイアウォールの管理を完全に切り離すことができます。
—
2. 3つのターゲット指定方式のアーキテクチャと使い分け
GCPのVPCファイアウォールルール(Ingress/Egress)では、パケットの宛先(Ingressの場合は受信側)を以下の3つの方式のいずれかで絞り込みます。
1. ターゲットタグ (Target Tags)
2. ターゲットサービスアカウント (Target Service Accounts)
3. ターゲットネットワーク / プレフィックスリスト / ターゲットなし(グローバル)
それぞれの特徴と、実務での「生々しい使い勝手」を見ていきましょう。
方式A:ターゲットタグ(Network Tags)- 最も手軽だが、ガバナンスに注意
インスタンスに付与する文字列の「タグ(例: web-server, db-replica)」をキーにしてファイアウォールを適用します。
- メリット: 直感的で分かりやすい。Terraformやgcloudコマンド、コンソールから気軽に追加・削除できる。
- デメリット(実務の罠): IAMの権限管理と切り離されているため、「誰でも任意のタグをインスタンスに付与できる状態」になっていると、悪意あるユーザーや設定ミスによって意図しないインスタンスにファイアウォールルールが開放されてしまいます(セキュリティ上の特権昇格リスク)。
方式B:ターゲットサービスアカウント(Target Service Accounts)- SREが推す堅牢な選択
GCPのIAMコンセプトである「サービスアカウント(SA)」をターゲットに指定します。
- メリット: 非常にセキュア。インスタンスに紐づくSA(例:
api-server-sa@project-id.iam.gserviceaccount.com)を基準にルールが適用されるため、タグのように「勝手に偽装される」リスクがありません。IAMの権限(roles/iam.serviceAccountUserなど)と連動した厳格なガバナンスが効きます。 - デメリット: 設定や運用ルールがチーム内で共有されていないと、「どのSAがどのファイアウォールと紐づいているか」の追跡がやや直感的ではない(コンソールの一覧性におけるデメリット)。
方式C:ターゲット未指定(すべてに適用)
ターゲットを明示的に指定しない場合、そのVPCネットワーク内のすべてのインスタンスが対象になります(基本的には避けるべき、または全社共通のセキュリティベースライン用)。
—
3. 実践!Terraformによるセキュアなファイアウォール定義
口で言うだけでは説得力がないので、実務でそのまま使えるTerraformコードを見てみましょう。ここでは、「ターゲットサービスアカウント」を用いて、特定のAPIサーバーからのみアクセスを許可するデータベース用ファイアウォールの設定例を示します。
# 1. データベース専用のサービスアカウントの定義
resource "google_service_account" "db_sa" {
account_id = "prod-db-backend-sa"
display_name = "Production Database Service Account"
}
# 2. APIサーバー専用のサービスアカウントの定義
resource "google_service_account" "api_sa" {
account_id = "prod-api-server-sa"
display_name = "Production API Server Service Account"
}
# 3. APIサーバーからDB(PostgreSQL: 5432ポート)へのアクセスを許可するIngressルール
resource "google_compute_firewall" "allow_api_to_db" {
name = "allow-api-to-postgres-prod"
network = "prod-vpc-01"
direction = "INGRESS"
priority = 1000
# 誰からの通信を許可するか(ソース側)
# ここではAPIサーバーのサービスアカウントを指定
source_service_accounts = [
google_service_account.api_sa.email
]
# どの通信を許可するか
allow {
protocol = "tcp"
ports = ["5432"]
}
# 【重要】このルールが適用されるターゲット(宛先側)
# データベースのサービスアカウントを持つインスタンスのみがこのルールの影響を受ける
target_service_accounts = [
google_service_account.db_sa.email
]
description = "Allow inbound PostgreSQL traffic strictly from API servers to DB instances."
}
この構成の美しいところは、仮に新しいAPIインスタンスがオートスケーリングで何百台立ち上がろうとも、それらが prod-api-server-sa を持っている限り、IPアドレスの変更を一切意識することなく、セキュアな通信経路が自動的に担保される点です。
—
4. トラブルシューティング:パケットはどこで消えているのか?
「ファイアウォールを設定したのに、APIからDBに繋がらない!」
現場で最もよくある阿鼻叫喚のシチュエーションです。このような泥沼のトラブルシューティングに直面した際、シニアSREがどのような手順で原因を切り分けるのか、その思考プロセスを伝授しましょう。
Step 1: gcloud で実効ルールの評価を確認する
インスタンスにどのファイアウォールがヒットしているかは、コンソールの画面を眺めているだけでは見落としがあります。以下のコマンドで、対象のインスタンスに適用されているルールをシミュレート・確認します。
# ターゲットインスタンスに対して、指定のポートへの通信が許可されているかテストする
gcloud compute firewall-rules test-for-instance prod-db-instance-01 \
--source-ip=10.128.0.15 \
--protocol=TCP \
--port=5432
このコマンドの出力を見ることで、優先度(priority)の競合や、暗黙の拒否(Deny all ingress)に引っかかっていないかを一発で特定できます。
Step 2: VPCフローログ(VPC Flow Logs)の解析
もしパケットが途中でドロップされている場合、VPCフローログを BigQuery や Cloud Logging で確認します。jsonPayload.connection.drop_reason などのフィールドに FIREWALL_RULE と記録されていれば、ファイアウォールで弾かれています。
ここで、自分が意図した「ターゲットタグ」や「ターゲットサービスアカウント」が、パケットの宛先インスタンスに正しく付与されているかを再確認してください(よくあるミス:TerraformでSAを指定したのに、GCEインスタンス作成時に別のSAをデフォルトで割り当てていた、など)。
—
5. まとめ:プロフェッショナルとしての推奨プラクティス
最後に、GCPのVPCネットワーク設計において私たちが守るべき鉄則をまとめます。
1. 基本は「ターゲットサービスアカウント」をファーストチョイスにする
タグの手軽さに逃げず、IAMのガバナンスと直結するサービスアカウントベースの指定を原則とすることで、セキュリティ事故の芽を摘み取ります。
2. 優先度(Priority)のナンバリングルールをチームで統一する
例えば、カスタム許可ルールは 1000〜1999、緊急遮断ルールは 100〜199 のように、組織内でルールの優先度帯をあらかじめ取り決めておき、カオスを防ぎましょう。
3. インフラのコード化(IaC)を徹底する
コンソールからの手動ポチポチ設定は、やがて「誰も全貌を把握できない負債ファイアウォール」を生み出します。必ずTerraform等で管理し、変更履歴をレビューできる状態を維持してください。
クラウドのネットワークは、正しく理解すればこれほど信頼性が高く、エレガントな仕組みはありません。この記事が、あなたのシステムの安全性と可用性を高める一助となれば幸いです。
それでは、また次回の現場でお会いしましょう。
コメント