【実務・中級編】 IT/OTネットワーク境界における産業用ファイアウォールとディープパケットインスペクション(DPI) – サイバーセキュリティとプライバシー保護実践ガイド

IT/OTの境界線を守り抜け:産業用ファイアウォールとDPI(ディープパケットインスペクション)が紡ぐリアルタイム防衛ライン

おい、ちょっとこっちに来てくれ。いま、プラントの制御ネットワークから奇妙なアラートが上がっているんだ。

オフィス側のITネットワークから、工場現場のOT(制御技術)ネットワークへ向けて、見慣れないパケットが流れている。宛先はPLC(プログラマブル・ロジック・コントローラ)。ポートは標準的な 502 番。プロトコルはModbus TCPだ。
一見すると、普通の監視システムがデータをポーリングしているだけのよう見えるだろ? だが、ペイロードの深部を覗いてみると……おいおい、これはマズい。本来なら許されないはずの、書き込み系の不正な関数コード(Function Code)が仕込まれている。もしこれをそのまま通したら、ボイラーの圧力バルブが勝手に全開にされてしまうかもしれない。

「大丈夫です、ITとの境界にはちゃんとした次世代ファイアウォール(NGFW)を置いていますから!」
……そんな威勢のいいセリフを吐いた若手エンジニアの肩を、私はそっと叩き、こう言ってやった。

「なあ、そのファイアウォールは、Modbusの 0x10(Multiple Registersの書き込み)と 0x03(Holding Registersの読み込み)の区別がパケットの奥底まで見えているか? 単にポート 502 が空いているから通す、なんて愚かな設定になっていないだろうか?」

今日のテーマは、まさにそこだ。IT/OTの境界領域における「産業用ファイアウォール」と「DPI(ディープパケットインスペクション)」の真実について、現場の泥臭い実務の視点から徹底的に紐解いていこう。

—

1. なぜ「普通のファイアウォール」ではOTネットワークを守れないのか?

現代のサイバーセキュリティにおいて、オフィスITと工場OTの融合(IT/OTコンバージェンス)は避けて通れないトレンドだ。エッジデバイスからリアルタイムに稼働データを吸い上げ、クラウドのビッグデータ基盤で予兆検知を行う。美しいアーキテクチャだ。だが、その裏で、かつて「エアギャップ(物理隔離)」という名の厚い壁に守られていた制御システムが、サイバー攻撃の最前線に晒されている。

境界防御における致命的なパラダイムシフト

従来のIT向けファイアウォールは、OSI参照モデルのレイヤー3(IPアドレス)やレイヤー4(TCP/UDPポート番号)を中心にパケットを検査してきた。例えば、「オフィスからのトラフィックであっても、宛先IP 192.168.100.50 のポート 502 以外はすべてドロップする」といったルールだ。

しかし、OTプロトコル(Modbus TCP, EtherNet/IP, PROFINET, IEC 60870-5-104など)の多くは、セキュリティを一切考慮せずに設計されたレガシーな代物だ。認証機構すらないものがゴロゴロしている。
つまり、ポート 502 さえ通してしまえば、攻撃者はその中身(ペイロード)でどんな悪質なコマンドを実行しようが、従来のL4ファイアウォールすり抜けてPLCに到達できてしまうのだ。

ここで登場するのが、パケットの深部まで解剖する DPI(Deep Packet Inspection) を搭載した産業用ファイアウォールである。

—

2. DPC(ディープパケットインスペクション)がModbus TCPの闇を暴く仕組み

では、産業用DPIがネットワーク上で実際に何をしているのか、パケットの挙動を追ってみよう。

Modbus TCPは、TCPポート 502 を使ってやり取りされる。通信の基本単位は「MBAPヘッダー(7バイト)」と「PDU(プロトコルデータユニット)」だ。PDUの先頭1バイトには 「関数コード(Function Code)」 が格納される。

例えば、安全な読み込み系コマンドと、危険な書き込み系コマンドの関数コードは以下のようになる。

  • 0x03:Read Holding Registers(保持レジスタの読み込み) -> 通常は監視端末から許可される
  • 0x06:Write Single Register(単一レジスタの書き込み) -> メンテナンス時以外は厳禁
  • 0x10:Write Multiple Registers(複数レジスタの書き込み) -> 極めて危険。プラントのパラメータを書き換える能力を持つ

