はじめに
前回の記事では、閉域(Private Subnet)環境のネットワーク基盤を構築し、Session Managerでのセキュアな接続確認までを完了しました。
今回は構築編②として、以下のステップを進めていきます。
- 一時的な通信確保(NAT Gateway)
- Splunk Server の構築
- ローカルPCからのセキュアなWebアクセス(SSMポートフォワーディング)
- Splunk Universal Forwarder の導入とログ監視設定
- WOWHoneypot の構築と Python 3.12 互換性エラーのデバッグ
- デーモン化(systemd化)
- ALBのマルチAZ制約と設置、ハニーポットの公開
1. 【課題解決】NAT Gateway の構築
前回の記事の最後で触れた通り、現在の Private Subnet は完全な閉域網のため、外部からパッケージをダウンロードすることができません。
そこで、「EC2はプライベートサブネットに置いたまま、安全に外部と通信する」というコンセプトを維持するため、一時的に Public Subnet へ NAT Gateway を作成しました。
-
実施したこと:
- Public Subnet 内に NAT Gateway を作成
- Private Subnet 用のルートテーブルに、デフォルトルート(
0.0.0.0/0➡NAT Gateway)を追加
これにより、一時的にEC2からインターネット(外向き)への通信経路が確保され、各種インストール作業が進められる状態になります。
2. Splunk Server のインストールと初期セットアップ
まずはログ集約基盤となる Splunk Server(EC2)に Session Manager で接続し、以下の手順で導入・起動していきます。
① パッケージのダウンロードとインストール
NAT Gateway 経由で、Splunk 公式からパッケージを取得してインストールします。
# パッケージのダウンロード
wget -O splunk.deb "[https://download.splunk.com/products/splunk/releases/10.4.1/linux/splunk-10.4.1-5a009d941268-linux-amd64.deb](https://download.splunk.com/products/splunk/releases/10.4.1/linux/splunk-10.4.1-5a009d941268-linux-amd64.deb)"
# パッケージのインストール
sudo dpkg -i splunk.deb
② 専用ユーザーの作成と所有権の変更、起動
セキュリティのベストプラクティスに従い、Splunk を root ユーザーではなく専用の splunk ユーザーで起動します。
# splunk ユーザーの作成
sudo useradd splunk
# インストールディレクトリの所有権を splunk ユーザーに変更
sudo chown -R splunk:splunk /opt/splunk
# splunk ユーザーとして Splunk を初回起動
sudo -u splunk /opt/splunk/bin/splunk start
③ ログ受信ポート(9997)の有効化
WOWHoneypot からのログ転送を待ち受けるため、受信用のポート(デフォルト: 9997)を有効化します。
sudo /opt/splunk/bin/splunk enable listen 9997 --run-as-root
④ ステータス確認とトラブルシューティング
Splunk のデーモン(splunkd)が正常に起動しているか確認します。
sudo /opt/splunk/bin/splunk status --run-as-root
splunkd is runningと表示されれば正常です。
もし not running状態であれば、以下のコマンドで再起動を試みます。
sudo /opt/splunk/bin/splunk start --accept-license --run-as-root
⑤ ポータル用 Web ポート(8000)の有効化確認
ブラウザから管理ポータルにアクセスするための Web サーバー機能が有効になっているかを確認します。
# Webポートの設定確認
sudo /opt/splunk/bin/splunk show web-port --run-as-root
# ローカルで8000番ポートがLISTENしているか確認
sudo ss -lntp | grep 8000
LISTENの状態になっていれば問題ありません。
もし Listen していない(Webサーバーが無効化されている)場合は、以下のコマンドで有効化して再起動します。
sudo /opt/splunk/bin/splunk enable webserver --run-as-root
sudo /opt/splunk/bin/splunk restart --run-as-root
3. セキュアに管理画面へアクセスする(SSMポートフォワーディング)
今回の環境構築における、こだわりポイントの一つです。
Splunk の管理画面(8000番ポート)にアクセスしたいですが、EC2は閉域網の中であり、セキュリティグループでも8000番のインバウンドはどこからも許可していません。
そこで、AWS Systems Manager の「ポートフォワーディング(Port Forwarding)機能」を使い、ローカルPCとEC2の間に安全なトンネルを作ってアクセスします。
① ローカルPC(今回はMacOS)の環境準備
手元のPCに AWS CLI と Session Manager Plugin が入っていない場合は、以下のコマンドでインストールします。
# 1. AWS CLI のインストール
curl "[https://awscli.amazonaws.com/AWSCLIV2.pkg](https://awscli.amazonaws.com/AWSCLIV2.pkg)" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /
# 2. Session Manager Plugin のインストール
curl "[https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip](https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip)" -o "sessionmanager-bundle.zip"
unzip sessionmanager-bundle.zip
sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin
② AWS CLI の初期設定(認証情報の紐付け)
AWSコンソール(IAM)から、一時的に必要な権限を持つアクセスキーを発行し、ローカルPCのターミナルで初期設定を行います。
aws configure
AWS Access Key ID: (作成したアクセスキーIDを入力)
AWS Secret Access Key: (作成したシークレットアクセスキーを入力)
Default region: ap-northeast-1
Default output format: json
③ ポートフォワーディング用のセッションを開始
準備が整ったら、以下のコマンドを実行して Splunk 用 EC2 の 8000 番ポートを、ローカルPCの 8000 番ポートにフォワード(転送)します。
aws ssm start-session \
--target <SplunkのインスタンスID> \
--document-name AWS-StartPortForwardingSession \
--parameters '{"portNumber":["8000"],"localPortNumber":["8000"]}'
ターミナルに Starting session... Port 8000 opened... のようなメッセージが表示されれば、セッション接続成功です。
この状態で、ローカルPCのブラウザから http://localhost:8000 にアクセスすると、Splunkのポータル画面にアクセスすることができます。
4. WOWHoneypot への Universal Forwarder 導入
続いて、ハニーポット(WOWHoneypot)側の EC2 に、ログを転送するためのミドルウェア Splunk Universal Forwarder を導入します。
Splunk公式からダウンロードURLを取得します。
# パッケージインデックスの更新
sudo apt update
# Universal Forwarderのダウンロード(※OS環境に合わせたURLを指定)
wget -O splunkforwarder.deb "ダウンロードURL"
# インストール
sudo dpkg -i splunkforwarder.deb
① 初期起動と転送先(Splunk Server)の指定
管理者パスワードを設定して対話なし(ノンインタラクティブ)で起動し、送信先として先ほど構築した Splunk サーバーのプライベートIPとポートを指定します。
# 初期起動
sudo /opt/splunkforwarder/bin/splunk start \
--accept-license \
--answer-yes \
--no-prompt \
--seed-passwd あなたのパスワード
# 転送先サーバーの追加
sudo /opt/splunkforwarder/bin/splunk add forward-server <SplunkのプライベートIP>:9997
※ID/PWを聞かれたら、先ほどForwarder用に設定した admin とパスワードを入力します。
② 自動起動の設定と状態確認
# 自動起動の有効化
sudo /opt/splunkforwarder/bin/splunk enable boot-start
# 転送先ステータスの確認
sudo /opt/splunkforwarder/bin/splunk list forward-server
Active forwards: <SplunkのプライベートIP>:9997と表示されればOKです。
③ 監視対象ログの追加
ハニーポットのアクセスログだけでなく、OS自体のセキュアな状態(不審なログイン試行など)も可視化するため、計3つのログを監視対象に追加します。
sudo /opt/splunkforwarder/bin/splunk add monitor /var/log/auth.log
sudo /opt/splunkforwarder/bin/splunk add monitor /var/log/syslog
sudo /opt/splunkforwarder/bin/splunk add monitor /home/ssm-user/wowhoneypot/log/access_log
# 反映のためForwarderを再起動
sudo /opt/splunkforwarder/bin/splunk restart
# 監視リストの確認
sudo /opt/splunkforwarder/bin/splunk list monitor
リストに3つのファイルが表示されていることを確認します。この段階で、先ほどのブラウザ(
localhost:8000)側でOSログが届き始めているか見ておくと安心です。
5. WOWHoneypot のインストールと「Python 3.12」互換性エラーの修正
いよいよ本丸であるハニーポット(WOWHoneypot)を導入します。
① ネットワーク(UFW)とポートリダイレクトの設定
WOWHoneypot はデフォルトで 8080 ポートで動作します。外部(ALB)からは 80 番ポートで通信を受け付けるため、OSのファイアウォール(UFW)の機能を使って、80番宛ての通信を8080番へリダイレクト(ポートフォワーディング)させます。
※コンセプト通り、SSH(22番)は外部公開しないため UFW でも許可しません。
sudo ufw default DENY
sudo ufw allow 80/tcp
sudo ufw allow 8080/tcp
sudo ufw enable
/etc/ufw/before.rules を編集し、*filter という行よりも前に、以下の4行を追記します。
*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
COMMIT
編集が終わったら、設定をリロードします。
sudo ufw reload
② リポジトリのクローンとPython 3.12 互換性エラーのデバッグ
GitHub から WOWHoneypot のソースコードをクローンして起動を試みます。
cd ~/
git clone [https://github.com/morihisa/WOWHoneypot.git](https://github.com/morihisa/WOWHoneypot.git) wowhoneypot
cd wowhoneypot
最新の Ubuntu 環境(Python 3.12)でそのまま python3 ./wowhoneypot.py を実行するとエラーが発生します。
調べたところ、Python 3.12 から random.seed() に datetime オブジェクトを直接渡すことができなくなった仕様変更に起因するものでした。
そこで、ソースコード(418行目付近)を修正してこのエラーを回避します。
# nanoエディタで行表示しながら418行目へジャンプ
nano -l +418 wowhoneypot.py
# 修正前
random.seed(datetime.now())
# 修正後(タイムスタンプ数値を渡すように変更)
random.seed(datetime.now().timestamp())
修正して保存することで、無事にハニーポットがエラーなく起動するようになります。
6. 【躓きポイント】systemd によるハニーポットのサービス化
筆者は当初、手動起動した状態でALBの作成に進んだのですが、ALBからのヘルスチェックがいつまでも Unhealthy のままになってしまいました。
原因は、Session Manager のセッションが切れたり、フォアグラウンドでプロセスが止まったりするとハニーポットの稼働も止まってしまうためでした。最初からバックグラウンドで永続稼働させるために、systemd によるサービス化をこの段階でやっておくべきでした。
筆者の時系列とは異なりますがこの順番で実施するのがおすすめです。
以下のサービス定義ファイルを作成します。
sudo nano /etc/systemd/system/wowhoneypot.service
[Unit]
Description=WOWHoneypot
After=network.target
[Service]
User=ssm-user
WorkingDirectory=/home/ssm-user/wowhoneypot
ExecStart=/usr/bin/python3 /home/ssm-user/wowhoneypot/wowhoneypot.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
保存後、サービスを有効化して起動します。
sudo systemctl daemon-reload
sudo systemctl enable wowhoneypot
sudo systemctl start wowhoneypot
これで、接続が切れてもハニーポットが裏で24時間動き続ける状態になりました。
7. ALB(Application Load Balancer)の設置とマルチAZ
最後の仕上げとして、インターネットからの受付窓口となる ALB を作成します。
① Target Group の作成
-
Target type:
Instances -
Protocol / Port:
HTTP / 8080(※UFWのリダイレクトを通すため、EC2側で待ち受けている8080番を指定) - ターゲット: WOWHoneypot の EC2 を指定
ALB のマルチAZ制約
ここで想定外の仕様の壁にぶつかりました。AWSの仕様上、ALBは最低でも「2つの異なるアベイラビリティーゾーン(AZ)」のサブネットに属している必要があることが判明しました。
AWS初心者のため知らなかったです...。
ここまでは1つのAZ(ap-northeast-1a)のプライベート空間だけを作っていたため、コンソール画面でエラーを吐かれてしまいました。そのため、慌てて別のAZ(ap-northeast-1c)に Public Subnet 2 を急遽作成・追加することで、無事にALBの作成ができました。
② ALB の作成
-
Scheme:
Internet-facing -
IP address type:
IPv4 - Subnet: 作成した2つの Public Subnet を指定
- Security Group: 事前に作成しておいた、HTTP(80)を全開放した「ALB用SG」
-
Listeners:
HTTP : 80 - Default action: 先ほど作成した Target Group へ転送
8. 運用の要塞化、最終疎通確認
ALBの配置と疎通が確認できたら、インフラ設計編で計画していた通り最後の要塞化(封じ込め)を実行します。
- 役目を終えた NAT Gateway を削除
- Private Route Table から外向きルート(
0.0.0.0/0)を削除
ログの受信確認
ローカルPCのブラウザから、作成した ALB のDNS名(http://<ALBのDNS名>)にテストアクセスしてみます。
その後、ポートフォワーディング経由で開いている Splunk の管理画面(http://localhost:8000)の「Search & Reporting」を開き、以下のSPL文を入力して検索をかけます。
source=*access_log*
ハニーポットが受動したアクセスログが、リアルタイムに Splunk の画面上に降ってきていれば完成です。
おわりに
AWS初心者としての挑戦でしたがとても良い経験になりました。
設計が終わった段階では3〜4時間もあれば構築が終わるだろうと思っていましたが、結局半日かかりました。
しかもめっちゃ疲れました。
自分の見通しの甘さを痛感する結果となりました。
ここまで環境終わればあとはインターネットから攻撃が降ってくるのを待つだけです。
次回(最終回・ログ分析編)では、この環境を実際に数日間インターネットに晒した結果、どのような攻撃ボットや自動スキャン、脆弱性探索が届いたのかを紹介します。

