【入門編】 Modbus TCPプロトコルの認証欠如とセッションハイジャック対策 – IoT・OT(制御システム) & ブロックチェーンセキュリティ防御ガイド

こんにちは!ITインフラやセキュリティの世界に一歩踏み出したばかりの皆さん、日々の業務本当にお疲れ様です。

突然ですが、皆さんの身の回りにある「工場」や「ビル管理システム」、そして「スマート農業のハウス」などを思い浮かべてみてください。水門が自動で開閉したり、巨大なモーターが唸りを上げて動いたりしていますよね。実は、それらを裏側でコントロールしている頭脳が「SCADA(スカダ)」と呼ばれるシステムであり、そこで言葉を交わすための共通言語の一つが Modbus TCP(モドバス・ティーシーピー) というプロトコルなんです。

今日は、このModbus TCPが抱える「致命的な秘密」と、それを狙う悪者から現場の設備を守るための方法について、身近な防犯に例えながら優しく紐解いていきたいと思います。一歩ずつ一緒に学んでいきましょう!

—

1. なぜModbus TCPは危ないの?(家の鍵がない世界)

まずは、Modbus TCPがどんな仕組みで動いているのか、私たちの日常に置き換えて考えてみましょう。

皆さんが住んでいるお家には、必ず玄関の「鍵」がありますよね。外出するときは鍵をかけ、帰ってきたら鍵を開けて中に入ります。宅配便の人が来ても、インターホンで本人確認をしてからドアを開けるはずです。

しかし、Modbus TCPの世界には、この「鍵」や「本人確認(認証)」の概念が最初から存在しません。

例えるなら、「すべての家の玄関ドアが全開で、誰でも自由にリビングに入り込めて、しかもリビングの壁にある『全館空調のスイッチ』や『ガス栓のバルブ』を自由にいじり放題の状態」です。これが、Modbus TCPが抱える根本的な課題なんです。

攻撃者がやっていること(セッションハイジャックと不正操作)

このプロトコルは1979年に生まれた古い設計をベースにしており、「ネットワークの内側にいる人は、全員みんないい人だよね」という性善説で作られています。

そのため、もし悪意を持った攻撃者が社内ネットワーク(あるいはセキュリティの甘いIoTネットワーク)に侵入すると、次のような恐ろしいことが簡単にできてしまいます。

1. 工場全体の機器の調査: ネットワーク上にあるPLC(制御用コンピューター)に「今どんな状態?」と話しかけて、すんなり答えを引き出す。
2. レジスタの書き換え: 「温度設定を限界まで上げろ」「モーターの回転数をゼロにしろ」という命令(レジスタ書き込み)を、偽の送信元として送りつける。
3. セッションハイジャック: 正当なエンジニアが作業している通信の隙間に入り込み、勝手に命令を差し込む。

物理的な破壊や大事故に直結するため、これは本当に笑い事では済まないリスクなんですね。

—

2. 攻撃を防ぐための「二重の防犯対策」

「鍵がないなら、どうやって守ればいいの?」と思いますよね。ご安心ください。Modbus TCP自体に鍵がないのであれば、「家全体を頑丈な塀で囲み、門番を置く」というアプローチで守ればいいのです。

現場のエンジニアやセキュリティ担当者が行うべき、現実的かつ最も効果的な対策は次の2つです。

  • 対策1:VPNによる通信の暗号化とトンネリング(外部からの侵入を防ぐ合鍵)
  • 対策2:産業用ファイアウォールによるネットワークセグメンテーション(不審者を門前払いにし、部屋ごとに出入りを制限する)

それでは、具体的な設定のイメージを見ていきましょう!

—

3. 実践!安全な通信路を作るための設定例

実務では、工場やプラントのネットワークをオフィスのITネットワークと完全に切り離すことが鉄則です。ここでは、産業用ルーターやファイアウォール(例: iptables や各種UTM)を使って、Modbus TCPが使っているポート(デフォルトは 502 番)へのアクセスを厳格に制限する設定例を見てみましょう。