DPIエンジンは、TCPの3ウェイハンドシェイクが完了し、データが流れてきた瞬間、L7層のペイロードをリアルタイムでパース(解析)する。そして、「このセッションは 0x03 しか許可されていないゾーンからの接続なのに、なぜ 0x10 のペイロードが含まれているんだ?」と検知し、瞬時にRSTパケットを返すか、パケットをサイレントドロップする。

—

3. 実践!産業用ファイアウォールにおけるDPIルールの設定実例

口で言うだけなら誰でもできる。インフラエンジニアなら、実際にどう設定に落とし込むかが見たいはずだ。
ここでは、一般的な産業用Linuxベースのファイアウォールや、商用DPIアプライアンスで用いられるルール定義の概念を、分かりやすい設定ファイルのサンプルとして示そう。

以下の設定は、OT境界に配置されたプロトコルインスペクターのルール定義ファイル(YAML形式を想定)のイメージだ。

# 産業用ファイアウォール DPIポリシー設定ファイル (it-ot-boundary-policy.yaml)
version: "3.2"
firewall_mode: "strict-inspection"

policies:
  - id: 101
    name: "Allow-Modbus-Read-Only-From-SCADA"
    description: "SCADAサーバーからPLC群への安全なデータ読み込みのみを許可し、書き込みを完全にブロックする"
    action: "ALLOW"
    protocol: "modbus-tcp"
    source:
      ip_subnet: "10.200.10.0/24"  # オフィス側のSCADA/監視ネットワーク
    destination:
      ip_subnet: "192.168.100.0/24" # 工場内のOT/PLCネットワーク
      port: 502
    inspection_criteria:
      allowed_function_codes:
        - 0x01  # Read Coils
        - 0x02  # Read Discrete Inputs
        - 0x03  # Read Holding Registers (正常なポーリング)
        - 0x04  # Read Input Registers
      forbidden_function_codes:
        - 0x05  # Write Single Coil
        - 0x06  # Write Single Register (不正な単体書き込みを遮断)
        - 0x10  # Write Multiple Registers (不正なバルク書き込みを遮断)
      max_transaction_rate: 100  # 秒間リクエスト数の制限(DDoSやスキャン対策)

  - id: 999
    name: "Default-Deny-All-OT"
    description: "上記ルールに一致しないすべてのOT向けトラフィックを破棄し、アラートログを出力する"
    action: "DROP_AND_LOG"
    protocol: "any"
    destination:
      ip_subnet: "192.168.100.0/24"

この設定のミソは、単に port: 502 を通すだけでなく、inspection_criteria(検査基準)で allowed_function_codes をホワイトリスト形式で厳格に定義している点だ。万が一、攻撃者がSCADAサーバーの踏み台に成功し、0x10 のコマンドを送り込もうとしても、DPIエンジンがパケットのペイロードを解釈した瞬間に遮断される。

—

4. Web APIやクラウド連携システムからのOTアクセス検証コード

さて、現代のスマートファクトリーでは、「クラウド上のWeb APIから工場の状態をモニタリングしたい」という要望が絶えない。例えば、Python製バックエンドからModbusゲートウェイ経由でPLCのデータを取得するスクリプトを書いてみよう。

ここで重要なのは、「正当な読み込みAPI」と「不正な書き込みコード」を叩いたときに、DPIがどのように挙動するのかをテスト・検証できる環境を持つことだ。以下のPythonコード(pymodbus ライブラリを使用)を見てほしい。

#!/usr/bin/env python3
"""
IT/OT境界におけるModbus DPI検証用スクリプト
開発者やインフラエンジニアが、ファイアウォールのDPIが正しく機能しているかをテストするためのコード。
"""

from pymodbus.client import ModbusTcpClient
import sys
import time

# 産業用ファイアウォールの外側(または通過テスト用クライアント)から見たターゲットIP
PLC_GATEWAY_IP = "192.168.100.50"
PLC_PORT = 502

