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 で運用し、誤検知を潰してから遮断に進む

お気軽にご相談ください

お見積りへ お問い合わせへ
▲