OTにおける決定論的検知ルールの仕組み — Allow Listからインシデントまで
OT監視の現場で足りないのはログではなく時間です。Allow ListからDetection Rule、インシデントまで、決定論的検知の仕組みを想定シナリオで解説します。
OTにおける決定論的検知ルールの仕組み — Allow Listからインシデントまで
OTチームの多くは、ログが足りないのではない。時間が足りないのだ。工場のネットワークトラフィックやSCADAシステムを毎日監視している人なら、同じ壁にぶつかったことがあるはずだ。監視ツールが四六時中、何かをアラートしてくる。追いきれなくなったチームは、結局いくつかのアラートをオフにしてしまう——これは、そもそもアラートシステムがない状態よりもさらに危険だ。
多くのベンダーは、機械学習によるアノマリー検知でこの問題に答えようとする。モデルに「正常な挙動」を学習させ、そこから外れたものをアラートするという発想だ。賢そうに聞こえる。だが問題は、実際にアラートが上がったときに表面化する。チームは「なぜアラートが出たのか」を説明できないことが多い。モデルは理由を教えてくれない。ただ「異常だ」としか言わないからだ。
だからこそ、決定論的(deterministic)な仕組みがOTの現場でいまだに居場所を持っている。このタイプのルールは機械学習モデルほど賢くはないが、条件はすべて明文化されている——AとBが同時に起きたらアラートする、というように。なぜアラートが出たのかを常に説明できる。判断ミスが生産ラインの停止につながりかねない現場では、この説明可能性は見た目以上の価値を持つ。
この記事では、zcrOTのDetection Engineを取り上げる。誰でもクリックして確認できる公開デモ(https://demo.ot.zcr.ai/dashboard/detection-engine)にある画面だ。デモはサンプルデータで動いているので、画面に出ている値を読み上げるのではなく、各タブが何のためにあって、どう読めばいいのかを説明し、そのうえで架空のシナリオを一つ使って、Allow Listのエントリーからインシデントまでを追っていく。デモを開きながら読み進めてほしい。
インシデントになるまでの3層構造
zcrOTのDetection Engineは複数のタブに分かれている。検知の仕組みに直接関わるのはAllow Lists、Device Mappings、Detection Rules、Incidents(対応とトリアージのためのタブ)の4タブだ。各タブの役割ははっきり分かれていて、トラフィックがチームの目に触れる「案件」になるまでの、いわばフィルターの層を成している。
第1層 — Allow List:「これはもともと正常」とシステムに教える
Allow Listのエントリーは、チームがすでに確認して「正常」と判断したトラフィックの記録だ。エントリーごとに、名前、説明、Scope(送信元、宛先、ポート範囲)、種別(通信がネットワークの内側で完結するのか外へ出るのか、そしてModbusやTLSといったプロトコル)を持つ。Allow Listは、「このネットワークにとっての正常」をあらかじめ書き出しておき、チームが同じ通信を何度も調べ直さなくて済むようにするためのものだ。
身につけたい習慣は、エントリーを狭く保つことだ。たとえば、監視サーバー1台が、ゲートウェイ1台に対して決まったスケジュールでModbusのポーリングをかけるエントリーを思い浮かべてほしい。これは「この送信元、この宛先、このポート、このプロトコル」という、かなり絞った内容を述べている。別のマシンがそのゲートウェイに話しかけ始めても、監視サーバーが別の宛先へ接続しても、このエントリーにそれを正常とする記述はない。エントリーが広くなるほど、「正常」と宣言する範囲も広がる。ネットワークの半分をカバーするようなエントリーは、入力の手間を省いてくれる代わりに、誰もきちんと確かめていない通信まで「正常」と宣言してしまう。
第2層 — Device Mapping:IPを一目でわかる名前に変換する
Device Mappingsは、IPアドレスやModbusのユニットIDを、人が読める名前に対応付けるタブだ。地味な整理作業に聞こえるが、人がほかの層を読み解けるのは、この層があるからだ。Allow Listのエントリーはアドレスで表され、生のトラフィックの大半も同じだ。エントリーをマッピングと照らし合わせれば、ネットワーク上のどのデバイスを指しているのかがわかる(2つのタブは互いを直接参照しているわけではないので、この照合は習慣にしておくといい)。とくに効くのは、深夜2時にアラートが鳴っているときだ。そんな時間に、アドレスがどの機器のものかを一から調べたい人はいない。名前の付け方も規律の問題になる。1台のデバイスには名前を1つだけ与えて、どこでもそれを使うこと。1文字違うだけの名前があると、実際には1台しかないのに2台目があるように見えてしまうことがある。
もうひとつ押さえておきたいのが、ModbusのユニットIDだ。ゲートウェイの背後につながる複数のデバイス(たとえば流量計、ドライブコントローラー、温度センサー)は、自分専用のIPを必ずしも持つわけではない。同じゲートウェイのアドレスの向こうで、それぞれ別のユニットIDで応答していることがある。OTの現場ではよくあるパターンだ。IPだけでなくユニットIDもマッピングしておけば、ログを読むチームはネットワーク図を開いて照合しなくても、そのユニットIDがどのデバイスなのかをすぐに判断できる。
第3層 — Detection Rule:いつ本当にアラートを出すかを決める条件
ここが、何をインシデントとして扱うかを最終的に判断する層だ。ルールは、名前、Priority、Type、Severityを持つ。Rule Typeは4種類ある。Single Event(1回発生しただけで即アラートできる。例えば見覚えのないクライアントがゲートウェイに接続しようとするケース)、Threshold(規定回数を超えて初めてアラートする。例えば営業時間外のリモートメンテナンスアクセス)、Aggregation(複数の小さなイベントをまとめてから判断する。例えば異常に頻発するModbusエラー)、Correlation(過去に見たベースラインと比較する。例えばいつものパターンから外れたクラウドへの送信トラフィック)だ。4種類がそろっていることは重要だ。工場で起きる異常は一つの形をしていない——一発検知が必要なものもあれば、傾向を見てから判断すべきものもあるからだ。
自社のOTネットワークでもこうしたルールを組んでみたいなら、zcrOTのプランを見る →で全パッケージを確認できる。
想定シナリオ — ルールからインシデントへ
理屈だけでは足りないので、ここでは一つのシナリオを最初から最後まで追ってみよう。これは作り話で、実在のデバイスもアドレスも名前も出てこない。自分のチームのランブックにこうしたシナリオを書くなら、RFC 5737がドキュメント用に予約しているアドレスブロックから取ったアドレスを使うといい。そうすれば、例が実在のシステムと取り違えられずに済む。
小さな工場を考える。データゲートウェイが1台あって、現場の複数のデバイスからModbusで値を集めている。チームは、そのゲートウェイをポーリングする監視サーバー向けのAllow Listのエントリーを持っていて、両方の機器がDevice Mappingsにも名前で登録されている。有効なルールは2つ。見覚えのないクライアントがゲートウェイに到達したら発火するSingle Eventのルールと、取り決めた時間帯の外でのリモートメンテナンス活動を捉えるThresholdのルールだ。
ある静かな夜、誰もマッピングしていないマシンが、ゲートウェイに向けてModbusのリクエストを送り始める。チームの記録と照らし合わせると、こうなる。
- Allow Listには、このマシンとゲートウェイの通信をカバーするエントリーがない。この通信を正常とする記述は、どこにもない。
- Device Mappingsにも名前がない。生のトラフィックの中では名前のないただのアドレスで、それ自体が手がかりになる。
- Single Eventのルールはまさにこの種のクライアントのために書かれているので、最初の1回で発火する。ルールの条件が明文化されているから、あとから誰でも理由を説明できる。見覚えのないクライアントがゲートウェイに到達した、というだけの話だ。
- マッチはインシデントになり、ここで初めて、人が目を向けるべきものが生まれる。
このインシデントから何が読み取れるかが、いちばん役に立つ部分だ。どの条件が満たされたのかは、それに対応するように書かれたルールから読み取れる。元になったトラフィックに含まれるアドレスをDevice Mappingsと照らし合わせれば、工場のどの部分が関わっているのかがわかる。ステータスを見れば、誰かがすでに手を付けたかどうかがわかる(たとえばOpen、Ack、Closedといった状態がある)。match数はルールが何回マッチしたかを示し、risk scoreは何から見るかを決める助けになる。
ただ、match数とrisk scoreの2つは読み方に気をつけたい。match数が同じ2つのインシデントでも、向けるべき注意がまったく違うことはある。未知のクライアントがゲートウェイに何度も到達しているのと、もともとノイズが多いとわかっているデバイスで低Severityのルールが何度もマッチしているのとでは、問題の質が違う。トリアージを担当するチームが「マッチした回数」だけを見て優先順位を決めるべきではない理由がここにある。risk scoreについても、ルールのSeverityを別の形で表しただけだと決めつけないほうがいい。トリアージの一つの材料であって、判決ではない。
静かなケースからも学べることがある。シナリオのThresholdルールは、その夜ずっと沈黙したままだ。これは必ずしも故障ではない。有効になっているのに一度もインシデントを出していないルールは、まだ起きていない条件を待っているだけかもしれない。ただし、頼りにする前に、本当にそれが理由なのかは確かめておきたい。
OTのインシデントがどんな形で現れ、どう重みを付けて見ればいいのかをもっと深く知りたい人には、OTインシデント4種という記事で詳しく解説している。
Modbusの読み書きだけではない——想像以上に細かいClassification
新しいAllow Listを作成するとき、システムはドロップダウンからClassificationを選ばせる。選択肢は、最初にイメージしがちなModbusのreadやwriteのカテゴリにとどまらない。Modbus以外の通信向けにも、たとえばHTTPSセッションやICMPプローブのようなグループや、受信ポートへのアクセス向けのグループがある——プロトコル名ひとつで括れる範囲を超えて、トラフィックを細かく分類していることがわかる。
とはいえ正直に言っておきたいことがある。このClassificationの細かさは、あくまでModbusとネットワークフロー(network flow)レベルの範囲にとどまっている。EV充電器がある現場では、この線引きが重要になる。zcrOTには、EV充電器がバックエンドと直接会話するプロトコルであるOCPP(Open Charge Point Protocol)専用のシグネチャが存在しない。つまりEV充電器まわりの検知は、充電器のIPに出入りするネットワークトラフィックが手がかりであって、OCPPのメッセージそのものをプロトコルレベルで解析しているわけではない。OCPPのメッセージレベルまで踏み込んで見たい組織は、専用ツールを別途用意する必要がある。これは隠すべきことではなく、判断の前に知っておくべき本当の制約だ。
こうしたプロトコル対応範囲の話は、zcrOTがグローバルプレイヤーにまだ及ばない部分でもある。zcrOTをClaroty、Nozomi Networks、Dragosと比較検討しているなら、どちらかに肩入れしないストレートな比較記事をzcrOT対Claroty・Nozomi Networks・Dragosにまとめている。
まとめ
ここまで見てきた仕組み全体——何が正常かを示すAllow List、IPを読みやすい名前に変換するDevice Mapping、アラートすべき条件を定めるDetection Rule、そして最後にrisk scoreで優先順位を付けられるIncident——は、OTチームが生のトラフィックを一行ずつ手作業で追わなくて済むようにするためのものだ。同時に、理由のわからないブラックボックスを盲目的に信じる必要もない。どのアラートも、条件が明文化されたルールから生まれるので、なぜ発火したのかをいつでも説明できる。
なぜOTの仕事がそもそもITと発想から違うのか、もっと大きな視点で知りたい人は製造業のためのOTセキュリティを読んでみてほしい。自分の手で実際に触ってみたい人は、登録不要でzcrOTデモにアクセスできる。全パッケージの詳細は料金ページで確認できる。
お問い合わせ
自社のOTネットワークにどんなルールが合うか知りたい方は、無料で私たちのチームに相談できる。
出典
- RFC 5737 — IPv4 Address Blocks Reserved for Documentation — 文書・サンプル用に3つのIPv4ブロック(TEST-NET範囲)が予約されており、そこから取ったアドレスは実在のシステムを指さないことを確認
- NIST SP 800-82 Rev. 3 — Guide to Operational Technology (OT) Security — ICS/OTシステムには高可用性、リアルタイム処理、決定論的な挙動が求められ、一般的なITとはセキュリティ要件が大きく異なることを確認。決定論的検知が今も居場所を持つという本記事の論拠を裏付けるが、NISTはML特有のexplainabilityの論点そのものには触れていない