ipsetを使って国別のFireWall設定

Web記事を探していたら、国別のFireWallでのブロックで ipset というものが使える との情報から、試してみた。 ipsetを使った理由は、iptables に、別物管理したい国別ルールを入れたくなかったため。

ちなみに、ipdeny から取得した CIDR なIPv4なアドレスブロック数は、以下のようになった。 ロシアが多いのは納得だけど、インターネットの普及のイメージとして中国≒インド≒韓国 ぐらいの感じを抱いていたけど、中国のアドレスブロックの数はインド・韓国の3倍。 人口の影響かな?後発出遅れで細切れアドレスになったのかな....

$ wc -l *.zone
  2635 cn.zone
   602 id.zone
   706 in.zone
   659 kr.zone
  6520 ru.zone
   388 tw.zone
 11510 合計

また、mergecidr.pl によって、隣接CIDRをマージさせてみたけど、 元々の11510件が、併合で9255件に減らすことができた(20%減)。

mergecidr.pl

#!/usr/bin/perl
my %net = () ;
while( <> ) {
    if ( /^(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)$/ ) {
        my $ip,$bt;
        ($ip,$bt) = ( ($1 << 24) + ($2 << 16)
                        + ($3 << 8) + $4 , $5 ) ;
        $net{$ip} = $bt ;
        # printf( "# %08x/%02d\n" , $ip , $bt ) ;
    }
}
my $count = 1 ;
while( $count > 0 ) {
    my $lip = 0 ;
    my $lbt = 0 ;
    $count = 0 ;
    foreach my $ip ( sort { $a <=> $b } keys %net ) {
        my $bt = $net{$ip} ;
        if ( $bt > 0 ) {
            if ( $lbt == $bt && $bt > 1 ) {
                # printf( "%08x/%02d\n" , $ip , $bt ) ;
                my $dbt = $bt - 1 ;
                my $mask = (((1 << $dbt) - 1)
                         << (32 - $dbt)) ;
                if ( ($ip & $mask) == ($lip & $mask) ) {
                    $count++ ;
                    undef $net{$lip} ;
                    undef $net{$ip} ;
                    $net{$ip & $mask} = $dbt ;
                    #printf( "%08x/%08x/%02d\n" ,
                    #   ($ip & $mask) , $mask , $dbt ) ;
                }
            }
            $lip = $ip ;
            $lbt = $bt ;
        }
    }
}
foreach my $ip ( sort {$a <=> $b } keys %net ) {
    my $bt = $net{$ip} ;
    if ( $bt > 0 ) {
        printf( "%d.%d.%d.%d/%d\n" ,
                (($ip >> 24) & 0xff) ,
                (($ip >> 16) & 0xff) ,
                (($ip >>  8) & 0xff) ,
                ( $ip        & 0xff) ,
                $bt ) ;
    }
}

geoipdeny.sh

参考サイトのスクリプトをほぼ、そのまま借用。

DIR="/usr/local/etc/geoipdeny"
ZONEURL="http://www.ipdeny.com/ipblocks/data/countries"

# download zonefile
for GEO in cn.zone kr.zone ru.zone tw.zone id.zone in.zone
do
        /usr/bin/wget -q -O - "$ZONEURL/$GEO" \
        | /bin/grep -v "^#|^$" > $DIR/$GEO
done

/usr/sbin/ipset destroy GEOIPDENY > /dev/null 2>&1
/usr/sbin/ipset create GEOIPDENY hash:net

for IP in ` $DIR/mergecidr.pl $DIR/*.zone `
do
        /usr/sbin/ipset add GEOIPDENY $IP
done

/usr/sbin/ipset save GEOIPDENY > $DIR/geoipdeny.store
/usr/sbin/ipset destroy GEOIPDENY

fermの設定に登録

自宅のFirewallの設定には、iptablesな設定を、ブロック的にまとめて記載できる、 ferm というのを使っているので、その設定の中に、上記でできた ipset を参照させる。

(( 設定ファイルの先頭に ))
@hook post  "/usr/sbin/ipset destroy GEOIPDENY" ;
@hook pre   "/bin/cat /usr/local/etc/geoipdeny/geoipdeny.store
                          | /usr/sbin/ipset restore" ;
@hook flush "/usr/sbin/ipset destroy GEOIPDENY" ;

(( Firewallのブラックリストな設定部分に ))
mod set set GEOIPDENY ( src dst ) REJECT ;

次は動作確認。

# geoiplookup www.baidu.cn
GeoIP Country Edition: CN, China
# ipset test GEOIPDENY www.baidu.cn
220.181.111.147 is in set GEOIPDENY.
# w3m http://www.baidu.ch
これがなぜか接続成功するんだよな....

ということで、まだなにかオカシイ?

# export http_proxy=http://中国のOpenProxy:xxxx
# w3m http://tsaitoh.net/
Connection Refused...
おお、ちゃんと拒否られるな....

自宅からだと、間に透過PROXYでも入っているのかな...

 

2017年2月

      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28        

ウェブページ

アーカイブ

Webデータ

このブログ記事について

このページは、T-Saitohが2012年10月19日 08:54に書いたブログ記事です。

ひとつ前のブログ記事は「棚壁紙と並べ方」です。

次のブログ記事は「iPhone5+エラー防止シートx2+Edyで成功」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。