はじめに
前回の記事では、ハニーポット環境全体の設計について紹介しました。
今回は実際にAWS環境を構築していきます。
本記事では以下の内容を構築します。
- VPC / Public & Private Subnet
- Internet Gateway / Route Table
- VPC Endpoint(Session Manager用)
- Security Group / IAM Role
- EC2 インスタンスの作成と接続確認
なお、実際のWOWHoneypotやSplunkのインストール・初期設定については次回の記事で紹介します。
完成イメージ
1.VPCの作成
まずはすべての基盤となるVPCを作成します。
今回は検証環境のため、ネットワーク帯域(CIDR)は以下のようにシンプルな設計にしました。
Pv4 CIDR: 10.0.0.0/16
2.Public / Private Subnetの作成
今回は以下のようにSubnetを分けています。
| サブネット名 | CIDR(例) | 主な配置コンポーネント |
|---|---|---|
| Public Subnet | 10.0.1.0/24 | ALB、NAT Gateway(構築時のみ) |
| Private Subnet | 10.0.10.0/24 | WOWHoneypot、Splunk |
EC2はすべてPrivate Subnetへ配置します。
これにより、攻撃者からEC2へ直接アクセスできない構成としています。
3.Internet Gatewayの作成
Public Subnetからインターネットへ通信できるよう、Internet Gatewayを作成します。
4.Route Tableの作成
パブリック環境とプライベート環境を明確に分離し、構築のフェーズに合わせて動的に変更する設計にしました。
🌐 Public Subnet 用ルートテーブル(常時利用)
インターネットからの入口となるALBが配置されるため、外向きのデフォルトルートを Internet Gateway(IGW)に向けています。
| 送信先(Destination) | ターゲット(Target) | 説明 |
|---|---|---|
| 10.0.0.0/16(例) | local | VPC内部の通信 |
| 0.0.0.0/0 | Internet Gateway | インターネットへの外向き通信 |
🔒 Private Subnet 用ルートテーブル(フェーズで切り替え)
WOWHoneypotやSplunkが配置される閉域環境です。ここでは、安全性を担保するために構築時と公開後(運用時)でルートテーブルの設定を切り替えるライフサイクルを採用しました。
【フェーズ1】環境構築時(一時的な開放)
WOWHoneypotやSplunkのインストール、各種パッケージのアップデートを行うためには、一時的にEC2からインターネット(外部のレポジトリなど)へ接続する必要があります。そのため、この期間だけ NAT Gateway を作成し、デフォルトルートを向けました。
| 送信先(Destination) | ターゲット(Target) | 説明 |
|---|---|---|
| 10.0.0.0/16 | local | VPC内部の通信 |
| 0.0.0.0/0 | NAT Gateway | インストール、アップデートのための外向き通信(一時的) |
【フェーズ2】ハニーポット公開・運用時
必要なソフトウェアのセットアップがすべて完了した後は、NAT Gatewayを即座に削除し、ルートテーブルからも 0.0.0.0/0のデフォルトルートを完全に削除しました。
| 送信先(Destination) | ターゲット(Target) | 説明 |
|---|---|---|
| 10.0.0.0/16(例) | local | VPC内部の通信 |
| ルート自体を削除(Outboundを遮断) |
これにより、ハニーポット公開後に万が一EC2のOSやミドルウェアのレイヤで侵害が発生した場合でも、EC2が自発的にインターネット(攻撃者のC2サーバーなど)へ通信を試みるルートそのものが存在しないため、ネットワークレベルでの封じ込めが実現できています。
5.VPC Endpointの作成
今回は安全管理のためSSH(22番ポート)を利用せず、AWS Systems ManagerのSession ManagerのみでEC2を管理する構成としました。
Private Subnet(閉域網)からインターネットを経由せずにSystems Managerと通信させるため、以下3つのVPCエンドポイント(インターフェイス型)を作成します。
com.amazonaws.ap-northeast-1.ssmcom.amazonaws.ap-northeast-1.ssmmessagescom.amazonaws.ap-northeast-1.ec2messages
※これらはSession Managerをプライベート環境で動作させるための必須コンポーネントとなります。エンドポイント自身のセキュリティグループには、VPC内部からのHTTPS(443)通信を許可しておきます。
6.Security Groupの作成
今回の環境では、役割ごとに3つのセキュリティグループ(SG)を作成し、お互いに必要最低限の通信だけを許可する「最小権限の原則」を徹底しました。管理アクセスにSession Managerを採用しているため、SSH(22番ポート)はどこからも開放していません。
具体的には、以下のようにインバウンド(受信)ルールを構成しています。
| 対象コンポーネント | 許可するプロトコル / ポート | 送信元(Source) | 設計の意図 |
|---|---|---|---|
| ALB用 SG | HTTP (80) | 0.0.0.0/0 (任意のインターネット) | インターネット上の攻撃者(スキャンボット含む)からの通信を全開放で受け付けます。 |
| WOWHoneypot用 SG | HTTP (80) | ALB用のセキュリティグループ | インターネットから直接EC2へアクセスされるのを防ぐため、送信元を「ALBからの通信のみ」に限定します。 |
| Splunk用 SG | ログ受付ポート (9997) | WOWHoneypot用のセキュリティグループ | ハニーポットが取得したログを安全に転送するため、送信元を「WOWHoneypotのEC2のみ」に限定します。管理画面(8000)は閉域化しています。 |
🔒 アウトバウンド(要塞化のポイント)
また、前述の「NAT Gatewayの削除」と合わせて、構築完了後は各EC2のセキュリティグループのアウトバウンド(送信)ルールからも 0.0.0.0/0(すべて許可)を削除しています。
これにより、万が一WOWHoneypotに未知の脆弱性(RCEなど)があり、攻撃者にシェルを取られたとしても、ハニーポットを踏み台にして外部へ攻撃パケットを飛ばしたり、C2サーバーから追加のマルウェアをダウンロードしたりできないようにしています。
(※SSM通信に必要なVPCエンドポイント宛てのアウトバウンド通信のみをピンポイントで許可、またはVPC内部通信のみに限定しています)
7.IAM Roleの作成
EC2へ以下のIAM Roleを付与します。
AmazonSSMManagedInstanceCore
これにより、Session Managerを利用できるようになります。
8.EC2の作成
今回はハニーポットおよびSIEMのベースOSとして Ubuntu Server 24.04 LTSを採用し、Private Subnet内に2台作成しました。
| サーバー用途 | インスタンスタイプ | ストレージ(EBS) | 割り当てたIAMロール |
|---|---|---|---|
| WOWHoneypot | t3.micro | 8 GB (General Purpose SSD) | 作成したSSM用ロール |
| Splunk Server | t3.small | 30 GB (General Purpose SSD) | 作成したSSM用ロール |
※Splunkは多くのログを蓄積・インデックス化して可視化するため、インスタンスタイプを少し引き上げ(t3.small)、ディスク容量も多めの30GBに拡張しています。
9.Session Managerで接続確認
ここまで設定できれば、Session ManagerからEC2へ接続できるはず…
と思っていましたが、ここでかなり時間を使いました。
EC2は正常に起動しているにもかかわらず、Session Managerから接続できなかったためです。

