2時間で作ってみた;)。
cronでまわすことを想定。監視だけならarpwatch使えば済む話ですが、ルータだけ監視できるとか、最後に書いたような通信遮断やパトランプをまわすとかの処理の追加も簡単にできるので、それなりに有用かなと。
#!/bin/sh
##### 設定用変数 #####
router_ip='192.158.0.254' # ルータのIPアドレス
expected_arp='01:23:45:67:89:ab' # ルータの本来のMACアドレス
alert_to='who@example.com' # 警告メールあて先
##### コマンドパス(FreeBSD用) #####
ARP_CMD='/usr/sbin/arp'
AWK_CMD='/usr/bin/awk'
MAIL_CMD='/usr/bin/mail'
SED_CMD='/usr/bin/sed'
# ARP Spoofing チェック
actual_arp=`$ARP_CMD $router_ip | $AWK_CMD '{print $4}'`
if [ "x$expected_arp" != "x$actual_arp" ]; then
# メール通知
echo "$actual_arp" | \
$MAIL_CMD -s "[Security Alert] ARP Spoofing detected." $alert_to
# 逆ARP Spoofing
$ARP_CMD -d $router_ip
$ARP_CMD -s $router_ip $expected_arp temp pub
# 攻撃ホストの通信遮断
ip_list=`$ARP_CMD -a | $AWK_CMD '{if ($4 == "'$actual_arp'") {print $2}}' | $SED_CMD 's/[()]//g'`
for spoofer_ip in $ip_list
do
echo "$ARP_CMD -d $spoofer_ip"
if [ "x$spoofer_ip" = "x$router_ip" ]; then
echo "$ARP_CMD -s $spoofer_ip $expected_arp temp pub"
else
echo "$ARP_CMD -s $spoofer_ip 00:00:00:00:00:00 temp pub"
fi
done
fi
対策の方は攻撃側のARPテーブルチェック・改ざんの頻度によってはあまり意味が無いです。
あと、FreeBSD以外のOSで使う場合はarpコマンドの出力とかを見て調整する必要があると思います。