ファイアウォールの先へ:パケットインスペクションが重要な理由
ITの世界でよくある誤解は、サーバーのセキュリティには強固なファイアウォールさえあれば十分だというものです。私も、ある公開Webサーバーを管理するまではそう信じていました。そのサーバーでは、わずか2時間の間に4,500回以上のSSHログイン試行失敗が記録されていたのです。鍵認証を使用していたとはいえ、その膨大なノイズは警鐘となりました。その時、ファイアウォールは単なる「施錠されたドア」に過ぎないのだと気づきました。誰がドアの取っ手を回そうとしているのか、どんな道具を使っているのかを実際に知るには、内部に「探偵」が必要なのです。
UFWやIPTablesのような標準的なファイアウォールは、接続レベルで動作します。IPアドレスやポートに基づいてトラフィックを遮断または許可しますが、パケットの中に隠された悪意のあるペイロードまでは見ることができません。そこで、ネットワーク侵入検知システム(NIDS)であるSnort 3が不可欠になります。Snort 3は高速アナライザーとして機能し、ライブトラフィックを既知の攻撃シグネチャのライブラリと比較することで、ファイアウォールがすり抜けてしまう脅威を捕らえます。
Snort 3:モダンなセキュリティエンジン
Snort 3(別名Snort++)は、従来のSnort 2を根本から書き直したものです。先代とは異なり、このバージョンはマルチスレッド化されています。このアーキテクチャにより、最新のマルチコアCPU全体でスケーリングが可能になり、パケットをドロップすることなく1Gbps以上のリンクを監視できます。また、古くて硬直的だった設定ファイルは、柔軟なLuaベースのシステムに置き換えられました。
NIDS vs. IPS:戦略の選択
インストールを始める前に、Snortをネットワークとどのように連携させるかを決める必要があります。
- NIDS(検知):Snortはトラフィックのミラーを監視します。脅威を発見するとアラートを送信しますが、通信の流れを妨げることはありません。これは導入として最も安全な方法です。
- IPS(防御):Snortはトラフィックの経路に直接配置されます。SQLインジェクションなどのシグネチャを特定すると、即座にパケットを破棄します。
今回のセットアップではNIDSモードに焦点を当てます。これにより、過度に攻撃的なルールによって誤って自らの通信を遮断してしまうトラブルを防ぐことができます。
ステップバイステップの実装手順
1. 環境の準備
Snort 3をソースからコンパイルすることは、最新のパフォーマンス最適化を確実に適用するための最良の方法です。単純な apt install よりも時間はかかりますが、より高速なパターンマッチングのためのHyperscanなどの機能を有効にできます。まずは、必要なビルドツールと依存関係をインストールしましょう。
sudo apt update && sudo apt upgrade -y
sudo apt install -y build-essential autotools-dev libdumbnet-dev libluajit-5.1-dev \
libpcap-dev zlib1g-dev libpcre3-dev libhwloc-dev cmake libssl-dev \
pkg-config liblzma-dev python3-pip uuid-dev libunwind-dev libhyperscan-dev flex bison
2. LibDAQのインストール
Data Acquisitionライブラリ(DAQ)は、Snortとネットワークカードの間の架け橋として機能します。Snort 3でマルチスレッドのトラフィック処理を行うには、モダンなバージョンのDAQが必要です。
mkdir ~/snort_src && cd ~/snort_src
git clone https://github.com/snort3/libdaq.git
cd libdaq
./bootstrap
./configure
make
sudo make install
sudo ldconfig
3. パフォーマンス調整を伴うSnort 3のコンパイル
いよいよコアのインストールです。高負荷環境下でSnortのパフォーマンスを10〜15%向上させることができるメモリ割り当てプログラム、tcmalloc を有効にします。
cd ~/snort_src
git clone https://github.com/snort3/snort3.git
cd snort3
./configure_cmake.sh --prefix=/usr/local --enable-tcmalloc
cd build
make -j$(nproc)
sudo make install
以下のコマンドを実行して、バイナリが動作していることを確認します:
/usr/local/bin/snort -V
4. プロミスキャスモードの有効化
標準的なインターフェースは、自分宛てのパケットのみを処理します。回線上のすべてのトラフィックを検査するには、インターフェースをプロミスキャスモードにする必要があります。eth0 を実際のインターフェース名に置き換えてください。
sudo ip link set dev eth0 promisc on
この設定は再起動後にリセットされることに注意してください。本番環境では、systemdサービスやnetplanの設定を通じてこれを自動化する必要があります。
5. 初めての検知ルールの作成
Snortの検知ロジックはルールによって定義されます。エンジンをテストするために、ローカルルールファイルを作成します。このシンプルなルールは、ICMPエコーリクエスト(ping)がサーバーに到達するたびにアラートを発生させます。
sudo mkdir -p /usr/local/etc/rules
sudo nano /usr/local/etc/rules/local.rules
ファイルに以下の行を追加します:
alert icmp any any -> any any (msg:"ICMP Pingを検知しました"; sid:1000001; rev:1;)
このルールの構成は以下の通りです:
- alert:条件が満たされたときにSnortが実行するアクション。
- icmp:検査対象のプロトコル。
- any any -> any any:任意の送信元IP・ポートから、任意の宛先への通信を対象にします。
- sid:Snort ID。カスタムルールには、公式ルールセットとの競合を避けるために1,000,000以上のIDを使用する必要があります。
6. Lua設定へのルールの統合
ルールを作成したら、Snortにその場所を教える必要があります。Lua構文で記述されたメイン設定ファイルを開きます。
sudo nano /usr/local/etc/snort/snort.lua
ips テーブルを探し、新しいファイルのパスを追加します:
ips =
{
include = '/usr/local/etc/rules/local.rules'
}
7. 検知エンジンのテスト
alert_fast 出力プラグインを使用して、Snortをフォアグラウンドで実行します。これにより、アラートがターミナルにリアルタイムで表示されます。
sudo snort -c /usr/local/etc/snort/snort.lua -i eth0 -A alert_fast
別のマシンからSnortサーバーにpingを送信します。ターミナルに以下のようなアラートが即座に表示されるはずです:
11/15-09:10:45.654321 [**] [1:1000001:1] "ICMP Pingを検知しました" [**] [Priority: 0] {ICMP} 192.168.1.15 -> 192.168.1.100
実際の脆弱性攻撃の検知
基本的なpingが検知できたら、実際の脅威に対するルールを書くことができます。例えば、Webブラウザ経由でシステムのパスワードファイルを読み取ろうとする攻撃者を捕らえるには、以下のルールを使用します:
alert tcp any any -> any 80 (msg:"ディレクトリトラバーサルの可能性"; content:"/etc/passwd"; nocase; sid:1000002;)
このルールは、すべてのHTTPリクエストのデータペイロードをスキャンし、”/etc/passwd” という文字列を探します。このような可視性の高さこそが、Snortがセキュリティオペレーションセンター(SOC)で重宝される理由です。
次のステップ
NIDSを運用することで、ファイアウォールでは不可能な、ネットワークの健全性に関する詳細な洞察を得ることができます。これで、高性能エンジンのコンパイルとカスタム検知ロジックの実装が完了しました。
本番環境レベルのセットアップに移行するための次のタスクは、Snortをバックグラウンドサービスとして実行し、これらのアラートをGrafanaやELKスタックなどの可視化ツールに送ることです。セキュリティは、観察と改善の絶え間ないサイクルです。トラフィックを監視することで、最終的にデータ侵害につながる異常をいち早く察知することができるのです。