躓きポイント
VPC Endpointを作成し、IAM RoleをEC2へ付与すれば接続できると思っていました。
しかし実際には、それ以外にも確認すべき設定がいくつかありました。
🔍 泥臭く実施したトラブルシューティング(確認項目)
「VPCエンドポイントを作成し、IAMロールをEC2へ付与すれば繋がるはず」という思い込みを捨て、以下のチェックリストを一つずつ切り分けながら確認していきました。
-
EC2に
AmazonSSMManagedInstanceCoreポリシーを含むIAMロールが付与されているか - IAMロールの変更がEC2に反映されているか(数分待機)
-
ssmエンドポイント(インターフェース型)が正しく作成されているか -
ssmmessagesエンドポイントが正しく作成されているか -
ec2messagesエンドポイントが正しく作成されているか -
VPCの設定で
Enable DNS Resolution(DNS解決)が有効になっているか -
VPCの設定で
Enable DNS Hostnames(DNSホスト名)が有効になっているか -
各VPCエンドポイントで
Private DNS(プライベートDNS)が有効になっているか - IMDS(インスタンスメタデータサービス)の設定(V2のみの場合のトークンホップ数など)
- (念のための)EC2の再起動
切り分けた結果、今回の原因は「各VPCエンドポイントの『プライベートDNS』が無効になっていたこと」でした。
これを有効化したところ、Session Managerでの接続が確立しました。
💡 なぜ「プライベートDNS」を有効にすると接続できるのか?
今回調査した中で、一番「インフラとしての学び」が深かった部分です。
最初は「VPCエンドポイントさえ作れば、AWSが内部でよしなに通信を曲げてくれる」と思っていました。
しかし、実世界(オンプレミス等)のネットワークと同様に、通信の裏側には必ず「DNSによる名前解決」のプロセスが存在します。
SSMのエージェント(EC2側)は、内部的に ssm.ap-northeast-1.amazonaws.com というパブリックなFQDNに対して通信を試みます。
プライベートDNSが「無効」の場合の挙動
名前解決を担当するのは、VPC内の AmazonProvidedDNS(別名:Route 53 Resolver)です。
プライベートDNSが無効な状態だと、このDNSサーバーは ssm.ap-northeast-1.amazonaws.com に対してAWSのパブリックIPアドレスを返してしまいます。
-
通信経路(失敗):
EC2 → (DNS問い合わせ) →AmazonProvidedDNS→ 「パブリックIP」と返答される
→ EC2はパブリックIPへ通信しようとする → NAT GatewayもIGWもない閉域(Private Subnet)のため、パケットが外に出られずタイムアウト
プライベートDNSを「有効」にした場合の挙動
VPCエンドポイントの「プライベートDNSを有効化」すると、AWSは AmazonProvidedDNS の内部に専用のDNSレコードを自動でインジェクション(登録)してくれます。
これにより、同じFQDNへの問い合わせに対して、VPCエンドポイント(に紐づくENI)のプライベートIPアドレスが返るようになります。
-
通信経路(成功):
EC2 → (DNS問い合わせ) →AmazonProvidedDNS→ 「VPCエンドポイントのプライベートIPだよ」と返答される
→ EC2は同じVPC内のプライベートIPへ通信する → VPCエンドポイントを経由してSystems Managerへ到達
結論
最初は「プライベートDNSを有効にする」という設定名の意図がピンと来ていませんでしたが、
「AWSが裏で提供しているDNSサーバー(AmazonProvidedDNS)に対して、パブリックなSSMのドメインをVPCエンドポイントのプライベートIPにすり替える(上書きする)機能」
であると理解できました。
まとめと次回予告
これで、インターネットから隔離されたPrivate Subnet内のEC2に対して、SSHポートを開放することなく安全にリモート接続できる環境が整いました。
インフラの骨組みとしてはこれで完成ですが、実はこのままでは「WOWHoneypotやSplunkをインストールするためのパッケージを外部からダウンロードできない」という問題にぶつかります。
次回の記事では、この「完全閉域網」というコンセプトを崩さずに、安全かつ一時的に外部と通信を確立するNAT Gatewayの導入からスタートし、ミドルウェアのインストールと可視化の連携までを進めていきます。
