管理しているWebサーバのトラフィックはほとんどが中国と韓国からのアタック。帯域を食い潰し、メモリを使い切る程の負荷が続いています。仕方が無いので国単位でフィルタすることにしました。主義とか思想的な意図はないのですが、運用上やむを得ないので。環境はFreeBSD8.0。
IPアドレスの取得
apnicに国別のIPアドレスリストがあります。こちらでCIDR表記化されているので使わせてもらいました。
# wget http://nami.jp/ipv4bycc/cidr.txt
# perl -ne 'print \
"block in log quick proto tcp from $2 to any port = 80 group 100\n" \
if /^(CN|KR|TW|HK)\t(.*)/' cidr.txt > ipf.tmp
こんな感じでCIDRブロックのリストをipf.rulesに記述するための表記に変更してファイル化しておきます。上の例では、中国・韓国・台湾・香港に割り当てられているIPアドレスを取り出しています。
ちなみに2010/04/02現在の上記行数は2228行。長過ぎるので割愛しますが以下のような記述になります。
block in log quick proto tcp from 27.8.0.0/13 to any port = 80 group 100 block in log quick proto tcp from 27.16.0.0/12 to any port = 80 group 100 block in log quick proto tcp from 27.36.0.0/14 to any port = 80 group 100 block in log quick proto tcp from 27.40.0.0/13 to any port = 80 group 100 (以下続く)
ipfilterのインストール
# kldstat ※カーネルの状態を表示 # kldload ipl ※モジュールをカーネルにロード # kldstat # vim /boot/loader.conf ipl_load="YES" # vim /etc/rc.conf ipfilter_enable="YES" ipfilter_rules="/etc/ipf.rules" ipfilter_flags="" ipmon_enable="YES" ipmon_flags="-D /var/log/ipflog" touch /var/log/ipflog
以下、フィルタルールの設定。
# vim /etc/ipf.rules
#
# The following routes should be configured, if not already:
#
# route add 192.168.0.100 localhost 0
#
# 不正なIPパケットをすべて拒否してログに記録
block in log quick from any to any with ipopts
block in log quick proto tcp from any to any with short
########################################################
# 外部への出力(グループ 150)
pass out on bge0 all head 150
block out from 127.0.0.0/8 to any group 150
block out from any to 127.0.0.0/8 group 150
block out from any to 192.168.0.100/32 group 150
########################################################
# 外部(Internet)からの入力(グループ 100)
pass in on bge0 all head 100
# アドレス偽装防止
block in from 127.0.0.0/8 to any group 100
block in from 192.168.0.100/32 to any group 100
# UDP パケットもデフォルトで拒否
block in proto udp all group 100
# 接続が確立されたパケットの通過を許可
pass in quick proto tcp all flags A/A group 100
# 外部からの SSH接続を許可する
pass in quick proto tcp from any to any port = 22 flags S/SA group 100
# 外部からのFTPサーバへの接続を許可する
pass in log first quick proto tcp from any to any port = 21 flags S keep state group 100
# PASVポート
pass in log first quick proto tcp from any to any port 10000 >< 10100 flags S keep state group 100
# 外部からのDNSサーバへの接続を許可する
pass in quick proto tcp from any to any port = 53 flags S/SA group 100
# 中国、韓国からのアクセスを遮断
ここに上記の ipf.tmpの内容を書き込む。
# 外部からのWebサーバへの接続を許可する
pass in quick proto tcp from any to any port = 80 flags S/SA group 100
pass in quick proto tcp from any to any port = 443 flags S/SA group 100
# それ以外の外部からの TCP 接続を拒否し、ログに残す
block in log quick proto tcp all flags S/SA group 100
# 外部の DNS に問い合わせた帰りのパケット
pass in proto udp from any port = 53 to any group 100
# 外部NTPサーバからの帰りは許可
pass in proto udp from any port = 123 to any group 10
# RFC2979
pass in proto icmp all icmp-type 3 group 100
########################################################
# ループバックへのルール(グループ 0)
pass in quick on lo0 all
pass out quick on lo0 all
# ipf -Fa -Z -f /etc/ipf.rules ※設定の反映 # ipfstat -i ※入力側のルール確認
設定を反映させて完了。後は「tail -f /var/log/ipflog」とかして楽しみます。
対処の結果、滝のように流れていたhttpdのログはほとんどなくなり、CPU、メモリ、swapなどの全ての負荷がほぼゼロになりました。ちょっと寂しいかも。でもよかった。
参考
http://www.lns.sci.osaka-u.ac.jp/lab/admin/ipfilter.html
http://nami.jp/ipv4bycc/
コメント (2)
ども。
参考になりましたー。
これは実際に投入しているルールですか?
投稿者: ぼぶ男 | 2010年04月06日 00:10
日時: 2010年04月06日 00:10
ほぼそのままです。IPアドレスを変えていたり、その他使用するport3000とかを加えている程度ですね。
投稿者: ts | 2010年04月06日 00:48
日時: 2010年04月06日 00:48