ネットワーク管理者の皆さん、こんにちは!日々のネットワーク監視、お疲れ様です。💪 ネットワーク上でどのデバイスがどのIPアドレスを使っているか、常に把握しておくのは大変ですよね。特に、不正なデバイスが接続されたり、IPアドレスの競合が発生したりすると、トラブルの原因になりかねません。
そんな悩みを解決するツールの一つが arpwatch
です。そして、その arpwatch
スイートに含まれる強力なコマンドが arpsnmp
です。このブログ記事では、arpsnmp
の使い方を基本から応用まで、詳しく解説していきます。
arpsnmp とは何か? 🤔
arpsnmp
は、arpwatch
パッケージに含まれるコマンドラインユーティリティです。その主な目的は、ネットワークデバイス(主にルーターやスイッチ)から SNMP (Simple Network Management Protocol) を使ってARP (Address Resolution Protocol) テーブル情報を取得し、イーサネットMACアドレスとIPアドレスのペアリングを追跡することです。
arpwatch
本体は、自身が接続されているネットワークセグメント上のARPパケットを直接監視(リッスン)しますが、arpsnmp
はリモートのデバイスに対してSNMPで問い合わせを行うことで、そのデバイスが保持しているARPキャッシュ情報を収集します。これにより、直接接続されていないセグメントの情報も監視対象に含めることが可能になります。
収集した情報は、arpwatch
と同様のデータベースファイル(デフォルトでは arp.dat
)に記録され、新たなMAC/IPペアの出現、MACアドレスの変更(flip flop)、長期間使用されていなかったペアの再利用などを検知し、管理者にメールで通知したり、syslogに記録したりすることができます。
arpwatch
はパケットキャプチャ (libpcap
) を利用し、arpsnmp
はSNMPを利用してARP情報を収集します。両者は補完的に使用することができます。
arpsnmp の仕組み ⚙️
arpsnmp
は、実際には直接SNMPエージェントと通信するわけではありません。多くの場合、snmpwalk
という別のコマンド(Net-SNMPパッケージに含まれることが多い)を利用して、ターゲットデバイスからARPテーブル情報を取得します。
snmpwalk
は指定されたSNMPコミュニティ名(パスワードのようなもの)とターゲットデバイスのIPアドレスを使って、ARPテーブルに対応するMIB (Management Information Base) の情報を取得します。一般的に、ARPテーブルの情報は ipNetToMediaTable
(RFC 2011 で定義) や、古いRFC1213-MIBの atTable
などに含まれています。
snmpwalk
で取得したARPテーブル情報(通常は特定のフォーマットで標準出力に出力される)をファイルに保存し、そのファイルを arpsnmp
コマンドの入力として与える、という流れで利用されます。
# 例: snmpwalkでルーター(192.168.1.1)からARPテーブルを取得し、ファイルに保存
snmpwalk -v2c -c public 192.168.1.1 ipNetToMediaPhysAddress > router_arp_table.txt
# 保存したファイルを使ってarpsnmpを実行
arpsnmp router_arp_table.txt
arpsnmp
は入力ファイルの内容を解析し、既存のデータベース (arp.dat
) と比較します。
- データベースに存在しない新しい MAC/IP ペアが見つかると「new station」として記録・報告します。
- IPアドレスに対応するMACアドレスが以前と変わっている場合、「changed ethernet address」または「flip flop」として記録・報告します。
- 長期間(デフォルトでは6ヶ月以上)見られなかったペアが再び現れると「new activity」として記録・報告します。
これらの変更は syslog に記録され、設定によっては指定されたメールアドレスに通知が送信されます。
前提条件 ✅
arpsnmp
を使用するには、以下の準備が必要です。
-
arpwatch パッケージのインストール:
arpsnmp
はarpwatch
パッケージに含まれています。お使いのLinuxディストリビューションのパッケージマネージャーでインストールしてください。# Debian / Ubuntu の場合 sudo apt update sudo apt install arpwatch # CentOS / RHEL / Fedora の場合 (EPELリポジトリが必要な場合があります) sudo yum install epel-release # 必要に応じて sudo yum install arpwatch # または sudo dnf install arpwatch
-
Net-SNMP ツールのインストール:
前述の通り、
arpsnmp
は通常snmpwalk
コマンドを利用します。これもパッケージマネージャーでインストールできます。# Debian / Ubuntu の場合 sudo apt install snmp # CentOS / RHEL / Fedora の場合 sudo yum install net-snmp-utils # または sudo dnf install net-snmp-utils
-
監視対象デバイスでのSNMP設定:
ARPテーブルを取得したいルーターやスイッチで、SNMPエージェントを有効にし、
arpsnmp
を実行するサーバーからのアクセスを許可する必要があります。最低限、読み取り専用のコミュニティ名を設定し、そのコミュニティ名を使ってアクセスできるようにACL(アクセス制御リスト)などを設定します。(設定方法はデバイスのベンダーやモデルによって異なります。)⚠️ 注意: SNMPv1/v2c のコミュニティ名は平文でネットワークを流れるため、セキュリティリスクがあります。可能であれば、より安全なSNMPv3の使用を検討してください。また、コミュニティ名は推測されにくい複雑なものにし、アクセス元IPアドレスを限定するなどの対策を講じてください。 -
空のデータベースファイルの作成:
arpsnmp
を初めて実行する前に、データベースファイル(デフォルト:arp.dat
)を空のファイルとして作成しておく必要があります。通常は/var/lib/arpwatch/
ディレクトリ(ディストリビューションによって異なる場合があります)に作成します。# デフォルトのディレクトリとファイル名の場合 sudo touch /var/lib/arpwatch/arp.dat # arpwatchを実行するユーザーが書き込めるように権限調整が必要な場合もあります # 例: Debian系でarpwatchユーザーが存在する場合 sudo chown arpwatch:arpwatch /var/lib/arpwatch/arp.dat
arpsnmp コマンドの使い方 🛠️
arpsnmp
の基本的な構文は以下の通りです。
arpsnmp [オプション] <入力ファイル> [...]
<入力ファイル>
には、snmpwalk
などで取得したARPテーブル情報を含むファイルを指定します。複数のファイルを指定することもでき、その場合は各ファイルの情報がマージされます。
主なオプションを見ていきましょう。利用可能なオプションは arpwatch
のバージョンやディストリビューションによって若干異なる場合があります。
オプション | 説明 |
---|---|
-d |
デバッグモードを有効にします。レポートがメール送信されず、標準エラー出力 (stderr) に表示されます。問題の切り分けに役立ちます。 |
-f <データファイル> |
使用するイーサネット/IPアドレスデータベースのファイル名を指定します。デフォルトは arp.dat です。 |
-m <メールアドレス> |
レポートを送信するメールアドレスを指定します。(Debian系などで利用可能) デフォルトはローカルマシンの root ユーザーです。 |
-s <sendmailパス> |
メール送信に使用するプログラム(例: /usr/sbin/sendmail )へのパスを指定します。(Debian系などで利用可能) レポートをメールではなくログファイルにリダイレクトする際などにも使えます。 |
-w <メールアドレス> |
-m と同様に、レポートの宛先メールアドレスを指定します。(OpenSUSEなどのmanページに記載) |
-W <メールアドレス> |
レポートの送信元 (From) メールアドレスを指定します。(OpenSUSEなどのmanページに記載) |
-q |
レポートのログ記録や標準エラー出力への表示を抑制します。(OpenSUSEなどのmanページに記載) |
-D <ディレクトリ> |
arpwatch の作業ディレクトリを指定します。データベースファイルなどがこのディレクトリにあるとみなされます。デフォルトは /usr/local/arpwatch や /var/lib/arpwatch など、インストールによって異なります。(OpenSUSEなどのmanページに記載) |
-C |
データベースファイル (arp.dat ) にコンパクトな形式 (例: 0:8:e1:1:2:d6 ) でMACアドレスを記録します。(OpenSUSEなどのmanページに記載) |
-Z |
データベースファイル (arp.dat ) にゼロパディングされた形式 (例: 00:08:e1:01:02:d6 ) でMACアドレスを記録します。(OpenSUSEなどのmanページに記載) |
入力ファイルの形式
arpsnmp
が期待する入力ファイルの形式は、arp.dat
と同じです。基本的には以下の情報がスペース区切りで並んだテキストファイルです。
MACアドレス IPアドレス [タイムスタンプ] [ホスト名]
- MACアドレス: イーサネットのMACアドレス (例:
00:11:22:aa:bb:cc
) - IPアドレス: 対応するIPv4アドレス (例:
192.168.1.100
) - タイムスタンプ (オプション): エポック秒(1970年1月1日からの経過秒数)。省略された場合は
arpsnmp
が実行された現在時刻が使用されます。 - ホスト名 (オプション): 単純なホスト名。
snmpwalk
の出力はそのままではこの形式ではない場合が多いです。そのため、snmpwalk
の出力を整形して arpsnmp
に渡すスクリプトが必要になることがあります。
例えば、arpfetch
というスクリプト(arpwatch
に含まれることがある)は、SNMPでARPテーブルを取得し、適切な形式で出力する機能を持っています。
# arpfetch を使う例 (コミュニティ名が public、ターゲットが 192.168.1.1 の場合)
arpfetch 192.168.1.1 public > router_arp.txt
arpsnmp router_arp.txt
実践的な使い方とスクリプト例 🚀
arpsnmp
は通常、定期的に実行してネットワークの変化を継続的に監視するために使われます。cronジョブとして設定するのが一般的です。
以下は、特定のルーター (192.168.1.1
) のARPテーブルを1時間ごとに取得し、arpsnmp
で処理する基本的なシェルスクリプトの例です。
#!/bin/bash
# 設定変数
ROUTER_IP="192.168.1.1"
COMMUNITY="public" # セキュアなコミュニティ名に変更してください!
SNMPWALK_CMD="/usr/bin/snmpwalk" # 環境に合わせてパスを確認
ARPSNMP_CMD="/usr/sbin/arpsnmp" # 環境に合わせてパスを確認
ARP_DATA_FILE="/var/lib/arpwatch/arp.dat"
TEMP_ARP_FILE="/tmp/arp_table_${ROUTER_IP}.txt"
MIB_OID="ipNetToMediaPhysAddress" # 一般的なARPテーブルのOID (環境により異なる可能性あり)
# 古い機器の場合: MIB_OID="atPhysAddress"
# snmpwalk でARPテーブルを取得
# -v2c: SNMPバージョン2cを使用
# -c: コミュニティ名を指定
# -OQ: OIDのみを出力しない
# -OU: OIDを完全に表示しない
# -On: OIDを数値で表示
# -Ot: タイムティックを数値で表示しない
# $SNMPWALK_CMD -v2c -c "$COMMUNITY" -OQ -OU -On -Ot "$ROUTER_IP" "$MIB_OID" > "$TEMP_ARP_FILE"
# snmpwalkの出力形式によっては整形が必要
# 例: "IP-MIB::ipNetToMediaPhysAddress.インターフェースID.IPアドレス = Hex-STRING: MACアドレス" のような出力を想定
# この場合、awkなどで "MAC IP" 形式に変換する必要がある
# === ここから snmpwalk 出力の整形例 (実際の出力に合わせて調整が必要) ===
# 例: RFC1213-MIB::atPhysAddress.インターフェースID.IPアドレス = Hex-STRING: XX XX XX XX XX XX
# $SNMPWALK_CMD -v2c -c "$COMMUNITY" -OQ -On "$ROUTER_IP" atPhysAddress | awk '{
# split($1, oid_parts, ".");
# ip_addr = oid_parts[length(oid_parts)]; # OIDの末尾がIPアドレス
# mac_addr = "";
# for (i = 4; i <= NF; i++) { # "Hex-STRING:" の後からMACアドレス部分
# mac_addr = mac_addr sprintf("%s:", $i);
# }
# sub(/:$/, "", mac_addr); # 末尾のコロンを削除
# print mac_addr, ip_addr;
# }' > "$TEMP_ARP_FILE"
# 例: IP-MIB::ipNetToMediaPhysAddress.インターフェースID.IPアドレス = STRING: "MACアドレス" (文字列の場合)
# $SNMPWALK_CMD -v2c -c "$COMMUNITY" -OQ -On "$ROUTER_IP" ipNetToMediaPhysAddress | awk '{
# split($1, oid_parts, ".");
# ip_addr = oid_parts[length(oid_parts)]; # OIDの末尾がIPアドレス
# mac_addr = $4; # "STRING:" の後がMACアドレス文字列
# gsub(/"/, "", mac_addr); # ダブルクォートを削除
# print mac_addr, ip_addr;
# }' > "$TEMP_ARP_FILE"
# arpfetchが使える場合は、整形が不要なことが多い
/usr/sbin/arpfetch "$ROUTER_IP" "$COMMUNITY" > "$TEMP_ARP_FILE"
# === 整形例ここまで ===
# snmpwalkが成功したかチェック (簡単なチェック)
if [ $? -ne 0 ] || [ ! -s "$TEMP_ARP_FILE" ]; then
echo "Error: Failed to fetch ARP table from $ROUTER_IP via SNMP." >&2
# 必要に応じてエラー通知などを追加
exit 1
fi
# arpsnmp を実行 (-f でデータベースファイルを指定)
"$ARPSNMP_CMD" -f "$ARP_DATA_FILE" "$TEMP_ARP_FILE"
# 一時ファイルを削除
rm -f "$TEMP_ARP_FILE"
exit 0
snmpwalk
の出力整形部分は、実際のルーター/スイッチが出力する形式に合わせて大幅な調整が必要です。snmpwalk
コマンドを単体で実行し、出力形式を確認してから整形ロジックを実装してください。もし arpfetch
が利用可能であれば、そちらを使う方が簡単です。
このスクリプトを /usr/local/sbin/update_arp_data.sh
などとして保存し、実行権限を与えます。
sudo chmod +x /usr/local/sbin/update_arp_data.sh
次に、cronジョブとして登録します。 sudo crontab -e
を実行し、以下のような行を追加します。(以下の例は毎時0分に実行)
0 * * * * /usr/local/sbin/update_arp_data.sh >> /var/log/arpupdate.log 2>&1
これにより、定期的にルーターのARP情報が arpsnmp
によってチェックされ、変更があれば arp.dat
が更新され、syslog やメールで通知が行われます。
arpwatch
パッケージには bihourly.sh
というスクリプトが含まれていることもあり、これは複数のホストリストファイルを読み込んで arpsnmp
を実行する例を提供しています。このスクリプトを参考に、複数のデバイスを監視する仕組みを構築することもできます。
レポートメッセージの解釈 📨
arpsnmp
(および arpwatch
) が生成する主なレポートメッセージには以下のようなものがあります。これらは syslog やメール通知で確認できます。
メッセージタイプ | 意味 |
---|---|
new station |
これまでデータベースに記録されていなかった新しいMACアドレスが検出されました。 |
changed ethernet address |
特定のIPアドレスに紐づくMACアドレスが、以前記録されていたものから変更されました。ARPスプーフィング攻撃や、デバイスの交換などが考えられます。 |
flip flop |
MACアドレスが、直近で記録されていたものと、その一つ前に記録されていたものの間で変更されました。ネットワークインターフェースの冗長化構成などで発生することがありますが、不安定な状態や攻撃の可能性も示唆します。 |
new activity |
長期間(デフォルト6ヶ月以上)活動が見られなかったMAC/IPペアが再びネットワーク上に現れました。 |
reused old ethernet address |
MACアドレスが、直近のものから、過去(3番目以前)に使用されていたものに変更されました。「flip flop」に似ていますが、より古いアドレスへの変更を示します。 |
ethernet broadcast |
MACアドレスがブロードキャストアドレス(例: ff:ff:ff:ff:ff:ff)として検出されました。通常は異常な状態です。 |
ip broadcast |
IPアドレスがブロードキャストアドレスとして検出されました。 |
bogon |
送信元IPアドレスが、監視対象のネットワーク範囲外のものです。設定ミスや不正なデバイスの可能性があります。(arpwatch の -n オプションでローカルネットワーク範囲を指定することで抑制できる場合があります) |
ethernet mismatch |
ARPパケット内の送信元MACアドレスと、イーサネットフレームヘッダの送信元MACアドレスが一致しません。ARPスプーフィングの兆候である可能性があります。 |
これらのメッセージを監視することで、ネットワーク上の変化や潜在的な問題を早期に発見することができます。特に changed ethernet address
や ethernet mismatch
はセキュリティインシデントの可能性を示すため、注意深く調査する必要があります。
まとめ ✨
arpsnmp
は、arpwatch
スイートの一部として、SNMPを利用してリモートデバイスのARPテーブルを監視するための便利なツールです。直接パケットをキャプチャできないネットワークセグメントの情報を収集したり、ルーターやL3スイッチが持つ広範なARP情報を効率的に取得したりするのに役立ちます。
設定には snmpwalk
の利用や出力の整形、監視対象デバイスでのSNMP設定など、いくつかのステップが必要ですが、一度設定してしまえば、cronジョブなどで自動化し、ネットワーク上のMACアドレスとIPアドレスのペアリングの変化を継続的に監視できます。
これにより、不正デバイスの接続、IPアドレスの競合、ARPスプーフィング攻撃などの兆候を早期に検知し、ネットワークの安定性とセキュリティを向上させることが期待できます。🔧🛡️
ぜひ、arpsnmp
を活用して、より堅牢なネットワーク監視体制を構築してみてください!
コメント