弁財天

ゴフマン「専門家を信じるのではなく、自分自身で考えて判断せよ」

arpwatchで特定のMACアドレスが持ってるDHCPクライアントのIPアドレスをモニターして、サーバー側のiptablesに利用する。

MACアドレスでブロックしてあるLANの一区画があって、 そのDHCPアドレスは会社全体で割り振られるので ネットワークアドレスでは分離できないようになってる。

固定IPアドレスのPCならそのまま使えばいいけど、 DHCPで毎日PC起動時に動的に割り振られるIPアドレスが問題。 サーバは別ビルにあるのでMACアドレスを使ったF/Wのルールは使えない。

なので、arpwatchでMACアドレスが使用するIPアドレスをモニターし、MACアドレスからIPアドレスがわかる仕掛けを構築してしまう。 サーバ側の公開したくないsshなどのポートはモニターしてるMACアドレスのIPアドレスからのアクセスしかできないようにしたいのだ。

既にLinuxの2つのEthernet I/Fを使ってブリッジ型F/Wにしてるので、そのLinuxにarpwatchを設置してしまう。

具体的にはiptablesの--mac-sourceのルールからMACアドレスを取得。arpwatchが構築した/var/lib/arpwatch/arp.datからIPアドレスを取得。そのIPアドレスだけを許可するルールをサーバ側のiptablesに追加するだけ。意外と簡単。

LANでブリッジ型F/WになってるLinux(CentOS5.x)にarpwatch-NG-1.7-3.el5.pp.x86_64.rpmを導入。

/etc/init.d/arpwatchを手メンテ
daemon arpwatch -u arpwatch -i bond0 -s /somewhere/arpwatch_dummy.sh
-s /somewhere/arpwatch_dummy.shはメール発報を抑止するexit 0するだけのシェル。

社内LANのMACアドレスとIPアドレスのリストが/var/lib/arpwatch/arp.datにリアルタイムで作成される。 現在4466件くらい。MACアドレスに振られたIPアドレスが履歴になってるかんじ。 社内LAN内の約2000台のアドレスがたまる。

mac-source.sh

#!/bin/sh

cd /somwhere

grep mac-source /etc/sysconfig/iptables|grep -v "^#"|while read line
do
	MAC=`echo $line|awk '{print $6}'|sed 's/-/:/g'`
	perl ip_from_arpwatch.pl $MAC
done

ip_from_arpwatch.pl

#!/usr/bin/perl

my @b = split(/:/, $ARGV[0]);
my $mac = sprintf("%x:%x:%x:%x:%x:%x",
	hex($b[0]), hex($b[1]), hex($b[2]),
	hex($b[3]), hex($b[4]), hex($b[5]));
my $TARGET = lc($mac);

open(ARP, "/var/lib/arpwatch/arp.dat") or die("Can\'t open...$!");

my $t = 0;
my $last_line;
my $last_ip = "N/A";

while() {
	chomp;
	if (/$TARGET/ && (/pc_hoge/ || /pc_wahaha/)) {
		my @arp = split(/\t/);
		if ($arp[2] > $t) {
			$last_ip = $arp[1];
			$t = $arp[2];
			$last_line = $_;
		}
	}
}

if ($last_ip ne "N/A") {
	my @l = split(/\t/, $last_line);
	print "# " . $l[0] . "\t" . $l[1] . "\t" . $l[3] . "\n";
	print "-A INPUT -s $last_ip/32 -j ACCEPT\n"
}

# End of FILE.

もちろんARPスプーフィングとかPCの電源を落としてるときに接続許可を出してるMACアドレスでアクセスするとか、いろいろ攻略ポイントはあるのだろうが、何もない無防備な状態よりはマシだろう。

arpwatch でMACアドレスをかき集める - いますぐ実践! Linuxシステム管理 / Vol.255:

さらに、/var/lib/arpwatch/arp.dat(あるいはI/F名.dat)にも情報を出力します。 15分おきに、1行に1つ、下記のフォーマットで出力します。

  MACアドレス  IPアドレス  日時  ホスト名  I/F名

個々の間は、上記ではスペースになっていますが、実際はタブです。
具体的には、こんな感じです。(下記もスペースに変換しています。)

  $ sudo cat /var/lib/arpwatch/arp.dat
  00:01:02:03:04:05    192.168.1.1     1392463365     foo     eth0
  06:07:08:09:0a:0b    192.168.1.2     1392463369         eth0

日時は、1970年1月1日0時0分0秒から現在までの秒です。dateコマンドで変換できます。

  $ date --date='@1392463365'
  2014年  2月 15日 土曜日 20:22:45 JST

…と思ったら、RedHat系では、日付の情報まででした。

#!/bin/sh

sec2date () {
        #date --date='@'$1 +'%Y-%m-%d %H:%M:%S'
        date --date='@'$1
}

grep $1 /var/lib/arpwatch/arp.dat|while read line
do
        #echo "*** " $line
        S=`echo $line|awk '{print $3}'`
        SS=`sec2date $S`
        echo $SS $line
done
/var/lib/arpwatch/arp.datの3列めは時刻秒なのだとか。 arpwatchが最後に確認した時刻ですな。 dateコマンドで変換できる。

投稿されたコメント:

コメント
コメントは無効になっています。