【実務・中級編】 ポートセキュリティのバイオレーションモード(Restrict、Shutdown、Protect)の挙動差異 – インフラ・物理&L2/L3ネットワーク基礎実践ガイド

こんにちは、ネットワークエンジニアの皆さん。日々のインフラ運用、本当にお疲れ様です。

Web APIの設計やモダンなクラウドアーキテクチャの構築にどれほど情熱を注いでいようとも、その基盤を支えるレイヤー2の足元が揺らいでいたら、システム全体は一瞬で崩壊します。特に「オフィスのフロアに勝手にハブを繋がれた」「退職者の机にあった卓上スイッチから未知の端末が大量のトラフィックを送り出している」といった、現場の泥臭いインシデントに直面したとき、あなたを助けてくれるのは教科書知識ではなく、スイッチの挙動に関する深い理解です。

今回は、そんなL2セキュリティの要である「ポートセキュリティ(Port Security)」のバイオレーションモード(Violation Mode)について、パケットの挙動から実務的な設定例まで、徹底的に深掘りしていきましょう。

—

1. ポートセキュリティとバイオレーションモードの基本概念

スイッチのポートには、学習できるMACアドレスの最大数を制限する「ポートセキュリティ」という強力な機能があります。例えば、「このポートには社給PCのMACアドレス1台分しか学習させない」と決めておくことで、不正なデバイスの接続を物理層に近いレイヤーでブロックできます。

しかし、ここで疑問が生じます。「もし、その制限を超えた不正なフレームが流れてきたら、スイッチはどう振る舞うべきか?」

この「違反(Violation)」を検知した際の挙動を定義するのが、バイオレーションモードです。Cisco等のL2スイッチでは、主に以下の3つのモードが用意されています。

1. Protect(プロテクト)
2. Restrict(レストリクト)
3. Shutdown(シャットダウン ※デフォルト)

これら3つの違いは、単に「パケットを捨てるか捨てないか」だけではありません。ログを残すか、カウンターを回すか、ポート自体を殺すかという、セキュリティポリシーと運用負荷のトレードオフがここに凝縮されています。

—

2. 3つのバイオレーションモードの挙動と仕様差異

それぞれのモードが内部でどのような処理を行っているのか、パケットのライフサイクルに沿って紐解いていきましょう。

01. Shutdown(シャットダウン)

  • 挙動: 最大MACアドレス数を超過したフレームを検知した瞬間、該当ポートを強制的に err-disable(エラーディスエーブル)状態にします。ポートのLEDがオレンジ色に変わり、物理的な通信が完全に遮断されます。さらに、SyslogやSNMPトラップで管理者に異常を通知します。
  • メリット: セキュリティレベルが最も高い。不正アクセスを完全に封じ込めます。
  • デメリット: 悪意のないユーザーがたまたま別端末を繋いだだけでもポートが落ちるため、管理者の復旧作業(shutdown / no shutdown)が発生します。

02. Restrict(レストリクト)

  • 挙動: 最大数を超過した未知のソースMACアドレスを持つフレームは破棄(Drop)します。同時に、違反カウンタ(Security Violation Count)をインクリメントし、Syslogを出力します。ただし、ポート自体は up 状態を維持し、正当なMACアドレスからの通信は通し続けます。
  • メリット: 攻撃や不正接続の兆候をログで検知しつつ、正当なトラフィックへの影響を最小限に抑えられます。
  • デメリット: ポートが生きているため、攻撃者が執拗に不正フレームを送り続けた場合、CPU負荷やログの肥大化を招く恐れがあります。

03. Protect(プロテクト)

  • 挙動: 超過した未知のソースMACアドレスのフレームを破棄(Drop)します。ここまでは Restrict と同じですが、Syslogを出力せず、コンソールへの警告も出しません。 唯一の痕跡は、内部の違反カウンタがひっそりと増加することだけです。
  • メリット: ログの嵐(ログフラッド)を防ぎつつ、静かに不正フレームをドロップできます。
  • デメリット: 管理者が異常に気づきにくいため、モニタリングシステム(SNMP等で違反カウンタを監視する仕組み)が構築されていない限り、インシデントを見逃すリスクがあります。

—

3. 実務で役立つ!スイッチ設定とデバッグの作法

それでは、実際にCisco IOSスイッチを例に、ポートセキュリティの設定と、現場で使えるトラブルシューティングの作法を見ていきましょう。

ネットワーク機器(Cisco IOS)の設定サンプル

以下は、アクセスポート(例: GigabitEthernet0/1)に対して、最大MACアドレス数を「2」に制限し、バイオレーションモードを Restrict に設定するコンフィグの例です。

! インターフェースコンフィグレーションモードへ移行
interface GigabitEthernet0/1
 description === User Access Port (Restrict Mode) ===
 switchport mode access
 switchport access vlan 10
 
 ! ポートセキュリティを有効化
 switchport port-security
 
 ! 学習できる最大MACアドレス数を「2」に制限(IP電話+PCなどの環境を想定)
 switchport port-security maximum 2
 
 ! MACアドレスの学習方法を動的(Dynamic)に設定
 switchport port-security mac-address sticky
 
 ! 違反時の動作を Restrict(破棄 + ログ出力)に指定
 switchport port-security violation restrict

> 実務Tips:
> mac-address sticky を併用すると、最初に通信した正当なMACアドレスを自動的にコンフィグへ書き込んでくれます。運用初期は sticky で正規端末を学習させ、ポリシーが固まったらスタティックに固定するのが鉄板の運用フローです。

