やりたいこと
日本以外のIPアドレスは全部拒否したい。(今回は Pingdom も許可する)
iptables で DROP のルールを作成します。
ルールが増えるとパフォーマンスが劣化するらしいので、ipset を使います。
手順
ipset のインストールと初期化
yum で入れるとinitスクリプトとかがインストールされなかったので、こちらから。
rpm -ivh ftp://fr2.rpmfind.net/linux/centos/6.7/os/x86_64/Packages/ipset-6.11-4.el6.x86_64.rpm
初期化します。
ipset create -exist WHITELIST hash:net
ipset create -exist PINGDOM hash:ip
JPのみをホワイトリストに入れる
国別のリストはこちらから取得できるのでありがたく使わせていただく。
wget 'http://nami.jp/ipv4bycc/cidr.txt.gz'
gunzip cidr.txt.gz
sed -n 's/^JP\t//p' cidr.txt | while read i ; do ipset add WHITELIST $i ; done
PingdomのIPアドレスをホワイトリストに入れる
監視で Pingdom を使っている都合でこちらもホワイトリストへ。
curl -s -o pingdom.txt 'https://my.pingdom.com/probes/ipv4'
cat pingdom.txt | while read i ; do ipset add PINGDOM $i ; done
設定の保存
OS を再起動すると消えちゃうので保存。自動起動の設定。
/etc/init.d/ipset save
(/etc/sysconfig/ipset に保存される)
chkconfig ipset on
IPアドレスのリストは変更する可能性があるので、シェルスクリプトとかにして cron で定期的に実行しておきます。こんなかんじ。
#!/usr/bin/env sh
set -ue
NOW=$(date +%Y-%m-%d-%H-%m)
MAILTO='you@example.com'
CIDR_LIST='http://nami.jp/ipv4bycc/cidr.txt.gz'
PINGDOM_LIST='https://my.pingdom.com/probes/ipv4'
alert () {
echo $1
echo $1 | mail -s "ERROR: ipset failed (${NOW})" ${MAILTO}
exit 1
}
TEMP_DIR=/tmp/$$
mkdir -p ${TEMP_DIR} ; cd ${TEMP_DIR}
# clean if trapped or finished
trap "echo Trapped ; rm -rf ${TEMP_DIR}" 1 2 3 15
trap "echo Finished; rm -rf ${TEMP_DIR}" EXIT
# update ipv4
wget -nv -O - http://nami.jp/ipv4bycc/cidr.txt.gz | gunzip -c > cidr.txt || alert "Download failed: CIDR"
ipset create -exist WHITELIST hash:net
ipset flush WHITELIST
sed -n 's/^JP\t//p' cidr.txt | while read i ; do ipset -q add WHITELIST $i ; done
echo "Added $(ipset list WHITELIST | grep -v : | wc -l) to WHITELIST"
# update pingdom
wget --no-check-certificate https://my.pingdom.com/probes/ipv4 || alert "Download failed: Pingdom"
ipset create -exist PINGDOM hash:ip
ipset flush PINGDOM
cat ipv4 | while read i ; do ipset -q add PINGDOM $i ; done
echo "Added $(ipset list PINGDOM | grep -v : | wc -l) to PINGDOM"
# save
echo "Total $(ipset list | grep -v : | wc -l) added"
/etc/init.d/ipset save
exit 0
iptablesのルールを追加
sshの場合。こんなかんじ。
-A INPUT -m state –state NEW -m tcp -p tcp –dport 22 -m set –match-set WHITELIST src -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp –dport 22 -m set –match-set PINGDOM src -j ACCEPT
hashlimitと組み合わせてもいいぞ。
捗れ〜。