クラウドインテグレーション部の渡邊です。
本記事のシリーズでは、サーバの構築・運用に最低限必要なセキュリティの体系的知識習得を目的としています。
本シリーズの全体像と今回執筆の内容の位置づけは以下の通りです。
IDPS(Intrusion Detection and Prevention System)とは、侵入検知システム(IDS)と侵入防止システム(IPS)の両方を総称したシステムです。
IDPSの目的はインシデントと考えられるイベントの特定や阻止などが挙げられます。
システムの侵害に成功された場合の、IDPSの流れの一例は以下の通りです。
このように、侵入の阻止に失敗したとしても、検知および通知することによって、セキュリティ管理者が早期にインシデントに対する対応を行うことができます。
早期なインシデントの対応によって、被害を最小限に抑えることができるため、IDPSはセキュリティ面で重要なシステムであることがわかるかと思います。
また、IPS / IDS の個別の説明も以下に記載します。
侵入検知システム(IDS:Intrusion Detection System)とは、侵入を検知し管理者に通知するシステムを指します。
一方で、侵入防止システム(IPS:Intrusion Prevention System)とは、侵入を検知し管理者に通知するシステムに加え、侵入を遮断するシステムを指します。
IDSテクノロジーとIPSテクノロジーは共通の機能が多いです。
また、IPS製品は通常、侵入防止機能を無効にしてIDSとして使用することもできます。
IDPSテクノロジーは4種類に分類できます。
ネットワークやホストベースのIDPSは有名ですが、比較的新しい種類として、無線やNBAを利用したIDPSがあることも覚えておきましょう。
今回のデモで使用する、SuricataとSnortはホスト型のIDPSとして動作させます。
IDPS テクノロジー種類 | 説明 |
---|---|
ネットワークベース | ネットワークセグメントやネットワーク装置のトラフィックを監視し、疑わしい活動を特定 |
無線 | 無線ネットワークのトラフィックを監視・解析し、無線ネットワークプロトコルの疑わしい活動を特定 |
ネットワーク挙動解析(NBA:Network Behavior Analysis) | ネットワークトラフィックを監視し通常と異なるトラフィックフローを生成する疑わしい活動を特定 |
ホストベース | サーバまたはその他のホスト上で発生するイベントを監視し疑わしい活動を特定 |
IDPSが備えている検知機能は3つに分類できます。
概要や簡単な説明を記載します。
②については正常な挙動をプロファイルで表現します。
アノマリはトレーニング期間が必要であり、導入後すぐ機能するわけではないです。
また、悪意ある活動内容を正常として記録しないように注意する必要があります。
③については、ソフトウェアベンダーや標準化機関がプロトコルモデルを提供しています。
処理のオーバーヘッドが大きいため、リソースの消費が多いです。
一般的なプロトコルの動作から外れていない、DoS攻撃などを検知できない点も注意する必要があります。
IPSは脅威に対して阻止するという点で、IDSと異なります。
本項ではその点について言及します。
IPSの脅威への対応方法として、3つに分類できます。
分類とその例について以下にまとめます。
②は製品によっては、脆弱性を検知した場合にパッチ適用するようなものもあるようです。
③は電子メールにおけるマルウェアに感染した添付ファイルの削除や、プロキシによるヘッダーの置換が挙げられます。
IDPS製品は多数あるため、選定の際に、基準を設ける必要があります。
本章では、以下5つの観点における基準を紹介します。
IDPSは製品によって検知の正確さ、カスタマイズ機能等の内容が大きく異なります。
そのため、IDPS製品で満たしておきたい要件をあらかじめ定義する必要があります。
たとえば、以下が挙げられます。
これらを参考に、製品が要件を満たしているかを検討する必要があります。
必要なセキュリティ機能を備えているかの観点から製品を比較する。
IDPS製品のパフォーマンスを比較することは、以下のような理由から困難です。
よって、部分的な評価ではなく、全体的なパフォーマンス特性に主眼を置き製品を比較することをオススメします。
管理においては以下5つの選定基準があります。
各基準内に具体的な内容を一部抜粋して紹介しております。
ライフサイクルコスト(初期コスト・保守コスト)と予算を比較する必要があります。
ここでは、有名なIDPSのOSSであるSnortとSuricataを利用してIDSおよびIPSの動作確認を行います。
Snortによる侵入検知を動作確認します。
実行結果が長いこともあり基本的に実施したコマンドのみ記載します。
また、本手順はrootユーザによって実行しています。
公式のインストール手順を参考に、必要なパッケージをパッケージ管理ツールまたはソースからインストールしてSnortをインストールします。
amazon-linux-extras install epel
yum -y install gcc flex bison pcre-devel libdnet libdnet-devel zlib zlib-devel luajit-devel.x86_64 openssl-devel.x86_64
cd /usr/local/src/
wget http://www.tcpdump.org/release/libpcap-1.9.1.tar.gz
tar xzvf libpcap-1.9.1.tar.gz
cd libpcap-1.9.1
./configure
make
make install
cd /usr/local/src/
wget https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.tar.gz
tar xzvf pcre2-10.42.tar.gz
cd pcre2-10.42
./configure
make
make install
cd /usr/local/src/
wget https://www.snort.org/downloads/snort/daq-2.0.7.tar.gz
tar xzvf daq-2.0.7.tar.gz
cd daq-2.0.7
./configure
make
make install
export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
cd /usr/local/src/
wget https://www.snort.org/downloads/snort/snort-2.9.20.tar.gz
tar xzvf snort-2.9.20.tar.gz
cd snort-2.9.20
./configure
make
make install
途中でPATHの環境変数を追加していますが、daq-modules-configが配置されている/usr/local/binがパスとして通っていなかったため、追加しています。
追加しないと、Snortのconfigure
を実行する際に以下エラーが発生しました。
./configure: line 16279: daq-modules-config: command not found
以上の手順を実行すると、以下のようにインストールに成功します。
[root@ip-10-0-1-168 src]# snort -V
,,_ -*> Snort! <*-
o" )~ Version 2.9.20 GRE (Build 82)
'''' By Martin Roesch & The Snort Team: http://www.snort.org/contact#team
Copyright (C) 2014-2022 Cisco and/or its affiliates. All rights reserved.
Copyright (C) 1998-2013 Sourcefire, Inc., et al.
Using libpcap version 1.9.1 (with TPACKET_V3)
Using PCRE version: 8.32 2012-11-30
Using ZLIB version: 1.2.7
必要なディレクトリやファイルおよび各権限設定を行います。
スティッキービットとSUIDが付与されているため、一部ディレクトリのパーミッションの値が5775となっていますね。(パーミッションについては、Linux × Security 権限の制御編を参考)
#グループ作成
groupadd snort
#ユーザ作成
useradd snort -r -s /sbin/nologin -c SNORT_IDS -g snort
#ディレクトリ作成
mkdir -p /etc/snort/rules
mkdir /var/log/snort
mkdir /usr/local/lib/snort_dynamicrules
#権限付与
chmod -R 5775 /etc/snort
chmod -R 5775 /var/log/snort
chmod -R 5775 /usr/local/lib/snort_dynamicrules
chown -R snort:snort /etc/snort
chown -R snort:snort /var/log/snort
chown -R snort:snort /usr/local/lib/snort_dynamicrules
#ファイル作成
touch /etc/snort/rules/white_list.rules
touch /etc/snort/rules/black_list.rules
touch /etc/snort/rules/local.rules
#設定ファイルのコピー
cp /usr/local/src/snort-2.9.20/etc/*.conf* /etc/snort
cp /usr/local/src/snort-2.9.20/etc/*.map /etc/snort
Snortではシグネチャを参照して不正なパケットを検出するため、ルールセットを参照します。
今回、そのルールセットはローカルで定義しているもの(ローカルルール)とコミュニティが提供しているもの(コミュニティルール)を使用します。
今回はicmp
コマンドによるIDSの動作確認のため、ローカルルールで事足ります。
しかし、より洗練されたルールを設定する場合は、コミュニティルールなどを利用する方が実践的です。
Oinkmasterは、Snortのルールセットを自動更新するためのツールです。
Oinkmaster用にoinkcodeを発行する必要があります。oinkcode=
以降でマスクされているところを、発行されたoinkcodeで置換してください。
#コミュニティルールのインストール
cd /usr/local/src/
wget https://www.snort.org/rules/community -O ~/community.tar.gz
tar -xvf ~/community.tar.gz -C ~/
cp ~/community-rules/* /etc/snort/rules
sed -i 's/include \$RULE\_PATH/#include \$RULE\_PATH/' /etc/snort/snort.conf
#Oinkmasterのインストール
cd /usr/local/src/
wget https://www.snort.org/rules/snortrules-snapshot-2983.tar.gz?oinkcode=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -O ~/registered.tar.gz
tar -xvf ~/registered.tar.gz -C /etc/snort
設定ファイルやlocalルールを編集および適用します。/etc/snort/snort.conf
ファイルを修正します。diff
コマンドで事前に保存した修正前のファイル/etc/snort/snort.conf_bk
と修正後の/etc/snort/snort.conf
の差分を以下に示します。
修正・追記した点は、おおむね以下の通りです。
[root@ip-10-0-1-168 src]# diff /etc/snort/snort.conf{,_bk}
45c45
< ipvar HOME_NET ${snortのサーバIP}/32
---
> ipvar HOME_NET any
50c50
< var WHITE_LIST_PATH /etc/snort/rules
< var BLACK_LIST_PATH /etc/snort/rules
---
> var WHITE_LIST_PATH ../rules
> var BLACK_LIST_PATH ../rules
512c506
< blacklist $BLACK_LIST_PATH/black_list.rules
---
> blacklist $BLACK_LIST_PATH/black_list.rules
524,525d516
< include $RULE_PATH/local.rules
< include $RULE_PATH/community.rules
設定ファイルを適用を実施します。
snort -T -c /etc/snort/snort.conf
ローカルルールを編集します。ルールファイル/etc/snort/rules/local.rules
作成後に以下の内容を記述してください。
alert icmp any any -> any any (msg: "ICMP Packet detected"; sid:999999;)
SnortをSystemdを使ってサービス化します。/lib/systemd/system/snort.service
作成後に以下の内容を記述してください。
[Unit]
Description=Snort NIDS Daemon
After=syslog.target network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/snort -u snort -g snort -c /etc/snort/snort.conf -i eth0 -A full -b -D
[Install]
WantedBy=multi-user.target
最後にSystemdのデーモンを再読み込みしてSnortを起動しましょう。
#設定反映
systemctl daemon-reload
#snort起動
systemctl start snort
Snortが起動しているか確認します。
[root@ip-10-0-1-168 src]# systemctl status snort
● snort.service - Snort NIDS Daemon
Loaded: loaded (/usr/lib/systemd/system/snort.service; disabled; vendor preset: disabled)
Active: active (running) since 水 2023-11-01 06:23:00 UTC; 47ms ago
Main PID: 9327 (snort)
CGroup: /system.slice/snort.service
└─9327 /usr/local/bin/snort -u snort -g snort -c /etc/snort/snort....
11月 01 06:23:00 ip-10-0-1-168.ap-northeast-1.compute.internal snort[9327]: ...
11月 01 06:23:00 ip-10-0-1-168.ap-northeast-1.compute.internal snort[9327]: ...
11月 01 06:23:00 ip-10-0-1-168.ap-northeast-1.compute.internal snort[9327]: ...
11月 01 06:23:00 ip-10-0-1-168.ap-northeast-1.compute.internal snort[9327]: ...
11月 01 06:23:00 ip-10-0-1-168.ap-northeast-1.compute.internal snort[9327]: ...
11月 01 06:23:00 ip-10-0-1-168.ap-northeast-1.compute.internal snort[9327]: ...
11月 01 06:23:00 ip-10-0-1-168.ap-northeast-1.compute.internal snort[9327]: ...
11月 01 06:23:00 ip-10-0-1-168.ap-northeast-1.compute.internal snort[9327]: ...
11月 01 06:23:00 ip-10-0-1-168.ap-northeast-1.compute.internal snort[9327]: ...
11月 01 06:23:00 ip-10-0-1-168.ap-northeast-1.compute.internal snort[9327]: ...
Hint: Some lines were ellipsized, use -l to show in full.
外部からSnortのIPアドレスにping
コマンドを実行してみましょう。
以下コマンドで待機していると、検知してログ出力がされていることがわかります。
[root@ip-10-0-1-168 src]# tail -f /var/log/snort/alert
[**] [1:999999:0] ICMP Packet detected [**]
[Priority: 0]
11/01-06:23:09.816112 XXX.XXX.XXX.XXX -> 10.0.1.168
ICMP TTL:50 TOS:0x0 ID:42220 IpLen:20 DgmLen:84
Type:8 Code:0 ID:41482 Seq:0 ECHO
[**] [1:999999:0] ICMP Packet detected [**]
[Priority: 0]
11/01-06:23:09.816147 10.0.1.168 -> XXX.XXX.XXX.XXX
ICMP TTL:255 TOS:0x0 ID:56432 IpLen:20 DgmLen:84
Type:0 Code:0 ID:41482 Seq:0 ECHO REPLY
Suricata互換の侵入防止ルールによる侵入防止の動作確認をします。
Suricataのパッケージは、EPELリポジトリに含まれているため、yum
コマンドでインストールします。
amazon-linux-extras install epel
yum -y update
yum -y install suricata
以上の手順を実行すると、以下のようにインストールに成功します。
[root@ip-10-0-1-254 ec2-user]# suricata -V
This is Suricata version 4.1.10 RELEASE
設定のために/etc/suricata/suricata.yaml
の以下の部分を修正します。
rule-files:
# - suricata.rules #コメントアウト
- local.rules #追記
detect-engine: #追記
- rule-reload: true #追記
こちらでもルールファイルの作成およびルール設定を行います。ルール用のディレクトリ作成しておきましょう。
mkdir /var/lib/suricata/rules
ローカルルールを編集します。/var/lib/suricata/rules/local.rules
作成後に以下の内容を記述してください。
drop icmp any any -> any any (msg:"ping drop AQ test"; sid:200000; rev:1;)
サービスを再起動して、ステータスを確認してみます。
systemctl restart suricata.service
systemctl status suricata.service
この時点ではIPSとして動作しないです。
試しに外部からping
コマンドを実施してみると疎通が確認できるはずです。
遮断動作をするためにNetfilter(iptables)と連携する必要があります。
ただ、以下のコマンドで待機すると、ログが取得できるためIDSとしては動作しています。
tail -f -n 1 /var/log/suricata/fast.log
ちなみに、自身のグローバルIPアドレスは以下コマンドで確認できます。
curl http://ifconfig.me/
以下のように、NFQUEUEの設定をして動作確認をすると、ログの取得もされ、遮断動作も確認できるはずです。
#nftableの設定
sudo iptables -I INPUT -p icmp -j NFQUEUE
iptablesのルールが追加されているか確認します。
[root@ip-10-0-1-254 ec2-user]# iptables -L --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 NFQUEUE icmp -- anywhere anywhere NFQUEUE num 0
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
外部からSnortのIPアドレスにping
コマンドを実行してみましょう。
以下コマンドで待機すると、IPSの遮断動作と検知動作が確認できます。
遮断動作
$ ping ${suricataのサーバIP}
PING XXX.XXX.XXX.XXX (XXX.XXX.XXX.XXX): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
検知動作
[root@ip-10-0-1-254 ec2-user]# tail -f -n 1 /var/log/suricata/fast.log
11/01/2023-06:46:29.973677 [wDrop] [**] [1:200000:1] ping drop AQ test [**] [Classification: (null)] [Priority: 3] {ICMP} XXX.XXX.XXX.XXX:8 -> 10.0.1.254:0
本シリーズはこちらをもって終了です。最後までありがとうございました!
【参考】