extractorでは、Graylogのインタフェースを使って、ログの分解などの設定を行うことができます。一方でpipelineには、そのようなインタフェースはありません。代わりに、Droolsと呼ばれるルールエンジンのルールを記述して、ログを操作します。
13.1. pipelineの概要
pipelineは、メッセージに適用されるルールのまとまりのことを指す言葉です。
イメージは次の通りです。
pipelineは、1つ以上のstreamに接続できるため、各streamを流れるログをpipelineに通して、ルールを適用することができます。
ルールの構造を単純化すると、以下のように条件とアクションがあるだけです。
rule "function howto"
when
// 条件
// secret_idというフィールドが存在した場合
has_field("secret_id")
then
// アクション
// secret_idフィールドを削除する
remove_field("secret_id");
end
またルールはステージというまとまりで動きます。
ステージを移行する条件は2つあります。
- All rules on this stage match the message
- すべてのルールの条件がマッチした場合のみ、次のステージに進む
- At least one of the rules on this stage matches the message
- どれかひとつのルールにマッチした場合、次のステージに進む
上記の図では、便宜的にステージ1、ステージ2という番号を振っていますが、Graylogでは、ステージの番号は、優先順位を意味します。より若い番号が優先順位が高いことを意味します。
13.2. pipelineの作成
pipelineの設定は、メニューの Pipelines
リンクから移動した画面で行います。
pipelineを作成するには、以下の順で設定を行います。
- ルールの作成
- ルールとステージの紐付け
- pipelineとstreamの紐付け
13.2.1. ルールの作成
pipelineを作成する前にまずルールの作成を行います。
ルールは、pipeline処理の基礎です。ルールを使うことで、ログメッセージの変更や値の追加・削除、streamの切り替えを行うことができます。
ルールの中で行う、条件の一致や値の操作などは関数で行われます。Graylogには、文字列変換やJSONや日付形式の解析、正規表現やGrokパターンによる値の比較を行うための関数が付属しています。
さらに関数はプラグインで追加可能です。
ルールの作成は、メニューの Manage rules
リンクから移動した画面で行います。
Create Rule
ボタンをクリックするとルールの作成画面に移動します。
入力値は以下の通りです。
Title
: ルールの名前を指定します。
Description
: ルールの説明を入力します。
Rule Builder
: When
の欄では条件を指定します。 Then
の欄ではアクションを指定します。
Rule Simulation
: 左側で作成したルールのシュミレーションを行うことができます。
Use Source Code Editor
では手動でルール作成を行うことができます。
ルールの作成画面では、画面の左側が入力フォーム、右側が利用できる関数のリファレンスとルールの例になっています。
Description
にはルールの説明を入力します。
Rule source
については、以下で詳しく解説します。
13.2.2. ルールの定義
ルールの定義方法を次の例を使って解説します。
ルール1
rule "has firewall fields"
when
has_field("src_ip") && has_field("dst_ip")
then
end
ルール2
rule "from firewall subnet"
when
cidr_match("10.10.10.0/24", to_ip($message.gl2_remote_ip))
then
end
ルール3
rule "drop_message"
when
true
then
drop_message();
end
まず、 ルール1を見ていきます。
rule
の行で、ルールの名前を定義しています。この名前はルール全体で一意である必要があります。また次の when-then
の間では、ルールを適用する条件を定義しています。この条件は、 has_field
関数を使い、src_ipフィールドとdst_ipフィールドが存在するか検査しています。
続く then-end
には何も記載がありませんが、本来であれば、この間には条件にマッチしたログに対するアクションが記載できます。条件のみを定義した場合、そのルールは、pipelineの次のステージに進むかどうかの検査を行う役割になります。このように条件を細分化しておくことで、後々同じようなルールのときに再利用できるメリットがあります。
ルール2もルール1と基本的な構造は変わりません。
ここでの重要な要素は以下のとおりです。
$message
変数を利用してフィールドの値を参照している
$message.gl2_remote_ip
はgl2_remote_ipフィールドを参照する意味となる
to_ip
関数を使い文字列のIPアドレスをネットワークバイトオーダに変換している
cidr_match
関数を行い、上記で変換したIPアドレスのデータが10.10.10.0/24の中であるか検査している
ルール3は、アクションだけを実行するルールです。
when-then
の間で true
を記載することで、必ず条件に一致してアクションが実行されるようになります。アクションで行っていることは、 drop_message
関数を使い、メッセージを破棄しています。
上記で解説したルールを作成すると次のように一覧が表示されます。
13.2.3. ルールとステージの紐付け
続いて、作成したルールをステージに紐づけしていきます。
ステージの設定を行うため、まずpipelineを作成します。
Manage pipelines
タブを押し、 Add new pipeline
をクリックします。
pipelineの title
(タイトル) と Description
(説明)を入力して新しいpipelineを作成します。
Create pipeline
を押すと、pipelineが作成され、詳細画面が表示されます。
デフォルトでは、ステージ0のみ作成されます。
ステージを追加する場合は、 Add new stage
のボタンをクリックします。
ステージの設定画面が表示されます。
入力項目は次の通りです。
Stage
: ステージの優先順位を入力します。
Continue processing on next stage when
: 次のステージ進む条件を選択します。
All rules on this stage match the message
: すべてのルールの条件が一致した場合のみ、次のステージに進む
At least one of the rules on this stage matches the message
: どれかひとつのルールに一致した場合、次のステージに進む
None or more rules on this stage match
: 一致するルールが一つも存在しない場合、次のステージに進む
Stage rules
: 作成したルールを選択します。複数のルールを追加できます。
作成したルールをそれぞれステージ別に追加すると次のようになります。
このpipelineの動きは以下の通りです。
- ステージ0で、src_ipなどのフィールドの存在検査をする
- ステージ1で、サブネットの範囲内であるかを検査する
- ステージ2で、メッセージを破棄する
つまり、ルールの組み合わせで値の検査を行い、条件にマッチしたログだけを破棄するというブラックリストの設定が行われました。
ただし、これだけではまだpipelineは動作しません。
pipelineとstreamの紐付けを行う必要があります。
13.2.4. pipelineとstreamの紐付け
Edit connections
をクリックしてstreamを選択します。
この設定で、pipelineの処理が開始されます。
13.4. ルールの詳細
13.4.1. データ型
関数に値を渡す場合には、関数の引数に適合する型のデータを渡す必要があります。
Graylogのルール言語のパーサは、無効な型の使用を拒否します。
Graylogのルール言語の組み込み型は以下の通りです。
- str : utf-8文字列
- double : 浮動小数点数(Javaのdoubleと同等)
- long : 数値型(JavaのLongと同等)
- boolean : ブール値
- void : 返り値なしを示す型
- ip : IPアドレス
型はプラグインにより追加可能です。
また慣例的に型を変換する関数のプレフィックスは to_
となっています。
13.4.2. 条件
Graylogの規則では、 when-then
の間は、ブール式で評価されます。
式は AND
(または &&
)、 OR
または ||
)、 <
, <=
, >=
, >
, ==
, !=
をサポートしています。
when-then
の間で、関数を使うこともできますが、最終的には、ブール値を返す必要があります。条件に必ず一致させたい場合は、ブールリテラル true
を使うことができます。
13.4.3. アクション
then-end
の間には、アクションを定義します。アクションには2種類あります。
変数の代入は次のような形式になります。
変数は、データを保持して、再計算するために役立ちます。またルールの可読性を上げるためにも役立ちます。
13.4.4. 関数
関数には、それぞれ必要なパラメータと戻り値が定義されています。
関数のパラメータには、必須なパラメータと、必須ではないオプショナルなパラメータが存在しています。
関数のパラメータをすべて渡す必要がない場合、次のようにパラメータの名前を指定して渡すことができます。
let new_date = parse_date(
value: to_string($message.transaction_date),
pattern: "yyyy-MM-dd HH:mm:ss",
timezone: to_string($message.transaction_timezone)
利用可能な関数についてはGraylog公式の Functions Reference を参照してください。