VPCトラフィックミラーリングを使用してAWS上にネットワークIDSを作ってみた

サービス概要

VPCトラフィックミラーリングとは、ミラー対象に指定したソースENIを通るトラフィックの中身をミラーリングしたパケットを、別のターゲットENIやNLB、GWLBに転送することができる機能です。


https://d1.awsstatic.com/webinars/jp/pdf/services/20201021_AWS-BlackBelt-VPC.pdfより)

目的・やりたいこと

インターネットから来た通信をALBで受けてECS/Fargateに流す通信があり、その通信をミラーリングして外部のIDSに流したいという要件がある。AWSで実装できる構成があるか検証する。

対象となる技術

条件(導入にあたって前提事項)

  • 次のリソースをトラフィック ミラー ターゲットとして使用できます。
    • インタフェースタイプのENI
    • NLB
    • GWLBエンドポイント
  • ALB配下のEC2(Web)はあらかじめ作成してあるものとします。
  • ALBの作成やそのターゲットの作成の説明は割愛します。

参考URL

注意事項

  • トラフィック ミラーリングは、次の仮想 Nitro インスタンス タイプでは使用できません。
    • 汎用: M6a、M6i、M6in、M7g、M7i、M7i-flex
    • 最適化されたコンピューティング: C6a、C6gn、C6i、C6id、C6in、C7g、Hpc6a
    • メモリ最適化: R6a、R6i、R6id、R6idn、R6in、R7g、R7iz、X2idn、X2iedn、X2iezn
    • ストレージの最適化: I4g、I4i、Im4gn、Is4gen
    • 高速コンピューティング: Inf2、Trn1
  • トラフィック ミラーリングはベアメタル インスタンスでは利用できません。
  • Traffic Mirroring は、Nitro 以外のインスタンス タイプ C4、D2、G3、G3s、H1、I3、M4、P2、P3、R4、X1、および X1e でのみ使用できます。これには T2 インスタンスは含まれない
  • UDP 4789ポートでトラフィックをミラーするので、IDS側で受けられるかどうかの確認が必要

作業の流れ

概要図

事前作業

これが骨が折れました。なにせ20年くらい前のツールなので文献も古いし、参考になるサイトで最新のものがなかなかない。
機能も流石に無償だけあって有償の製品に比べたら全然劣ります。無料で最低限のIDSの検証だけできればいいというのならオススメ
AWSならNetwork FirewallのSuricataがあるし、あまり使われることはないでしょう。
ちなみにファイル改ざん検知に特化するならAIDE(Advanced Intrusion Detection Environment)がオススメ

1.Snortのインストール
EC2(Amazon Linux 2)に、Snortの最新版を入れます。

# wget https://www.snort.org/downloads/snort/snort-2.9.20-1.centos.x86_64.rpm
# amazon-linux-extras install epel -y
# yum install -y gcc flex bison zlib libpcap pcre libdnet tcpdump libnghttp2 daq daq-devel
# ln -s /usr/lib64/libdnet.so.1.0.1 /usr/lib64/libdnet.1
# yum install -y snort-2.9.20-1.centos.x86_64.rpm

2.Snortの起動確認