—

状態確認とデバッグのCLIコマンド

現場で「ポートが通信できない」「不正な端末が繋がっていないか確認したい」という時に叩くべきコマンド群です。

# ポートセキュリティ全体のステータスと、各ポートの違反モード、カウンタを確認する
Switch# show port-security interface gigabitethernet 0/1
Port Security : Enabled
Port Status : Secure-up
Violation Mode : Restrict
Maximum MAC Addresses : 2
Total MAC Addresses : 2
Configured MAC Addresses : 0
Sticky MAC Addresses : 2
Last Source Address Vlan : 001a.2b3c.4d5e
Security Violation Count : 14  <-- 違反フレームを何回ドロップしたかがここに記録されます

もしバイオレーションモードを Shutdown にしていて、ポートが err-disable に落ちてしまった場合は、以下の手順で原因を特定して復旧させます。

# 1. どの原因でポートがerr-disableになったかを確認する
Switch# show interfaces status err-disabled

Port      Name               Status       Reason
Gi0/1     User Port          err-disabled psecure-violation  <-- ポートセキュリティ違反が原因

# 2. 該当ポートを一度シャットダウンし、再有効化する
Switch# configure terminal
Switch(config)# interface gigabitethernet 0/1
Switch(config-if)# shutdown
Switch(config-if)# no shutdown
Switch(config-if)# end

—

4. 自動化と監視への応用(Pythonによるスニペット)

モダンなインフラストラクチャでは、CLIを人力で叩くだけでなく、APIやSNMPを通じて「Security Violation Count」のメトリクスを収集し、閾値を超えたらSlackやWebhook経由でアラートを飛ばす仕組みが求められます。

以下は、Pythonの pysnmp ライブラリ(または簡易的な概念実習用スクリプト)を用いて、スイッチのポートセキュリティ違反カウンタを定期ポーリングするイメージコードです。

from pysnmp.hlapi import *
import time
import requests

# 監視対象スイッチの情報
SWITCH_IP = "192.168.1.1"
COMMUNITY_STRING = "public"
# Ciscoポートセキュリティ違反カウンタの一般的なOID(例としてダミーを含む表現)
# 実際の環境ではCISCO-PORT-SECURITY-MIBのオブジェクトIDを使用します
VIOLATION_COUNTER_OID = '1.3.6.1.4.1.9.9.315.1.2.1.1.7.10101' 
SLACK_WEBHOOK_URL = "https://hooks.slack.com/services/T00/B00/X00"

def get_snmp_counter(ip, community, oid):
    """SNMP GETリクエストを送信してカウンタ値を取得する関数"""
    errorIndication, errorStatus, errorIndex, varBinds = next(
        getCmd(SnmpEngine(),
               CommunityData(community, mpModel=0),
               UdpTransportTarget((ip, 161)),
               ContextData(),
               ObjectType(ObjectIdentity(oid)))
    )

    if errorIndication:
        print(f"SNMP Error: {errorIndication}")
        return None
    elif errorStatus:
        print(f"SNMP Error Status: {errorStatus.prettyPrint()}")
        return None
    else:
        for varBind in varBinds:
            return int(varBind[1])

def send_slack_alert(message):
    """異常検知時にSlackへ通知を送る関数"""
    payload = {"text": f":warning: *Port Security Alert*: {message}"}
    response = requests.post(SLACK_WEBHOOK_URL, json=payload)
    if response.status_code != 200:
        print(f"Failed to send Slack alert: {response.text}")

def monitor_port_security():
    previous_count = get_snmp_counter(SWITCH_IP, COMMUNITY_STRING, VIOLATION_COUNTER_OID)
    print(f"Monitoring started. Initial violation count: {previous_count}")

    while True:
        time.sleep(60) # 60秒ごとにポーリング
        current_count = get_snmp_counter(SWITCH_IP, COMMUNITY_STRING, VIOLATION_COUNTER_OID)
        
        if current_count is not None and previous_count is not None:
            if current_count > previous_count:
                diff = current_count - previous_count
                alert_msg = f"ポートセキュリティ違反を検知しました! 増加数: {diff}回 (累計: {current_count})"
                print(alert_msg)
                send_slack_alert(alert_msg)
                
            previous_count = current_count

if __name__ == "__main__":
    # 実運用ではバックグラウンドプロセスや監視基盤(Prometheus/Zabbix等)に組み込みます
    print("Starting Port Security Monitor...")
    # monitor_port_security()

このように、Protect や Restrict モードを選択している場合でも、SNMPやAPIを通じてカウンタの変動を監視していれば、「ログが出ないから気づかない」という最悪のシナリオを防ぐことができます。

—

まとめ

ネットワークのトラブルシューティングにおいて、L2の挙動を正しく把握していることは、シニアエンジニアとしての大きな武器になります。

  • Shutdown: 厳格に遮断したい基幹エリアや無人サーバーラックに。
  • Restrict: 不正をログに残しつつ、ユーザーの利便性やデバッグのしやすさを考慮したいフロアスイッチに。
  • Protect: ログの肥大化を防ぎつつ、上位の監視システムと連携して静かに検知したい環境に。

それぞれのバイオレーションモードが持つ特性を現場の要件に合わせて巧みに使い分け、堅牢で信頼性の高いネットワークインフラを構築していきましょう。皆さんの日々のネットワーク運用の参考になれば幸いです。

コメント

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