本文へスキップ

03 / 05 · 2022.08 — 2023.07

浙江木鏈科技有限公司

産業制御セキュリティ分野での Python バックエンド。バイパス型トラフィック監査システムのトラフィック処理経路、ホワイトリスト検知エンジン、Django REST API に参画し、Suricata によるブラックリスト検知を統合。27 種の産業プロトコルの詳細解析に対応した。

職種
Python 開発エンジニア
業種
産業制御セキュリティ
所在地
浙江
チーム
13名
在籍
1年

主な成果

  • 27 種

    詳細解析する産業プロトコル:Modbus、S7COMM、IEC104、IEC61850、DNP3、OPC UA、PROFINET、BACnet など

  • 996 件

    Suricata に取り込んだ産業系脆弱性シグネチャ(ブラックリスト検知用)

  • 10 秒

    Redis の有効期限イベントで実現したフロー集約窓。パケット単位の書き込みをフロー単位に

この会社での案件

PROJECTS · 1

2022.08 – 2023.07 · Python バックエンド開発 · 体制 13名

産業制御セキュリティ監査プラットフォーム

電力・製造などの制御システム向けのバイパス型トラフィック監査システム。プローブがスイッチのミラートラフィックを取得し、Kafka を経由して Cython 製のプロトコル解析エンジンへ。資産・ホワイトリスト・ブラックリストの 3 層ポリシーで検知・通知する。Modbus、S7COMM、IEC104、IEC61850、DNP3、OPC UA/DA/AE、PROFINET、ENIP/CIP、BACnet など 27 種の産業プロトコルを詳細解析し、電力系研究機関などの案件で稼働。

  • トラフィック処理経路の開発に参画:キャプチャプローブ → Kafka → プロトコル解析エンジン → PostgreSQL。Redis の有効期限イベントで 10 秒窓のフロー集約と一括登録を実現し、DB 書き込み負荷を大幅に低減。Redis の TTL で機器のオフライン検知を実装
  • 5 タプル・MAC・プロトコルのファンクションコードに基づくホワイトリスト検知エンジンを実装し、ビットマップで「通信行動の異常」と「内容の異常」を区別。IEC104 ASDU や OPC のインターフェース/ファンクションコードまで踏み込んだルール照合、時間帯指定でのホワイトリスト自動学習にも対応
  • 資産管理、ホワイト/ブラックリストポリシー、アラート、レポートなどの Django REST API を担当。Celery Beat でレポート出力、ポリシーバックアップ、期限切れデータの削除、プローブのヘルスチェックなどの定期ジョブを実装
  • Suricata を組み込み、unified2 アラートを解析。約 1,000 件(996 件)の産業系脆弱性シグネチャでブラックリスト検知を実現
  • Kafka Connect(Debezium CDC)で Pilosa のビットマップインデックスへデータ同期し、トラフィック統計と多次元検索を支援
  • (カスタム版)IEC 61850 の SCD ファイルを解析し、変電所の IED 通信ベースラインとトポロジを自動生成
  • Python
  • Django / DRF
  • Celery
  • Kafka
  • Redis
  • PostgreSQL
  • Pilosa
  • Suricata
  • Cython
  • Vue 2

システム構成