def test_modbus_inspection():
    print(f"[*] ターゲットPLCゲートウェイ ({PLC_GATEWAY_IP}:{PLC_PORT}) へ接続を試みます...")
    
    client = ModbusTcpClient(PLC_GATEWAY_IP, port=PLC_PORT)
    connection = client.connect()

    if not connection:
        print("[!] 接続失敗: ファイアウォール、またはネットワーク経路でブロックされています。")
        return

    try:
        print("\n--- テスト1: 許可された読み込みコマンド (Function Code 0x03) の送信 ---")
        # レジスタアドレス 0 から 10個の保持レジスタを読み込む(通常はDPIを通過するはず)
        rr = client.read_holding_registers(address=0, count=10, slave=1)
        
        if rr.isError():
            print(f"[!] 読み込みエラー(DPIによるブロックの可能性あり): {rr}")
        else:
            print(f"[+] 成功! 読み取ったデータ: {rr.registers}")

        print("\n--- テスト2: 禁止された書き込みコマンド (Function Code 0x06) の送信 ---")
        # レジスタアドレス 10 に強制的に値 9999 を書き込む(DPIによりブロックされるべき)
        wr = client.write_register(address=10, value=9999, slave=1)
        
        if wr.isError():
            print(f"[+] 期待通りの動作: DPIまたはPLCにより書き込みコマンドがブロックされました: {wr}")
        else:
            print("[!] 警告!本来ブロックされるべき書き込みコマンドが通過してしまいました!セキュリティ設定を確認してください。")

    except Exception as e:
        print(f"[!] 例外が発生しました: {e}")
    finally:
        client.close()
        print("\n[*] セッションを終了しました。")

if __name__ == "__main__":
    # 実環境への影響を防ぐため、実行前に確認を促す
    confirm = input("注意: このスクリプトは実稼働中のPLCに対してModbusコマンドを送信します。続行しますか? (y/N): ")
    if confirm.lower() == 'y':
        test_modbus_inspection()
    else:
        print("テストを中止しました。")

このスクリプトを実環境や検証環境(Staging環境)で走らせることで、自社のファイアウォールが本当に不審な関数コードを弾いているかどうかを、身をもって確認できる。インフラの運用において、「動いているはずだ」という思い込みほど恐ろしいものはない。必ず自分の手でパケットの生死を確かめることだ。

—

5. 現場のシニアが教える、DPI導入・運用のリアルな泥臭いTips

最後に、私がこれまでの現場で血を流しながら学んだ、産業用ファイアウォールとDPI運用の実践的なTipsをいくつか授けておこう。教科書には載っていない生きた知見だ。

1. 「学習モード(Learning Mode)」から始めろ
いきなり厳格なDPIポリシーを本番稼働させると、既存の正当な制御トラフィックまで巻き込んでプラントを緊急停止(トリップ)させる大惨事を引き起こす。まずは数週間、トラフィックを「ロギングのみ(監視モード)」で動作させ、工場内で使われているすべての関数コードと通信パターンを完全にプロファイリングすること。
2. ベンダー独自の拡張プロトコルに泣かされる覚悟を持て
ModbusやEtherNet/IPといった標準規格であっても、PLCメーカー(Schneider, Siemens, Rockwellなど)が独自の私家版拡張コマンド(ベンダー固有コード)をペイロードにねじ込んでいるケースが多々ある。汎用DPIがこれを「未知の不正パケット」と誤認してドロップすることがあるため、例外ルールのチューニングには膨大な根気が必要になる。
3. 暗号化(TLS)のジレンマに備えよ
「安全のためにOT通信もすべてTLSで暗号化しよう」というIT側の正しいアプローチは、実はDPIの致命的な天敵になる。パケットの中身が暗号化されてしまっては、ファイアウォールは深部を覗く(Inspectする)ことができず、ただのL4フォワーダーに成り下がってしまう。これを解決するためには、境界アプライアンスでいったんパケットを終端・復号して検査する(SSL/TLSインスペクション)か、信頼されたゾーン間でのみ暗号化を解くといったアーキテクチャの再設計が不可欠だ。

—

おわりに

ITとOTの境界線を守るということは、単にサイバー空間のデータ守るだけではない。その向こう側にある「現実世界の物理的な安全(Safety)」を守ることに直結している。

パケットのヘッダーの向こう側、ペイロードの深淵に潜むコマンドの意味を理解し、ファイアウォールのルールを血肉化させること。それこそが、これからの時代に求められる真のネットワークセキュリティスペシャリストの姿なのだ。

さあ、コーヒーブレイクは終わりだ。ログの解析に戻るとしよう。君のネットワークにも、おかしなパケットが紛れ込んでいないか、今すぐ確認してみるんだな。

コメント

タイトルとURLをコピーしました