NATゲートウェイの「中」を覗く:VPCフローログで紐解くセキュリティ監査の勘所
こんにちは。現場で叩き上げのSREをしています。
クラウドの設計図を眺めていると、プライベートサブネットに鎮座するNAT Gatewayは、まるで「外の世界へ繋がる唯一の門番」のように見えますよね。しかし、その門番が誰と通信し、何を弾いているのか、ブラックボックスのままにしていませんか?
セキュリティ監査の現場で「NATゲートウェイを通っている怪しい通信を特定せよ」と言われた時、設定画面をクリックしていても答えは出ません。今回は、VPC Flow Logsを武器に、パケットの挙動を追跡し、実務で使える監査手法を解説します。
なぜNATゲートウェイのログが「真実」を語るのか
AWSやGCPにおいて、NAT Gatewayはマネージドサービスです。OSにログインしてtcpdumpを仕掛けることはできません。ここで唯一、パケットの軌跡を記録してくれるのがVPC Flow Logsです。
特にセキュリティ監査で重要なのは、以下の3点です。
1. 送信元・宛先 IP/Portの特定: どのアプリケーションが、どこへデータを送っているか。
2. REJECTされた通信: セキュリティグループやネットワークACLでブロックされた、不穏な試行の可視化。
3. トラフィックの統計: 突発的なスパイクや、異常なデータ転送量の検知。
監査のためのフローログ設定:最小構成で最大効果を
まずは、解析のために適切なログを出力する必要があります。コンソールからポチポチ設定するのも良いですが、IaC(Terraform等)で管理されているなら、以下のような設定が望ましいです。
# NAT Gatewayのネットワークインターフェース(ENI)に対してフローログを有効化
resource "aws_flow_log" "nat_gateway_logs" {
iam_role_arn = aws_iam_role.flow_log_role.arn
log_destination = aws_cloudwatch_log_group.nat_logs.arn
traffic_type = "ALL" # ACCEPTもREJECTも全て記録する
log_format = "$${version} $${account-id} $${interface-id} $${srcaddr} $${dstaddr} $${srcport} $${dstport} $${protocol} $${packets} $${bytes} $${start} $${end} $${action} $${log-status}"
}
ここで重要なのは、traffic_typeをALLにすることです。REJECTだけでは、正常な通信のトレンドが掴めず、何が「異常」なのかのベースラインが引けません。
Athenaを使った泥臭いログ解析術
CloudWatch Logsに溜まったログをそのまま眺めるのは、砂漠で針を探すようなものです。ここは Amazon Athena を使ってSQLで叩くのがSREの定石です。
1. 通信量のトップランキングを出す
どのインスタンスが外へ大量に通信しているか、IPアドレス別にサマリを作成します。
SELECT
srcaddr,
sum(bytes) / 1024 / 1024 AS total_mb
FROM nat_flow_logs
WHERE action = 'ACCEPT'
GROUP BY srcaddr
ORDER BY total_mb DESC
LIMIT 10;
2. 拒否された(REJECT)通信を特定する
セキュリティグループで弾かれた「意図しない通信」を抽出します。ここには、攻撃の予兆や、設定ミスによる疎通障害のヒントが隠されています。
SELECT
srcaddr,
dstaddr,
dstport,
count(*) AS reject_count
FROM nat_flow_logs
WHERE action = 'REJECT'
GROUP BY srcaddr, dstaddr, dstport
ORDER BY reject_count DESC;
実戦Tips:Web APIのデバッグとNAT
もし、開発中のWeb APIが外部のサードパーティAPIと通信している際にTimeoutが発生しているなら、フローログを見てください。
REJECTが記録されているなら、セキュリティグループのEgressルールを確認してください。ACCEPTされているのに通信が失敗しているなら、それはネットワークの問題ではなく、宛先サーバー側のIP制限や、HTTPヘッダーの不備(User-AgentやContent-Typeなど)である可能性が高いです。
以下は、Pythonで特定のIPへの通信状況を素早く確認するための簡易的なデバッグコードの例です。
import requests
# 接続先APIのテスト
def test_external_api(url):
try:
# タイムアウトを短めに設定してNATの挙動をあぶり出す
response = requests.get(url, timeout=5)
print(f"Status: {response.status_code}")
except requests.exceptions.ConnectTimeout:
print("NAT経由で接続タイムアウトが発生。フローログでREJECTを探せ!")
except Exception as e:
print(f"Error: {e}")
test_external_api("https://api.external-service.com/v1/data")
最後に:ログは「読む」ものではなく「問いかける」もの
セキュリティ監査とは、単にチェックリストを埋める作業ではありません。「この通信は本当に必要か?」「このトラフィックパターンはビジネスの成長と合致しているか?」と、ログに対して問いを立てる作業です。
NATゲートウェイの向こう側は、インターネットという荒野です。フローログという「航海日誌」を正しく記録し、解析する力こそが、堅牢なクラウドインフラを守る唯一の道だと私は信じています。
皆さんのインフラにも、ぜひ一度フローログの光を当ててみてください。意外な「迷子パケット」が見つかるかもしれませんよ。
コメント