キャプチャ · プローブ メッセージバス 解析 · 検知 保存 · 同期 アプリ · 管理 オフライン警告 HTTP REST ルール · 資産 · プロトコルスイッチ · しきい値 5 秒ごとに取得(ホット更新) 制御ネットワークのミラートラフィックSPAN ポート · 読み取り専用 network-capturer キャプチャプローブ · Python Scapy L2 raw ソケット selector で複数 NIC をポーリング Cython Cstat カウント deque バッファ → Producer 運用の備え Supervisor で常駐プロセスを監視 Celery が 5 分ごとにプローブを巡回 取得 / Kafka 書込を二重計数 systemd で Pilosa の状態を確認 cpulimit でプロセスの CPU を制限 Suricata 4.0.4 AF_PACKET · cluster_flow 産業系脆弱性シグネチャ 996 件 unified2 バイナリログを出力 Kafka クラスタ cp-kafka 5.4 · ZooKeeper SASL 認証 · Docker 配備 retention.ms = -1 raw_packets 生フレーム · 300GB 保持 alerts 検知アラート · 1GB 保持 Kafka の設計ポイント キャプチャと解析を分離しピークを吸収 解析側を再起動してもデータを失わない Producer retries = 5 100 件ずつバッチ送信 BufferError → flush して再試行 raw 300GB / その他 1GB unified2 ログ /var/log/suricata packet-inspector 解析・検知エンジン · Consumer が raw_packets を取得 · pypkt (Cython) で 70 超のプロトコルを解析 · 5 タプル+MAC+プロトコル+ペイロード → ハッシュ · Redis 10 秒の期限窓でカウント集約 · 5 秒ごとに一括 INSERT … RETURNING · WhitelistInspector でポリシー検知 · 異常 → Producer が alerts へ書き込み · ThreadPool(16) + fail2restart で自己復旧 内部スレッド図は第 2 節 store.py アラート登録 alerts を消費 → sec_alert テーブル Syslog 外部送信 · 演習環境へ送信 Supervisor 常駐プロセス gunicorn · celery worker/beat store.py · unified2_recorder db_2_pilosa · packet_stat detect_device_offline cpulimit unified2_recorder idstools で解析 → ブラックリストアラートを登録 Redis 6 DB0/1 Celery ブローカー/結果 DB2 フロー集約窓 TTL 10 秒 DB3 機器アクティブ TTL N 分 keyspace 期限切れイベント (Ex) PostgreSQL 10 packet_packet フロー記録(count / length 含む) sec_alert_secalert セキュリティアラート 資産 · 許可 · 拒否リスト · 設定 wal_level = logical max_connections = 300 Kafka Connect · Debezium pgoutput 論理レプリケーション → Avro auditor.public.* CDC 変更 · Schema Registry db_2_pilosa AvroConsumer → ビットマップ Pilosa ビットマップインデックス 統計 · 許可リスト自動学習 Vue 2 フロントエンド Vuex · Router · ECharts iView · axios · Electron Django 1.11 + DRF Gunicorn 8 workers :9003 資産 · ホワイトリスト · ブラックリスト セキュリティ · システム警告 パケット監査 · レポート出力 ポリシー退避復元 · 設定 ユーザー · ライセンス有効化 ホワイトリスト自動学習 統合管理プラットフォーム連携 drf-yasg API ドキュメント Django アプリ約 12 個 Celery worker + beat Redis をブローカーに レポート · ポリシーバックアップ · 統計 期限切れデータの削除 · プロセス巡回 bigdaddy 機器エージェント IP / 時刻の変更 / 再起動 キャプチャ NIC の設定 · ルール配信 ファームウェア更新 RSA + AES 証明書生成 · ライセンス有効化 外部連携 統合管理基盤 · 国家暗号 SM4 Syslog · 演習環境への送信 1 2 3 4 5 6 7 8 9 10
pop map[key] 登録待ちキューへ ① Kafka 消費スレッドpoll(0.01) raw_packets raw deque·1000 ② 解析 + 集約スレッドpypkt 判定 → ハッシュキー生成 メモリ map + Redis DB2 新規キー:SETEX key 10 秒 既存キー:count++ / bytes+= SETEX src_ip → DB3(離脱検知) ③ 期限切れ監視スレッド__keyevent@2__:expired parsed deque·1000 ④ 登録 + 検知スレッド(5 秒ごと) 一括 INSERT … RETURNING count InspectorManager → ホワイトリスト検知 異常あり → thread_pool.submit(send_alert) PostgreSQL packet_packet Kafka alerts(異常リスト) ⑤ ルールのホット更新スレッド(5 秒ごと) 資産・許可リスト・プロトコル・閾値 → share_data Django バックエンド API メインスレッドが fail2restart で監視 5 秒ごとに 5 スレッドの future を確認 スレッド異常 → ログを残して再 submit PG 切断 → 再接続を繰り返し終了しない スレッドプール滞留 > 500 → 自発的に退避 deque に上限を設けてメモリ膨張を防止 Producer キュー 10 万件のバッファ アラート送信失敗はコールバックで記録
資産チェック · check_ip_and_mac ホワイトリストチェック · check_whitelists 独立した検知経路 いいえ はい はい いいえ いいえ · ビットマップ 0 はい 不一致 · ビットマップ 2 一致/ペイロードルールなし 解析後のフロー記録2 種類のチェックを同時実行 IP は資産表にある?通信機器(ルータ)は MAC 判定をスキップ 不正機器の接続 2 IP-MAC バインドが有効かつ実 MAC が資産と不一致? MAC アドレス競合 4 資産チェック通過アラートなし いずれかのホワイトリスト 5 タプルに一致?IP / MAC / ポート範囲 / L4 / プロトコル 通信行動の異常 3 産業プロトコルのペイロードルール検査ファンクションコード / フィールド値 / 値の範囲 通信内容の異常 5 正常通過結果ビットマップ = 3 Suricata シグネチャに一致CODESYS、S7 などの産業系脆弱性悪用パターン ブラックリストアラート 1 Redis DB3 の機器キーが期限切れN 分間この IP の通信がない 機器の無通信 30

システムデータフロー

抽象的な図示・内部の詳細は含みません
  1. スイッチのミラーポート

    バイパス・読み取り専用

  2. キャプチャプローブ → Kafka

    Scapy・raw_packets 300GB 保持

  3. プロトコル解析エンジン

    Cython・27 種の産業プロトコル

  4. ポリシー検知

    資産・ホワイトリスト(ビットマップ)・Suricata ブラックリスト

    ▲ 担当範囲

  5. PostgreSQL → Pilosa

    明細・CDC ビットマップ索引

  6. Django + Vue

    アラート・ポリシー・レポート

    ▲ 担当範囲

写真は同僚の同意を得ているか、他の方の顔をぼかしています

ここで学んだこと

産業セキュリティの分野で、一般的な攻撃手法と権限昇格を理解し、Modbus、S7COMM、IEC104、OPC などの産業プロトコルとバイパス型のトラフィック監査に初めて触れました。業務コードを書きながら Django / DRF と Celery にもさらに習熟しました。

プロトコル解析は CPU 負荷の高いバイト単位の処理で、解析ライブラリは Cython でホットパスを C 拡張にコンパイルし、上位には Python インターフェースを保っています。この時期には C++ から Rust への移行プロジェクトにも参加しました。Redis の有効期限イベントによる集約窓、ビットマップによる異常種別の区別。どれも単純な部品で、高頻度な制御系通信の書き込みと検知の負荷をさばく工夫でした。

TECH STACK

  • Python
  • Django / DRF
  • Celery
  • Kafka
  • Redis
  • PostgreSQL
  • Pilosa
  • Suricata
  • Cython
  • Vue 2
  • Docker