【実務・中級編】 ネットワークセグメンテーションとマイクロセグメンテーション – ガバナンス・リスク管理 & 生成AIセキュリティ防御ガイド

境界防御は死んだ。マイクロセグメンテーションで「侵入前提」の防衛線を敷け

現場のエンジニア諸君、お疲れ様。今日もどこかで誰かが「うちはVPCで囲っているから大丈夫」なんて楽観的なことを言っているだろうが、ハッキリ言おう。境界防御だけのセキュリティは、もはやザルだ。

一度WebサーバがRCE(リモートコード実行)を食らえば、そこは攻撃者の拠点(Pivot)となる。ネットワークがフラットなままなら、攻撃者はそこを足がかりにデータベースや管理用APIへ自由に横展開(ラテラルムーブメント)してくる。

今日は、教科書的な「セグメント分けましょう」というお題目を通り越して、「侵入されても被害を最小化する」ための、現場直結のマイクロセグメンテーション戦略を伝授する。

—

1. 攻撃者の視点:なぜ「フラットなネットワーク」は地獄なのか

攻撃者は、最初の足がかりを得た後、まず何をすると思う? 答えは nmap や arp -a じゃない。彼らは、Webサーバの環境変数からAWSのメタデータサービス(IMDSv2)を叩き、IAMロールの権限を盗み、社内の内部ネットワークを「偵察」する。

もし君のWebサーバとDBが同じサブネットにあり、セキュリティグループ(SG)で「VPC内全許可」なんて設定をしていたら、攻撃者は「見えない壁」を突破したも同然だ。攻撃者は、認証不要な内部APIや、パッチ未適用の管理画面を狙い撃ちにする。これが「ラテラルムーブメント」の正体だ。

—

2. 実践:AWSにおける「最小権限」のSG設計

VPCのサブネット分離は当たり前として、肝心なのは「SGによる通信のホワイトリスト化」だ。

よくあるダメな例は「HTTP/HTTPSをどこからでも許可(0.0.0.0/0)」した後に、内部通信も「同じSG内なら許可」とすること。これでは横展開を止められない。

推奨:階層別セキュリティグループの実装

以下の通り、役割ごとにSGを細分化し、「送信元をIPアドレスではなくSG IDで指定」するのが鉄則だ。

  • Web-SG: 80/443をインターネットから許可。
  • App-SG: Web-SG からのトラフィックのみ許可。
  • DB-SG: App-SG からのDBポート(3306/5432等)のみ許可。

Terraformによる定義例(インフラのコード化)

# DBサーバ用のセキュリティグループ定義
resource "aws_security_group" "db_sg" {
  name        = "db-security-group"
  description = "App-SGからのアクセスのみ許可"
  vpc_id      = var.vpc_id

  # ここが重要:IPではなく「App-SG」のIDをソースとして指定する
  ingress {
    from_port       = 5432
    to_port         = 5432
    protocol        = "tcp"
    security_groups = [aws_security_group.app_sg.id] 
    description     = "App-SGからの通信のみ許可(ラテラルムーブメント阻止)"
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

—

3. アプリケーション層でのガードレール:WAFによる保護

ネットワークレベルだけでなく、アプリケーション層でも「想定外の通信」を弾く必要がある。特に最近は、生成AI系のAPIを利用するアプリが増えているが、これが「SSRF(サーバーサイド・リクエスト・フォージェリ)」の温床になりやすい。

curl や file_get_contents で外部URLを直接叩くロジックには、必ずバリデーションを噛ませろ。

PHPでの実装例:URLホワイトリストによるSSRF対策

<?php
/**
 * 外部API呼び出し時のSSRF対策
 * 信頼できるホスト以外へのリクエストを遮断する
 */
function safe_remote_request($url) {
    $allowed_hosts = ['api.trusted-service.com', 'ai-model.provider.com'];
    $parsed_url = parse_url($url);

    // ホスト名がホワイトリストに含まれているかチェック
    if (!in_array($parsed_url['host'], $allowed_hosts)) {
        throw new Exception("不正なホストへのリクエストを検知しました: " . $parsed_url['host']);
    }

    // ここから先で実際の通信処理を行う
    // ...
}
?>

—

4. 最後に:なぜ現場でこれが守れないのか

現場でこの設計が崩れる最大の理由は「運用コスト」だ。SGを細かく分けすぎると、開発時に「あれ、繋がらない!」というトラブルシューティングが増える。

しかし、セキュリティチーフとして言わせてもらえば、「繋がらない」というエラーは、攻撃者にとっても「侵入できない」という最強の壁だ。

エンジニア諸君、便利なだけの環境は、攻撃者にとっても便利な環境だということを忘れるな。今日から、君たちのVPCを見直してほしい。特定のSG ID以外からの通信はすべて DENY されているか? ログには拒否されたパケットが記録されているか?

セキュリティは「設定して終わり」じゃない。「監視して、絞り込んで、育てる」ものだ。明日からの運用で、ぜひこの意識を取り入れてくれ。期待している。

コメント

タイトルとURLをコピーしました