# systemctl start snortd
# systemctl status snortd
● snortd.service - SYSV: snort is a lightweight network intrusion detection tool that currently detects more than 1100 host and network vulnerabilities, portscans, backdoors, and more.
   Loaded: loaded (/etc/rc.d/init.d/snortd; bad; vendor preset: disabled)
   Active: active (running) since Fri 2023-10-27 15:41:52 UTC; 7h ago
     Docs: man:systemd-sysv-generator(8)
  Process: 12747 ExecStop=/etc/rc.d/init.d/snortd stop (code=exited, status=0/SUCCESS)
  Process: 12763 ExecStart=/etc/rc.d/init.d/snortd start (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/snortd.service
           mq12781 /usr/sbin/snort -A fast -b -d -D -i eth0 -u snort -g snort -c /etc/snort/snor...

Oct 27 15:41:52 ip-10-0-43-242.ap-northeast-1.compute.internal snort[12781]:            Preproce...
Oct 27 15:41:52 ip-10-0-43-242.ap-northeast-1.compute.internal snort[12781]:            Preproce...
Oct 27 15:41:52 ip-10-0-43-242.ap-northeast-1.compute.internal snort[12781]:            Preproce...
Oct 27 15:41:52 ip-10-0-43-242.ap-northeast-1.compute.internal snort[12781]:            Preproce...
Oct 27 15:41:52 ip-10-0-43-242.ap-northeast-1.compute.internal snort[12781]:            Preproce...
Oct 27 15:41:52 ip-10-0-43-242.ap-northeast-1.compute.internal snort[12781]:            Preproce...
Oct 27 15:41:52 ip-10-0-43-242.ap-northeast-1.compute.internal snort[12781]:            Preproce...
Oct 27 15:41:52 ip-10-0-43-242.ap-northeast-1.compute.internal snort[12781]:            Preproce...
Oct 27 15:41:52 ip-10-0-43-242.ap-northeast-1.compute.internal snort[12781]:            Preproce...
Oct 27 15:41:52 ip-10-0-43-242.ap-northeast-1.compute.internal snort[12781]: Commencing packet p...
Hint: Some lines were ellipsized, use -l to show in full.

3.Snortの設定
ここではまず検知テストとして、pingを検知するルールを作ります。
/etc/snort/snort.conf に下記の設定を追加

include $RULE_PATH/icmp_test.rules

4.シグネチャ/etc/snort/rules/icmp_test.rules を作成

# vi /etc/snort/rules/icmp_test.rules
alert icmp any any -> any any (msg:"ICMP Packet"; sid:477;rev:3;)

5.local.rules、white_list.rules、black_list.rulesのファイルが無いと起動時にエラーになるので、起動前に作成しておく。

# touch /etc/snort/rules/local.rules
# touch /etc/snort/rules/white_list.rules
# touch /etc/snort/rules/black_list.rules

6.設定ファイルの文法チェック

# snort -T -c /etc/snort/snort.conf
〜略〜
Total snort Fixed Memory Cost - MaxRss:45512
Snort successfully validated the configuration!
Snort exiting

「successfully」が出てればOK
ここでエラーが出た場合は、ルールが無いとかがほとんどなので、設定ファイル内のルールを参照している箇所をひたすらコメントアウトしてください。例えばこんな感じ

#include $RULE_PATH/app-detect.rules
#include $RULE_PATH/attack-responses.rules
#include $RULE_PATH/backdoor.rules
#include $RULE_PATH/bad-traffic.rules
#include $RULE_PATH/blacklist.rules
#include $RULE_PATH/botnet-cnc.rules
#include $RULE_PATH/browser-chrome.rules
#include $RULE_PATH/browser-firefox.rules

7.設定を反映するため、Snort を再起動

# systemctl restart snortd

8.アラートファイルを作成

# touch /var/log/snort/alert

9.Pingを実行

# ping www.yahoo.co.jp

10.アラートが出ていることを確認

# cat /var/log/snort/alert
10/27-23:50:24.594682  [**] [1:477:3] ICMP Packet [**] [Priority: 0] {ICMP} 10.0.43.242 -> 183.79.219.252
10/27-23:50:24.601611  [**] [1:477:3] ICMP Packet [**] [Priority: 0] {ICMP} 183.79.219.252 -> 10.0.43.242
  • NLBの設定

今回はNLBをターゲットにミラーリングしているため、そのNLBの設定が大事になってきます。
自分はポート4789の設定を完全に忘れていてハマったため、注意してください。
NLBの設定はここが参考になりました。

1.UDP 4789ポートによるターゲットグループを作成しておきます。今回は遠隔地のオンプレミスIDSを想定しているため、ターゲットタイプは[IPアドレス]にしておきます。

2.リスナーをUDP 4789にしてNLB作成します。

  • VPC Traffic Mirroringの設定

VPC Traffic Mirroringでは、「ミラーターゲット」「ミラーフィルタ」「ミラーセッション」の3つを作成する必要があります。

1.トラフィックミラーターゲットの作成
ターゲットとして作成したNLBを選択します。

2.トラフィックミラーフィルタの作成
インバウンド/アウトバウンドともに念のため全許可のルールで作成しておきます。

3.トラフィックミラーセッションの作成
ミラーソースはキャプチャしたいALBのENIを選択、ミラーターゲットは先ほど作成したNLBを選択します。

セッション数は1、ミラーフィルタは先ほど作成したものを選択します。

検証手順

  • まず、ALBにアクセスして、そのパケットがSnortに流れているかを確認します。

1.ALBのURLにアクセス

2.Snort側でtcpdumpし、該当のHTTPSパケットが来ていることを確認

# tcpdump -i eth0 -n port 4789
IP 10.0.15.155.https > 134.238.*.*. 33800: Flags [P.], seq 5438:5779, ack 1067, win 179, options [nop,nop,TS val 402313766 ecr 2755605989], length 341
  • 次に、いよいよIDSで検知ルールを作成して検知します。

1.Snortで、UDP 4789宛のパケットを検知するルールlocal.rulesを作成

# vi /etc/snort/rules/local.rules
alert udp any any -> any 4789 (msg: "VXLAN Packet detected!"; sid:999;)

2.アラートファイルで検知を確認!

# tail /var/log/snort/alert
0/28-00:49:44.518171  [**] [1:999:0] VXLAN Packet detected! [**] [Priority: 0] {UDP} 10.0.15.155:65522 -> 10.0.43.242:4789
10/28-00:49:44.518172  [**] [1:999:0] VXLAN Packet detected! [**] [Priority: 0] {UDP} 10.0.15.155:65522 -> 10.0.43.242:4789

所要時間

2時間