以下の設定ファイルは、社内の一般的なPCから、直接工場のPLC(Modbus機器)へアクセスさせないためのファイアウォールルール(Linuxの iptables のイメージ)です。

#!/bin/bash

# ==============================================================================
# 産業用ネットワーク(Modbus TCP)保護のためのファイアウォール設定スクリプト
# ==============================================================================

# 1. すべてのModbus TCP通信(ポート502)をデフォルトで拒否する(原則禁止)
iptables -A INPUT -p tcp --dport 502 -j DROP

# 2. 信頼された保守用踏み台サーバー(例: 192.168.100.50)からのアクセスだけは許可する
iptables -A INPUT -p tcp -s 192.168.100.50 --dport 502 -j ACCEPT

# 3. 確立済みのセッションや関連する通信は継続を許可する
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

echo "Modbus TCPのアクセス制御ルールが正常に適用されました。"

このように、「誰からの通信であっても、ポート 502 への直接アクセスは基本的にすべて拒否し、許可された特定の安全な端末(踏み台サーバー)からだけ通す」というホワイトリスト方式を取るのが、現場におけるセオリーになります。

—

4. Pythonで学ぶ「安全な設計」の意識

開発者の皆さんが、IoTデバイスやSCADA連携用のプログラムをPythonなどで書く場合も、「認証がないプロトコルをそのまま野ざらしにしない」という意識が非常に大切です。

例えば、テスト環境でModbusのライブラリ(pymodbus など)を使って通信テストをする際、以下のように安全なローカルループバックや、セキュアなVPNトンネル内でのみ通信が行われるようにコードを組み立てる癖をつけましょう。

from pymodbus.client import ModbusTcpClient

# ==============================================================================
# 安全なネットワーク経由でModbusデバイスに接続するサンプルコード
# ==============================================================================
# 注意: パブリックなインターネット経由で直接このコードを実行してはいけません。
# 必ずVPNや安全にセグメント化された閉域網(プライベートIP)の内側で使用します。

TARGET_IP = "192.168.10.100"  # 工場のPLCが設置されている安全な内部プライベートIP
TARGET_PORT = 502             # Modbus TCPの標準ポート

def read_plc_temperature():
    # クライアントの初期化
    client = ModbusTcpClient(TARGET_IP, port=TARGET_PORT)
    
    try:
        # デバイスへの接続を試みる
        connection = client.connect()
        if not connection:
            print(f"[-] エラー: {TARGET_IP} への接続に失敗しました。ネットワーク経路を確認してください。")
            return

        print(f"[+] {TARGET_IP} との接続に成功しました。データを読み込みます...")
        
        # レジスタアドレス 0 番地から温度データを1つ読み出す(例)
        result = client.read_holding_registers(address=0, count=1)
        
        if result.isError():
            print("[-] レジスタの読み込み中にエラーが発生しました。")
        else:
            temperature = result.registers[0]
            print(f"[+] 現在のプラント温度: {temperature} ℃")
            
    except Exception as e:
        print(f"[-] 予期せぬエラーが発生しました: {e}")
        
    finally:
        # 通信終了後は確実にソケットを閉じる
        client.close()
        print("[*] 接続を切断しました。")

if __name__ == "__main__":
    read_plc_temperature()

このように、コードを書く段階から「この通信は本当に安全な経路を通っているか?」を意識することが、インシデントを防ぐ第一歩になります。

—

おわりに

Modbus TCPの認証欠如は歴史的な背景もあり、今すぐにプロトコルの仕様自体をガラリと変えることは難しいのが現実です。だからこそ、私たちインフラエンジニアや開発者が、ネットワークの構造(セグメンテーション)や適切なアクセス制御(ファイアウォール、VPN)でしっかりと「頑丈な城壁」を作ってあげる必要があります。

最初は難しく感じるかもしれませんが、要は「大事なもの(制御機器)の周りに、きちんと鍵付きの扉と門番を置く」という物理世界と同じ防犯の考え方です。

一歩ずつ、安全なシステム作りを楽しみながら進めていきましょう!それではまた次回の記事でお会いしましょう。

コメント

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