Suricataと呼ばれるオープンソースのIDS(侵入検知システム) / IPS(侵入防止システム)をRaspberry Piに導入します。
今回はIDSとして構築し、カスタムルールを作成してそのルールに基づくパケットを検知するところまで。
$ uname -aLinux rasp4-1 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux
とても簡単なネットワーク構成です。
(実際の弊宅のネットワーク構成はもう少しごちゃってます。)
eth0 : 192.168.120.5wlan0 : 192.168.1.6 (SSH接続でも使う)
nic1 : 192.168.120.3nic2 : 192.168.1.9
ひとまずaptパッケージの更新をします。
$ sudo apt update$ sudo apt upgrade$ sudo apt dist-upgrade
Suricataに必要なパッケージ群をインストールします。
$ sudo apt install -y libpcre3 libpcre3-dbg libpcre3-dev \build-essential autoconf automake libtool libpcap-dev libnet1-dev \libyaml-0-2 libyaml-dev zlib1g zlib1g-dev libmagic-dev libcap-ng-dev \libjansson-dev pkg-config python3-yaml rustc cargo
Suricataをラズパイにダウンロードして、解凍します。
$ wget https://www.openinfosecfoundation.org/download/suricata-6.0.13.tar.gz$ tar -xvf suricata-6.0.13.tar.gz
解凍した展開されたディレクトリに移動して、ビルドとインストールを行います。
$ cd suricata-6.0.13$ ./configure$ make$ sudo make install-full$ sudo ldconfig
ビルドには約10分程かかります。
sudo make install-fullのinstall-full
は必要なディレクトリや設定ファイルの生成、利用可能なルールセットのダウンロードなど、すぐ使える状態にセットアップしてくれます。
(詳細: https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Debian_Installation#Auto-setup)
備考: configureのオプション
他の文献でよくみるオプションの軽い説明を書いときます。
今回はデフォルトの配置場所で問題ないと思っているので未指定です。また、--enable-nfqueue
はIPSとして動かすときに必要で、別途前提パッケージのインストールが必要です。
(詳細: https://docs.suricata.io/en/suricata-6.0.13/install.html#common-configure-options)
--prefix : バイナリの配置場所 (デフォルト: /usr/local)--sysconfdir : 構成ファイルの配置場所 (デフォルト: /usr/local/etc)--localstatedir : ログファイルの配置場所 (デフォルト: /usr/local/var/log/suricata)--enable-nfqueue : IPSとして動かすときに必要なオプション
設定ファイルであるsuricata.yamlを編集します。一応、編集前にオリジナルのsuricata.yamlのバックアップを取っておきます。
$ sudo cp /usr/local/etc/suricata/suricata.yaml /usr/local/etc/suricata/suricata.yaml.org$ sudo vi /usr/local/etc/suricata/suricata.yaml
rule-files:
という文字列を探して、以下のように任意のrulesファイル名を追記します。
#### Configure Suricata to load Suricata-Update managed rules.##default-rule-path: /usr/local/var/lib/suricata/rulesrule-files:- suricata.rules- user_custom.rules # add
rule-files
に列挙したファイル名は、default-rule-path
内に存在する必要があります。
ということで、rulesファイルを下のようにして作成します。
$ sudo vi /usr/local/var/lib/suricata/rules/user_custom.rules
user_custom.rulesに下のようなルールを書きます。
alert icmp any any -> any any (msg: "ICMP ping detected"; sid: 100001; rev: 1;)alert http any any -> any any (msg: "Access to himazin331.com"; http.host; content: "himazin331.com"; sid: 100002; rev: 1;)
このルールについては後ほど説明しますので一旦先に進んで、suricata-update
でルールを適用します。
$ sudo suricata-update1/7/2023 -- 03:32:57 - <Info> -- Using data-directory /usr/local/var/lib/suricata.1/7/2023 -- 03:32:57 - <Info> -- Using Suricata configuration /usr/local/etc/suricata/suricata.yaml1/7/2023 -- 03:32:57 - <Info> -- Using /usr/local/share/suricata/rules for Suricata provided rules.1/7/2023 -- 03:32:57 - <Info> -- Found Suricata version 6.0.13 at /usr/local/bin/suricata.1/7/2023 -- 03:32:57 - <Info> -- Loading /usr/local/etc/suricata/suricata.yaml1/7/2023 -- 03:32:57 - <Info> -- Disabling rules for protocol http21/7/2023 -- 03:32:57 - <Info> -- Disabling rules for protocol modbus1/7/2023 -- 03:32:57 - <Info> -- Disabling rules for protocol dnp31/7/2023 -- 03:32:57 - <Info> -- Disabling rules for protocol enip1/7/2023 -- 03:32:57 - <Info> -- No sources configured, will use Emerging Threats Open1/7/2023 -- 03:32:57 - <Info> -- Last download less than 15 minutes ago. Not downloading https://rules.emergingthreats.net/open/suricata-6.0.13/emerging.rules.tar.gz.1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/app-layer-events.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/decoder-events.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/dhcp-events.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/dnp3-events.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/dns-events.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/files.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/http-events.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/ipsec-events.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/kerberos-events.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/modbus-events.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/nfs-events.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/ntp-events.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/smb-events.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/smtp-events.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/stream-events.rules1/7/2023 -- 03:32:57 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/tls-events.rules1/7/2023 -- 03:32:58 - <Info> -- Ignoring file rules/emerging-deleted.rules1/7/2023 -- 03:33:05 - <Info> -- Loaded 43403 rules.1/7/2023 -- 03:33:05 - <Warning> -- Disabling ja3 rules as Suricata is built without libnss.1/7/2023 -- 03:33:05 - <Info> -- 116 ja3_hash rules disabled.1/7/2023 -- 03:33:06 - <Info> -- Disabled 130 rules.1/7/2023 -- 03:33:06 - <Info> -- Enabled 0 rules.1/7/2023 -- 03:33:06 - <Info> -- Modified 0 rules.1/7/2023 -- 03:33:06 - <Info> -- Dropped 0 rules.1/7/2023 -- 03:33:07 - <Info> -- Enabled 131 rules for flowbit dependencies.1/7/2023 -- 03:33:07 - <Info> -- Backing up current rules.1/7/2023 -- 03:33:16 - <Info> -- Writing rules to /usr/local/var/lib/suricata/rules/suricata.rules: total: 43403; enabled: 34466; added: 0; removed 1; modified: 01/7/2023 -- 03:33:16 - <Info> -- Writing /usr/local/var/lib/suricata/rules/classification.config1/7/2023 -- 03:33:17 - <Info> -- Testing with suricata -T.1/7/2023 -- 03:33:30 - <Info> -- Done.
suricata-update
は自身が定義したルールを適用する他、Emerging Threats Open rulesetのダウンロード・更新もします。
Emerging Threats Open rulesetはセキュリティ情報共有コミュニティであるEmerging Threatsが提供するオープンソースのルールセットです。
ルールにはaction, header, optionsの3つのセクションに分かれています。
actionは次にも説明しますが、ルールに該当するパケットの処理を記述します。
headerは通信プロトコルと送信側/受信側IPアドレスとポート、通信の方向を記述します。TCP/IPのインターネット層とトランスポート層にあたる情報ですね。
optionsはシグネチャ情報やパケットの詳細なルール(TCP/IPのアプリケーション層にあたる情報)を記述します。
シグネチャとは、脅威を特定・判別するために用いられる識別情報です。
| alert | icmp any any -> any any | (msg: "ICMP ping detected"; sid: 100001; rev: 1;) || ↑ | ↑ ↑ ↑ ↑ ↑ ↑ | ↑ ↑ ↑ || 処理形式 |プロトコル src-ip src-port direction dst-ip dst-port | シグネチャメッセージ シグネチャID リビジョン ||---------|----------------------------------------------------|---------------------------------------------------|| action | header | options |
ここでは簡単に最小限の説明にとどめます。
actionもとい、処理形式はそのルールに該当する場合、そのパケットをどう処理するかを指定します。種類は下のとおりです。
種類 | 説明 |
---|---|
alert | アラートを発報 |
pass | パケット解析を中止(通信の許可) |
drop | パケットをドロップしてアラートを発報 |
reject | パケット送信者にRST/ICMP 到達不能エラーを送信 |
rejectsrc | rejectと同じ |
rejectdst | パケット受信者にRST/ICMP 到達不能エラーを送信 |
rejectboth | パケット送信者/受信者にRST/ICMP 到達不能エラーを送信 |
headerについて説明します。
tcp, udp, icmp, ipもちろん、下のようなプロトコルも対応しています。http, ftp, tls(*1), smb, dns, dcerpc, ssh, smtp, imap, nfs, ikev2, krb5, ntp,dhcp, rfb, rdp, snmp, tftp, sip, http2, modbus(*2), dnp3(*2), enip(*2)*1. sslも含む*2. デフォルトで無効になっているため、suricata.yamlで要有効化
$HOME_NET
/$EXTERNAL_NET
)、any(全てのIPアドレス)を指定します。
$HOME_NET
/$EXTERNAL_NET
はsuricata.yamlで定義できます。[ ]
を使ってIPアドレスを複数列挙できるほか、not演算子!
を使って除外もできます。any192.168.1.2192.168.1.0/24$HOME_NET$EXTERNAL_NET[192.168.1.2, 192.168.1.3]![192.168.1.2, 192.168.1.3][$HOME_NET, 192.168.1.2][192.168.1.0/24, !192.168.1.2][192.168.1.0/24, ![192.168.1.2, 192.168.1.3]]
:
を使ってポート番号を範囲指定できるほか、IPアドレスの指定同様カッコ[ ]
による複数列挙とnot演算子!
による除外もできます。any80[80, 81, 82][80: 82][1024: ]!8080[80:100, !99][1:80, ![2,4]]
->
ですが、双方向通信を示す<>
を指定することもあるようです。
<-
は存在しないっぽいです。(要らないですし)optionsについて説明します。
msg
sid
sid
は整数値のみ認められ、一意である必要があります。rev
の前、最後から2番めに書くっぽいです。rev
rev
は整数値のみ認められます。上で挙げた情報はいずれもルールに関わる情報で、メタキーワードと呼ばれます。
他にもいくつかのメタキーワードがありますので、詳細は7.2. Meta Keywords — Suricata 6.0.13 documentationを確認してください。
また、TCP/IPのアプリケーション層にあたる情報についても大量にあるので、
7. Suricata Rules — Suricata 6.0.13 documentationから各プロトコルごとのキーワードを確認して指定してください。
簡単にルール構文の説明をしたところで、user_custom.rulesに書いたルールを説明すると...
alert icmp any any -> any any (msg: "ICMP ping detected"; sid: 100001; rev: 1;)→ すべての送信元からすべての送信先に対してICMP通信がきたらアラートを発報するalert http any any -> any any (msg: "Access to himazin331.com"; http.host; content: "himazin331.com"; sid: 100002; rev: 1;)→ すべての送信元において"himazin331.com"とHTTP通信が行われたらアラートを発報する(himazin331.comのIPアドレス/ポートは問わない)
となります。とても簡単なルールですね。
以下のコマンドを入力してSuricataを実行します。
-c
は設定ファイルパスの指定オプション。多分無くても動くと思います。-i
はインターフェースの指定オプション、-v
はログレベルInfoを出力するオプションです。
インターフェースの指定は複数指定が可能で、eth0とwlan0両方を監視対象としています。
<Notice> - all X packet processing threads, X management threads initialized, engine started.
みたいなのが出力されたら監視が開始されます。
1$ sudo suricata -c /usr/local/etc/suricata/suricata.yaml -i eth0 -i wlan0 -v21/7/2023 -- 05:09:58 - <Notice> - This is Suricata version 6.0.13 RELEASE running in SYSTEM mode31/7/2023 -- 05:09:58 - <Info> - CPUs/cores online: 441/7/2023 -- 05:09:58 - <Info> - Setting engine mode to IDS mode by default51/7/2023 -- 05:09:58 - <Info> - Found an MTU of 1500 for 'eth0'61/7/2023 -- 05:09:58 - <Info> - Found an MTU of 1500 for 'eth0'71/7/2023 -- 05:09:58 - <Info> - Found an MTU of 1500 for 'wlan0'81/7/2023 -- 05:09:58 - <Info> - Found an MTU of 1500 for 'wlan0'91/7/2023 -- 05:09:58 - <Info> - fast output device (regular) initialized: fast.log101/7/2023 -- 05:09:58 - <Info> - eve-log output device (regular) initialized: eve.json111/7/2023 -- 05:09:58 - <Info> - stats output device (regular) initialized: stats.log121/7/2023 -- 05:09:58 - <Info> - Running in live mode, activating unix socket131/7/2023 -- 05:10:02 - <Info> - 2 rule files processed. 34468 rules successfully loaded, 0 rules failed141/7/2023 -- 05:10:02 - <Info> - Threshold config parsed: 0 rule(s) found151/7/2023 -- 05:10:03 - <Info> - 34471 signatures processed. 1278 are IP-only rules, 5234 are inspecting packet payload, 27752 inspect application layer, 108 are decoder event only161/7/2023 -- 05:10:11 - <Info> - Going to use 4 thread(s)171/7/2023 -- 05:10:11 - <Info> - Going to use 4 thread(s)181/7/2023 -- 05:10:11 - <Info> - Running in live mode, activating unix socket191/7/2023 -- 05:10:11 - <Info> - Using unix socket file '/usr/local/var/run/suricata/suricata-command.socket'201/7/2023 -- 05:10:11 - <Notice> - all 8 packet processing threads, 4 management threads initialized, engine started.211/7/2023 -- 05:10:11 - <Info> - All AFP capture threads are running.
PC上でターミナルを開き、pingコマンドを実行します。
まずは192.168.1.0/24のネットワークで。PC: 192.168.1.9 ---> Rasp Pi: 192.168.1.6
ping 192.168.1.6 -n 10
pingが完了したらラズパイに戻って、Ctrl+C
でSuricataを終了します。
次に下のコマンドを実行し、アラートが出力されているかを確認します。
$ cat /usr/local/var/log/suricata/fast.log07/01/2023-05:10:34.258335 [**] [1:100001:1] ICMP ping detected [**] [Classification: (null)] [Priority: 3] {ICMP} 192.168.1.9:8 -> 192.168.1.6:007/01/2023-05:10:34.258420 [**] [1:100001:1] ICMP ping detected [**] [Classification: (null)] [Priority: 3] {ICMP} 192.168.1.6:0 -> 192.168.1.9:0
$ cat /usr/local/var/log/suricata/eve.json | grep 100001{"timestamp":"2023-07-01T05:16:51.347768+0900","flow_id":852141781765752,"in_iface":"eth0","event_type":"alert","src_ip":"192.168.120.3","src_port":0,"dest_ip":"192.168.120.5","dest_port":0,"proto":"ICMP","icmp_type":8,"icmp_code":0,"alert":{"action":"allowed","gid":1,"signature_id":100001,"rev":1,"signature":"ICMP ping detected","category":"","severity":3},"flow":{"pkts_toserver":1,"pkts_toclient":0,"bytes_toserver":74,"bytes_toclient":0,"start":"2023-07-01T05:16:51.347768+0900"}}{"timestamp":"2023-07-01T05:16:51.347865+0900","flow_id":852141781765752,"in_iface":"eth0","event_type":"alert","src_ip":"192.168.120.5","src_port":0,"dest_ip":"192.168.120.3","dest_port":0,"proto":"ICMP","icmp_type":0,"icmp_code":0,"alert":{"action":"allowed","gid":1,"signature_id":100001,"rev":1,"signature":"ICMP ping detected","category":"","severity":3},"flow":{"pkts_toserver":1,"pkts_toclient":1,"bytes_toserver":74,"bytes_toclient":74,"start":"2023-07-01T05:16:51.347768+0900"}}
つづいて、192.168.120.0/24のネットワークで。PC: 192.168.120.3 ---> Rasp Pi: 192.168.120.5
ping 192.168.120.5 -n 10
先程同様に終了し、ログをみてみます。
$ cat /usr/local/var/log/suricata/fast.log07/01/2023-05:16:51.347768 [**] [1:100001:1] ICMP ping detected [**] [Classification: (null)] [Priority: 3] {ICMP} 192.168.120.3:8 -> 192.168.120.5:007/01/2023-05:16:51.347865 [**] [1:100001:1] ICMP ping detected [**] [Classification: (null)] [Priority: 3] {ICMP} 192.168.120.5:0 -> 192.168.120.3:0
$ cat /usr/local/var/log/suricata/eve.json | grep 100001{"timestamp":"2023-07-01T05:16:51.347768+0900","flow_id":852141781765752,"in_iface":"eth0","event_type":"alert","src_ip":"192.168.120.3","src_port":0,"dest_ip":"192.168.120.5","dest_port":0,"proto":"ICMP","icmp_type":8,"icmp_code":0,"alert":{"action":"allowed","gid":1,"signature_id":100001,"rev":1,"signature":"ICMP ping detected","category":"","severity":3},"flow":{"pkts_toserver":1,"pkts_toclient":0,"bytes_toserver":74,"bytes_toclient":0,"start":"2023-07-01T05:16:51.347768+0900"}}{"timestamp":"2023-07-01T05:16:51.347865+0900","flow_id":852141781765752,"in_iface":"eth0","event_type":"alert","src_ip":"192.168.120.5","src_port":0,"dest_ip":"192.168.120.3","dest_port":0,"proto":"ICMP","icmp_type":0,"icmp_code":0,"alert":{"action":"allowed","gid":1,"signature_id":100001,"rev":1,"signature":"ICMP ping detected","category":"","severity":3},"flow":{"pkts_toserver":1,"pkts_toclient":1,"bytes_toserver":74,"bytes_toclient":74,"start":"2023-07-01T05:16:51.347768+0900"}}
ICMPパケットを10個送ったので、forward/backward合わせて20個のアラートがあることを期待したのですが、なぜか2個しか無いですね....
フロー情報を出力したeve.jsonをみても、pkts_toserver/pkts_toclientは1だし...
この辺、理由がわかるかた居ましたらTwitterやメールで教えてください。
まあ、とりあえずICMPパケットが送られてきたことを検知して、アラートが出力されたことが確認できましたね。
ラズパイに別セッションでSSH接続し、そのターミナル上で"himazin331.com"にHTTP通信でアクセスします。
まずは192.168.1.0/24のネットワークで。Rasp Pi: 192.168.1.6 ---> himazin331.com: 103.152.178.181
$ curl --interface wlan0 http://himazin331.com
Suricataを終了し、ログを見ます。
$ cat /usr/local/var/log/suricata/fast.log07/01/2023-05:20:33.577228 [**] [1:100001:1] ICMP ping detected [**] [Classification: (null)] [Priority: 3] {ICMP} 192.168.120.1:3 -> 192.168.120.5:307/01/2023-05:20:33.649334 [**] [1:100002:1] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 103.152.178.181:80 -> 192.168.1.6:3976007/01/2023-05:20:33.652658 [**] [1:100002:1] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 103.152.178.181:80 -> 192.168.1.6:3976007/01/2023-05:20:33.652701 [**] [1:100002:1] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.1.6:39760 -> 103.152.178.181:8007/01/2023-05:20:33.653460 [**] [1:100002:1] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.1.6:39760 -> 103.152.178.181:8007/01/2023-05:20:33.674213 [**] [1:100002:1] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 103.152.178.181:80 -> 192.168.1.6:3976007/01/2023-05:20:33.674251 [**] [1:100002:1] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.1.6:39760 -> 103.152.178.181:80
$ cat /usr/local/var/log/suricata/eve.json | grep 100002{"timestamp":"2023-07-01T05:20:33.649334+0900","flow_id":294012943676400,"in_iface":"wlan0","event_type":"alert","src_ip":"103.152.178.181","src_port":80,"dest_ip":"192.168.1.6","dest_port":39760,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":100002,"rev":1,"signature":"Access to himazin331.com","category":"","severity":3},"http":{"hostname":"himazin331.com","url":"/","http_user_agent":"curl/7.74.0","http_method":"GET","protocol":"HTTP/1.1","length":0},"app_proto":"http","flow":{"pkts_toserver":3,"pkts_toclient":2,"bytes_toserver":284,"bytes_toclient":140,"start":"2023-07-01T05:20:33.603120+0900"}}{"timestamp":"2023-07-01T05:20:33.652658+0900","flow_id":294012943676400,"in_iface":"wlan0","event_type":"alert","src_ip":"103.152.178.181","src_port":80,"dest_ip":"192.168.1.6","dest_port":39760,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":100002,"rev":1,"signature":"Access to himazin331.com","category":"","severity":3},"http":{"hostname":"himazin331.com","url":"/","http_user_agent":"curl/7.74.0","http_method":"GET","protocol":"HTTP/1.1","length":0},"app_proto":"http","flow":{"pkts_toserver":3,"pkts_toclient":3,"bytes_toserver":284,"bytes_toclient":559,"start":"2023-07-01T05:20:33.603120+0900"}}{"timestamp":"2023-07-01T05:20:33.652701+0900","flow_id":294012943676400,"in_iface":"wlan0","event_type":"alert","src_ip":"192.168.1.6","src_port":39760,"dest_ip":"103.152.178.181","dest_port":80,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":100002,"rev":1,"signature":"Access to himazin331.com","category":"","severity":3},"http":{"hostname":"himazin331.com","url":"/","http_user_agent":"curl/7.74.0","http_content_type":"text/html","http_method":"GET","protocol":"HTTP/1.1","status":301,"redirect":"https://himazin331.com/","length":162},"app_proto":"http","flow":{"pkts_toserver":4,"pkts_toclient":3,"bytes_toserver":350,"bytes_toclient":559,"start":"2023-07-01T05:20:33.603120+0900"}}{"timestamp":"2023-07-01T05:20:33.653460+0900","flow_id":294012943676400,"in_iface":"wlan0","event_type":"alert","src_ip":"192.168.1.6","src_port":39760,"dest_ip":"103.152.178.181","dest_port":80,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":100002,"rev":1,"signature":"Access to himazin331.com","category":"","severity":3},"http":{"hostname":"himazin331.com","url":"/","http_user_agent":"curl/7.74.0","http_content_type":"text/html","http_method":"GET","protocol":"HTTP/1.1","status":301,"redirect":"https://himazin331.com/","length":162},"app_proto":"http","flow":{"pkts_toserver":5,"pkts_toclient":3,"bytes_toserver":416,"bytes_toclient":559,"start":"2023-07-01T05:20:33.603120+0900"}}{"timestamp":"2023-07-01T05:20:33.674213+0900","flow_id":294012943676400,"in_iface":"wlan0","event_type":"alert","src_ip":"103.152.178.181","src_port":80,"dest_ip":"192.168.1.6","dest_port":39760,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":100002,"rev":1,"signature":"Access to himazin331.com","category":"","severity":3},"http":{"hostname":"himazin331.com","url":"/","http_user_agent":"curl/7.74.0","http_content_type":"text/html","http_method":"GET","protocol":"HTTP/1.1","status":301,"redirect":"https://himazin331.com/","length":162},"files":[{"filename":"/","sid":[],"gaps":false,"state":"CLOSED","stored":false,"size":162,"tx_id":0}],"app_proto":"http","flow":{"pkts_toserver":5,"pkts_toclient":4,"bytes_toserver":416,"bytes_toclient":625,"start":"2023-07-01T05:20:33.603120+0900"}}{"timestamp":"2023-07-01T05:20:33.674251+0900","flow_id":294012943676400,"in_iface":"wlan0","event_type":"alert","src_ip":"192.168.1.6","src_port":39760,"dest_ip":"103.152.178.181","dest_port":80,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":100002,"rev":1,"signature":"Access to himazin331.com","category":"","severity":3},"http":{},"app_proto":"http","flow":{"pkts_toserver":6,"pkts_toclient":4,"bytes_toserver":482,"bytes_toclient":625,"start":"2023-07-01T05:20:33.603120+0900"}}
つづいて、192.168.120.0/24のネットワークで。Rasp Pi: 192.168.120.5 ---> himazin331.com: 103.152.178.181
$ curl --interface eth0 http://himazin331.com
Suricataを終了し、ログを見ます。
$ cat /usr/local/var/log/suricata/fast.log07/01/2023-05:22:19.954569 [**] [1:100001:1] ICMP ping detected [**] [Classification: (null)] [Priority: 3] {ICMP} 192.168.120.1:3 -> 192.168.120.5:307/01/2023-05:22:20.016863 [**] [1:100002:1] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 103.152.178.181:80 -> 192.168.120.5:3315607/01/2023-05:22:20.017127 [**] [1:100002:1] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 103.152.178.181:80 -> 192.168.120.5:3315607/01/2023-05:22:20.017149 [**] [1:2013028:7] ET POLICY curl User-Agent Outbound [**] [Classification: Attempted Information Leak] [Priority: 2] {TCP} 192.168.120.5:33156 -> 103.152.178.181:8007/01/2023-05:22:20.017149 [**] [1:100002:1] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.120.5:33156 -> 103.152.178.181:8007/01/2023-05:22:20.017831 [**] [1:100002:1] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.120.5:33156 -> 103.152.178.181:8007/01/2023-05:22:20.018316 [**] [1:100002:1] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 103.152.178.181:80 -> 192.168.120.5:3315607/01/2023-05:22:20.018372 [**] [1:100002:1] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.120.5:33156 -> 103.152.178.181:80
$ cat /usr/local/var/log/suricata/eve.json | grep 100002{"timestamp":"2023-07-01T05:22:20.016863+0900","flow_id":435169198357210,"in_iface":"eth0","event_type":"alert","src_ip":"103.152.178.181","src_port":80,"dest_ip":"192.168.120.5","dest_port":33156,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":100002,"rev":1,"signature":"Access to himazin331.com","category":"","severity":3},"http":{"hostname":"himazin331.com","url":"/","http_user_agent":"curl/7.74.0","http_method":"GET","protocol":"HTTP/1.1","length":0},"app_proto":"http","flow":{"pkts_toserver":3,"pkts_toclient":2,"bytes_toserver":284,"bytes_toclient":140,"start":"2023-07-01T05:22:20.015066+0900"}}{"timestamp":"2023-07-01T05:22:20.017127+0900","flow_id":435169198357210,"in_iface":"eth0","event_type":"alert","src_ip":"103.152.178.181","src_port":80,"dest_ip":"192.168.120.5","dest_port":33156,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":100002,"rev":1,"signature":"Access to himazin331.com","category":"","severity":3},"http":{"hostname":"himazin331.com","url":"/","http_user_agent":"curl/7.74.0","http_method":"GET","protocol":"HTTP/1.1","length":0},"app_proto":"http","flow":{"pkts_toserver":3,"pkts_toclient":3,"bytes_toserver":284,"bytes_toclient":559,"start":"2023-07-01T05:22:20.015066+0900"}}{"timestamp":"2023-07-01T05:22:20.017149+0900","flow_id":435169198357210,"in_iface":"eth0","event_type":"alert","src_ip":"192.168.120.5","src_port":33156,"dest_ip":"103.152.178.181","dest_port":80,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":100002,"rev":1,"signature":"Access to himazin331.com","category":"","severity":3},"http":{"hostname":"himazin331.com","url":"/","http_user_agent":"curl/7.74.0","http_content_type":"text/html","http_method":"GET","protocol":"HTTP/1.1","status":301,"redirect":"https://himazin331.com/","length":162},"app_proto":"http","flow":{"pkts_toserver":4,"pkts_toclient":3,"bytes_toserver":350,"bytes_toclient":559,"start":"2023-07-01T05:22:20.015066+0900"}}{"timestamp":"2023-07-01T05:22:20.017831+0900","flow_id":435169198357210,"in_iface":"eth0","event_type":"alert","src_ip":"192.168.120.5","src_port":33156,"dest_ip":"103.152.178.181","dest_port":80,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":100002,"rev":1,"signature":"Access to himazin331.com","category":"","severity":3},"http":{"hostname":"himazin331.com","url":"/","http_user_agent":"curl/7.74.0","http_content_type":"text/html","http_method":"GET","protocol":"HTTP/1.1","status":301,"redirect":"https://himazin331.com/","length":162},"app_proto":"http","flow":{"pkts_toserver":5,"pkts_toclient":3,"bytes_toserver":416,"bytes_toclient":559,"start":"2023-07-01T05:22:20.015066+0900"}}{"timestamp":"2023-07-01T05:22:20.018316+0900","flow_id":435169198357210,"in_iface":"eth0","event_type":"alert","src_ip":"103.152.178.181","src_port":80,"dest_ip":"192.168.120.5","dest_port":33156,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":100002,"rev":1,"signature":"Access to himazin331.com","category":"","severity":3},"http":{"hostname":"himazin331.com","url":"/","http_user_agent":"curl/7.74.0","http_content_type":"text/html","http_method":"GET","protocol":"HTTP/1.1","status":301,"redirect":"https://himazin331.com/","length":162},"files":[{"filename":"/","sid":[],"gaps":false,"state":"CLOSED","stored":false,"size":162,"tx_id":0}],"app_proto":"http","flow":{"pkts_toserver":5,"pkts_toclient":4,"bytes_toserver":416,"bytes_toclient":625,"start":"2023-07-01T05:22:20.015066+0900"}}{"timestamp":"2023-07-01T05:22:20.018372+0900","flow_id":435169198357210,"in_iface":"eth0","event_type":"alert","src_ip":"192.168.120.5","src_port":33156,"dest_ip":"103.152.178.181","dest_port":80,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":100002,"rev":1,"signature":"Access to himazin331.com","category":"","severity":3},"http":{},"app_proto":"http","flow":{"pkts_toserver":6,"pkts_toclient":4,"bytes_toserver":482,"bytes_toclient":625,"start":"2023-07-01T05:22:20.015066+0900"}}
次にもう少し実際の運用に近づけて、any
(すべての通信)とするのではなくホームネットワークに限ったルールに変更してみましょう。
suricata.yamlを開き、HOME_NET
を192.168.120.0/24
として定義します。
$ sudo vi /usr/local/etc/suricata/suricata.yaml
vars:# more specific is better for alert accuracy and performanceaddress-groups:#HOME_NET: "[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]" # comment outHOME_NET: "[192.168.120.0/24]" # edit#HOME_NET: "[10.0.0.0/8]"#HOME_NET: "[172.16.0.0/12]"#HOME_NET: "any"
次にカスタムルールを変更します。
$ sudo vim /usr/local/var/lib/suricata/rules/user_custom.rules
alert icmp any any -> $HOME_NET any (msg: "ICMP ping detected from external network"; sid: 100001; rev: 2;)alert http $HOME_NET any -> any any (msg: "Access to himazin331.com"; http.host; content: "himazin331.com"; sid: 100002; rev: 2;)
最後に更新を忘れずに。
$ sudo suricata-update
$ sudo suricata -c /usr/local/etc/suricata/suricata.yaml -i eth0 -i wlan0 -v
操作は先程と同様なので簡易的に記述します。
PC: 192.168.1.9 ---> Rasp Pi: 192.168.1.6
アラート数が0となっています。^C1/7/2023 -- 05:36:32 - <Notice> - Signal Received. Stopping engine.1/7/2023 -- 05:36:33 - <Info> - time elapsed 14.521s1/7/2023 -- 05:36:34 - <Info> - Alerts: 01/7/2023 -- 05:36:35 - <Info> - cleaning up signature grouping structure... complete
PC: 192.168.120.3 ---> Rasp Pi: 192.168.120.5
アラート数が2となっています。^C1/7/2023 -- 05:37:32 - <Notice> - Signal Received. Stopping engine.1/7/2023 -- 05:37:32 - <Info> - time elapsed 14.525s1/7/2023 -- 05:37:33 - <Info> - Alerts: 21/7/2023 -- 05:37:34 - <Info> - cleaning up signature grouping structure... complete
192.168.120.0/24
のネットワークでのみ、ルールが適用されアラートが出力されていることが確認できました。
PC: 192.168.1.9 ---> himazin331.com: 103.152.178.181
ICMP通信のルールはこのケースだと除外されないのでアラートが出力されますが、HTTP通信のルールには適用されずアラートは出力されません。^C1/7/2023 -- 05:39:16 - <Notice> - Signal Received. Stopping engine.1/7/2023 -- 05:39:16 - <Info> - time elapsed 15.893s1/7/2023 -- 05:39:17 - <Info> - Alerts: 11/7/2023 -- 05:39:18 - <Info> - cleaning up signature grouping structure... complete$ cat /usr/local/var/log/suricata/fast.log07/01/2023-05:39:13.242902 [**] [1:100001:2] ICMP ping detected from external network [**] [Classification: (null)] [Priority: 3] {ICMP} 192.168.120.1:3 -> 192.168.120.5:3
PC: 192.168.120.3 ---> himazin331.com: 103.152.178.181
こちらは期待通り、HTTP通信のルールが適用されてアラートが出力されました。^C1/7/2023 -- 05:41:27 - <Notice> - Signal Received. Stopping engine.1/7/2023 -- 05:41:27 - <Info> - time elapsed 16.617s1/7/2023 -- 05:41:28 - <Info> - Alerts: 51/7/2023 -- 05:41:29 - <Info> - cleaning up signature grouping structure... complete$ cat /usr/local/var/log/suricata/fast.log07/01/2023-05:41:15.925092 [**] [1:100001:2] ICMP ping detected from external network [**] [Classification: (null)] [Priority: 3] {ICMP} 192.168.120.1:3 -> 192.168.120.5:307/01/2023-05:41:15.974681 [**] [1:2013028:7] ET POLICY curl User-Agent Outbound [**] [Classification: Attempted Information Leak] [Priority: 2] {TCP} 192.168.120.5:42754 -> 103.152.178.181:8007/01/2023-05:41:15.974681 [**] [1:100002:2] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.120.5:42754 -> 103.152.178.181:8007/01/2023-05:41:15.976533 [**] [1:100002:2] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.120.5:42754 -> 103.152.178.181:8007/01/2023-05:41:15.977208 [**] [1:100002:2] Access to himazin331.com [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.120.5:42754 -> 103.152.178.181:80
いかがでしたか?ラズパイにSuricataを入れて動かしてみました。
今回は、とても簡単なルールにとても簡単なネットワーク構成でしたが、Suricataはもっと高度なルールを作成できますし、より詳細なログを出力が可能です。
例えば、本記事中でHTTP通信のパケット情報がeve.jsonに記載されていましたが、パケットのmetadataを出力することもでき、HTTP Request/Response Bodyも確認できます。
また、監視インターフェースをプロミスキャスモードでアップすることで、同一ネットワーク上の通信を監視することもできます。というかそれができてIDSです。
このRaspberry PiとSuricataのお話は今後も何回か書こうと思います。
現時点では、Suricataがアラートを発報したらラズパイのGPIOでLEDを点灯させてみるとか、Suricataが出力したeve.jsonをElasticsearchやらの分析ツールに食わせて統計データとして眺めてみるとかやろうかなと考えています。