2026年6月4日
2026年6月4日
Snortでルールを作成する方法:書式・local.rulesへの追加・テストまで
Snortの独自ルールは「ヘッダー(何を・どこからどこへ)」と「オプション(何に一致したら、どう記録するか)」の2つで書き、local.rules にまとめて設定ファイルから読み込みます。書いたら構文チェックとpcapでの再生テストを通してから本番に入れる、という順番を守れば、検知漏れや誤検知を早い段階で見つけられます。この記事では、Snort 3を前提にルールの書式、WordPressを例にした実用的なルール、テストと運用のつまずきどころまでを説明します。
前提:Snort 3とSnort 2の違い
現在の主流はSnort 3です(2026年10月現在)。Snort 2系の公式サポートは縮小しており、新しく導入するならSnort 3を選ぶのが無難です。両者はルールの基本形は同じですが、次の点が違います。
- 設定ファイルが snort.conf から Lua形式の snort.lua に変わった
- HTTPのURIやヘッダーを指定する書き方が「修飾子」から「スティッキーバッファ」に変わった(後述)
- Snort 3ではルールの括弧の中を複数行に分けて書ける(Snort 2では行末に
\が必要)
ネット上の解説はSnort 2の書式で書かれたものがまだ多いため、コピーする前にどちらの書式かを確認してください。
ルールの基本構造
ルールは1本で1つの検知条件を表します。最小の例です。
alert icmp any any -> $HOME_NET any (msg:"LOCAL ICMP echo request"; itype:8; sid:1000001; rev:1;)
括弧より前がヘッダー、括弧の中がオプションです。
ヘッダー
ヘッダーは「アクション プロトコル 送信元IP 送信元ポート 方向 宛先IP 宛先ポート」の順に並べます。
- アクション: まずは
alert(検知して記録)で書きます。dropやrejectはSnortをインライン(通信の経路上)で動かしているときだけ意味があり、監視専用の構成では通信を止められません - プロトコル:
tcp、udp、icmp、ipなど。Snort 3ではhttpのようにサービス名で書く書式もあります - IPとポート:
any、192.0.2.0/24、$HOME_NETのような変数が使えます。変数は snort.lua(またはそこから読み込む既定値のファイル)で定義します - 方向:
->は一方向、<>は双方向です
$HOME_NET を any のままにしている環境はよくあります。これでは内外の区別がつかず、ルールの意味が変わるので、最初に自分のネットワークの範囲を設定してください。
オプション
オプションは キー:値; の形で並べ、最後のセミコロンも省略しません。よく使うものは次のとおりです。
msg: アラートに表示される説明。後でログを読む人が分かる文にしますsid: ルールの識別番号。1,000,000未満は配布ルール用に予約されているので、独自ルールは1000001以降を使いますrev: ルールの改訂番号。内容を変えたら1つ上げますcontent: パケットの中身に含まれる文字列。nocaseで大文字小文字を区別しませんflow:to_server,establishedのように、通信の向きと状態を絞りますclasstype: 分類。重要度の初期値にも影響します
WordPressを例にしたルール
例:wp-login.phpへのPOSTの集中を検知する
ログイン画面への総当たりを、同じ送信元からの短時間の集中で検知する例です。
alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS (
msg:"LOCAL WordPress wp-login.php POST burst";
flow:to_server,established;
http_method; content:"POST";
http_uri; content:"/wp-login.php", nocase;
detection_filter:track by_src, count 10, seconds 60;
classtype:attempted-user;
sid:1000010; rev:1;
)
http_method; や http_uri; がスティッキーバッファで、その後ろの content を「メソッド」「URI」の範囲で照合するという意味です。Snort 2では content:"/wp-login.php"; http_uri; のように後ろに修飾子を付けていました。detection_filter は「同じ送信元から60秒間に10回を超えたら」アラートを出す条件です。
HTTPSの通信は中身が見えない
ここが最もつまずきやすい点です。Snortは暗号化された通信の中身を読めません。サイトがHTTPSで、Snortがインターネットとサーバーの間にいるなら、上のルールのURIの照合は一致しません。
対策は構成によって変わります。
- ロードバランサーやリバースプロキシでTLSを終端し、その後ろの平文区間をSnortで監視する
- 中身ではなく、接続数やポート、送信元IPなどのヘッダー情報で書けるルールに限る
- アプリケーション層の検知は、WAFやサーバーのログ(アクセスログ、fail2ban など)に任せる
どの区間の通信をSnortが見ているかを図に描いてから、ルールの方針を決めると無駄がありません。
高速に動くルールにするコツ
contentを最低1つ入れる。Snortはcontentで候補を絞ってから細かい条件を調べるので、pcreだけのルールは重くなります- 長く、珍しい文字列を
contentに選ぶ。GETのような短い文字列だけでは、ほぼ全ての通信が候補になります flowで向きを絞る。応答側の通信まで調べる必要がないルールは多いです
local.rulesに追加して読み込む
独自ルールは配布ルールと別のファイル(例: local.rules)にまとめます。配布ルールの更新で上書きされるのを防ぎ、自分が書いたものを一覧できるようにするためです。
snort.lua の ips の設定で、ルールファイルを読み込みます。パスは環境に合わせて変えてください。
ips =
{
variables = default_variables,
include = '/usr/local/etc/rules/local.rules',
}
既に配布ルールを rules などで読み込んでいる場合は、その設定に local.rules を追加する形になります。どこで何を読み込んでいるかは、変更前に設定ファイルをバックアップしてから確認してください。
テストする
1. 構文チェック
設定とルールを読み込めるかを、本番の起動前に確認します。
snort -c /usr/local/etc/snort/snort.lua -T
エラーが出たら、表示された行番号のルールを見ます。多いのは、セミコロンの付け忘れ、引用符の閉じ忘れ、sidの重複です。
2. pcapで再生して一致を確かめる
本番の通信で試す前に、検知させたい通信を記録したpcapファイルで確かめます。テスト用の環境でアクセスを発生させ、tcpdump で保存しておきます。
sudo tcpdump -i eth0 -w test.pcap port 80
snort -c /usr/local/etc/snort/snort.lua -R /usr/local/etc/rules/local.rules \
-r test.pcap -A alert_fast -k none
-r でpcapを読み込み、-A alert_fast でアラートを1行ずつ画面に出します。-k none はチェックサムの検証を省く指定で、ネットワークカードの機能でチェックサムが後付けされる環境で記録したpcapでも検知できるようにします。
確認するのは2点です。検知させたい通信でアラートが出ること、そして普段の正常な通信(管理画面の操作やプラグインの更新など)で出ないことです。後者を確かめずに本番に入れると、誤検知のアラートが大量に出て、本当の異常が埋もれます。
3. 本番に入れたら最初はalertで様子を見る
インライン構成でも、最初は alert で数日動かし、件数と内容を見てから drop に切り替えます。正常な利用者を止めてしまう誤検知は、検知だけの段階で見つけておきます。
運用でのつまずきどころ
- ルールの更新と独自ルールの衝突: 配布ルール(Talosのルールなど)は PulledPork 3 などのツールで更新するのが一般的です。独自ルールは別ファイルにしておけば更新で消えません
- sidの管理: 誰がいつ何のために書いたかを、
msgと別の記録(Gitなど)で残します。revを上げずに内容を変えると、ログの読み手が混乱します - 誤検知の抑制: 特定のIPだけ除外したいときは、ルールを書き換える前に、Snortの抑制(suppress)の設定で対応できないかを検討します
- ログの量: アラートが多すぎる場合、ルールの条件を絞るか、
detection_filterなどで出し方を調整します
まとめ
- ルールはヘッダー(アクション・プロトコル・IP・ポート・方向)とオプション(msg・content・sid・rev など)で書く。独自ルールのsidは1000001以降
- Snort 3ではスティッキーバッファで照合範囲を指定する。Snort 2の書式と混ぜない
- HTTPSの中身は見えないため、Snortが監視する区間を先に決めてからルールを書く
-Tで構文チェック、pcapの再生で「検知すべきものが検知され、正常な通信では出ない」ことを確かめてから本番に入れる- 本番では最初は alert で運用し、誤検知を潰してから遮断に進む