現場のエンジニア諸君、日々のアラート対応とデプロイで疲弊していないだろうか。
「クラウドは安全だ」という神話は、AWSやAzureが物理層を守ってくれるというだけの話だ。その上で動くOS、そしてその中を流れるトラフィックという「泥沼」は、依然として我々が守り抜かねばならない聖域である。
今回は、インフラの要塞化において最も見落とされがちな、しかし攻撃者にとっては「宝の山」となるVPCフローログの収集とSIEM連携について、実務的な知見を共有する。
なぜ「ログ」ではなく「フロー」なのか
攻撃者は、侵入後の「ラテラルムーブメント(横展開)」で必ずネットワークを探索する。OSのプロセスを覗き見る前に、まずはどのポートが空いているか、どのIPと通信しているかをスキャンするのだ。
ここでフローログを見ていれば、攻撃者の足跡は丸見えだ。
- 「通常、Webサーバーが接続することのないDBサーバーへの不審なコネクション」
- 「深夜帯の、外部未知IPへの巨大なアウトバウンド通信(データ持ち出しの兆候)」
これらをSIEMでリアルタイムに検知できなければ、侵入されてから数ヶ月間、気づかぬうちにバックドアを維持される。これが現代のインシデントの「正体」だ。
AWSにおけるフローログの「正しい」設定
コンソールからポチポチ設定するだけでは足りない。IAMロールの設計と、収集するデータの粒度が肝だ。以下は、最小権限の原則に基づいたTerraformの設定例である。
# フローログを保存するS3バケットへの書き込み権限を持つIAMロール
resource "aws_iam_role" "vpc_flow_logs_role" {
name = "vpc-flow-logs-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = { Service = "vpc-flow-logs.amazonaws.com" }
}]
})
}
# 実際にフローログを有効化する
resource "aws_flow_log" "main_vpc_flow" {
iam_role_arn = aws_iam_role.vpc_flow_logs_role.arn
log_destination = aws_cloudwatch_log_group.flow_logs.arn
traffic_type = "ALL" # REJECTだけでなくACCEPTも取得せよ。許可したはずの通信の異常を見抜くためだ。
vpc_id = aws_vpc.main.id
# 重要なTips: サンプリング頻度を「1分」に設定する。デフォルトの10分では攻撃の初動を見逃す。
max_aggregation_interval = 60
}
SIEMとの連携:異常検知のロジック
ログを溜めるだけでは「墓場」だ。SIEM(Splunk, Datadog, あるいはAWS OpenSearch)側で、以下のPythonスクリプトのようなロジックを走らせ、異常な通信を即座にSlackへ通知させる設計が不可欠だ。
# 簡易的な異常検知ロジックの概念コード
def detect_malicious_flow(log_entry):
"""
SIEM側で実行される検知関数
"""
# 1. 拒否された通信が短時間に急増していないか?(ポートスキャンの兆候)
if log_entry['action'] == 'REJECT':
if count_rejects(log_entry['src_addr']) > THRESHOLD:
return "ALERT: Possible Port Scan detected from " + log_entry['src_addr']
# 2. 許可リストにない外部IPへのアウトバウンド通信
if log_entry['dst_addr'] not in TRUSTED_IPS and log_entry['direction'] == 'outbound':
return "CRITICAL: Unauthorized Outbound Connection to " + log_entry['dst_addr']
return None
現場の盲点:なぜ「ACCEPT」ログが重要なのか
多くの初心者が「REJECT(拒否)」ログだけを監視する。しかし、熟練の攻撃者は、既に開いている穴(例:設定ミスで公開された管理画面、あるいはWebアプリの脆弱性)を通って侵入する。
彼らは「許可された通信」に偽装して動く。だからこそ、「許可された通信の異常なパターン(通信量、時間帯、送信先)」をベースラインとして学習し、そこからの逸脱を検知するアプローチが必要なのだ。
最後に:防御は「停止」から始まる
ネットワークをどれだけ監視しても、不要なサービスが動いていれば、それは「穴」が増えているのと同じだ。サーバー要塞化の鉄則を最後に伝えておく。
1. netstat -tulpn で不要なポートを開けているプロセスを特定する。
2. systemctl stop ではなく systemctl disable で再起動時の自動起動を殺す。
3. クラウドのセキュリティグループは 0.0.0.0/0 を絶対に許さない。特定の踏み台サーバーやVPN経由のIPのみに限定する。
セキュリティとは、ツールを入れることではない。「何が正常で、何が異常か」を定義し、それを執拗に監視し続ける運用そのものだ。今日から、君たちのログを「墓場」から「武器」に変えていってほしい。
何かあれば、またいつでも相談に乗る。健闘を祈る。
コメント