VPSサーバーで海外からの不正アクセスを全て遮断する

今までサーバーを自分で管理するVPSとか難しすぎて敬遠していたけれども、どうしても普通のレンタルサーバーではできる事の限界があり、ようやく重い腰をあげてさくらサーバーのVPSを借りてつかっている。

まあ、使ってみたらネット上に情報は結構落ちているし、なんとなくわかってきたような気がする...。
あれやこれやと最低限のセキュリティ設定など初期インストールを終えて一か月たった今。
毎日メールで送られてくるLogwatchに以下のようなアクセスログ(一部文字伏せ)が送られてきた。

 --------------------- httpd Begin ------------------------ 

 Connection attempts using mod_proxy:
    xxx.xxx.93.42 -> xxx.xxmail.netease.com:25: 1 Time(s)
 
 Requests with error response codes
    404 Not Found
       /phpmyadmin/scripts/setup.php: 1 Time(s)
       http://xxx.xxx.24.233/POST_ip_port.php: 17 Time(s)
    405 Method Not Allowed
       xxx.xxmail.netease.com:25: 1 Time(s)
 
 ---------------------- httpd End ------------------------- 

まあ、不正アクセスか。ありもしないファイルを探している感じ?
アクセスしてきているIPを調べたら、やっぱり中国だ。

iptablesで最低限のsshポート変更などはやってましたが、まあhttpのWebサーバーなどは海外からアクセスし放題だったのでこういうことが起こるのは想定内でしたが。
とはいっても、そう簡単に侵入されることはないとは思いますが、毎日毎日しらない人が家の周りをグルグルと徘徊して窓やドアをガチャガチャされているみたいなもん。要するに気持ち悪い。
運営しているのはバリバリの日本語のみで日本人向けのコンテンツだし、海外在住の日本人がアクセスしてくれる可能性も低いので、僕は思い切ってWebサイトの閲覧も含めて海外からのアクセスはすべて遮断することにした。

ここで一つ失敗。
ログをみたところ、まさにガチャガチャされ中だったので、僕は焦った。
ネットで調べて出てきた海外IP遮断のソースをどういう動きをしているかよく調べずに、そのサイトに書いてあるとおりソースのコピペで対応作業していたら、その作業中に、僕自身がSSHもFTPもWebサイトもアクセスできなくなった。
血の気が引くとはまさにこのこと。ソースを確認するとdenyAllの後に日本IPアドレスをAllowしている。
一旦全て拒否してから許可IPを記述するのはアクセス遮断の基本だから問題ないが、その許可IPリストである日本CIDRの取得に失敗して、denyALLしたまま処理が止まっていた。

軽くパニックになった。何もアクセスできないから修正もできない。コンテンツのバックアップもしてなかった。終わった...。
もう、サーバーの再インストールしかないのか...。
と思っていたら、さくらVPSでは管理画面にコンソールがあり、このコンソールはiptablesを無視しているらしくアクセス可能で復旧することができた。今回は非常に助けられたけど、これってセキュリティ的に問題あるんじゃなかろうか?結局さくら管理画面のIDとPASSが抜かれたら終わりってことだよね?

前置きが長くなった。
そういうことがあって、今度は丁寧に調べて手順を踏んで日本以外からのアクセス遮断に対応した。
(参考)iptables で日本以外のアクセスを全部拒否する
こちらのやり方も日本のCIDRを取得するのは変わらないけど、一旦スクリプトでCIDR形式のリストをダウンロードしてリストを作成してからiptablesに反映させているので、さっきのような途中で取得に失敗して青ざめることもない。
やったことをまとめると。

get-iptable-jp.sh を作成。

#!/bin/sh
wget -q -O - http://nami.jp/ipv4bycc/cidr.txt.gz |\
gzip -d |\
grep "JP" |awk '{print "iptables -A ALLOW-JP-INPUT -p all -s ",$2," -j RH-Firewall-1-INPUT"}'\
 > /etc/sysconfig/iptables-allowjp

get-iptable-jp.sh を実行。

# /etc/sysconfig/get-iptable-jp.sh

/etc/sysconfig/iptables-allowjp が作成されてCIDR形式で保存されているか確認する。

iptables -A ALLOW-JP-INPUT -p all -s  1.0.16.0/20  -j RH-Firewall-1-INPUT
iptables -A ALLOW-JP-INPUT -p all -s  1.0.64.0/18  -j RH-Firewall-1-INPUT
iptables -A ALLOW-JP-INPUT -p all -s  1.1.64.0/18  -j RH-Firewall-1-INPUT
iptables -A ALLOW-JP-INPUT -p all -s  1.5.0.0/16  -j RH-Firewall-1-INPUT
iptables -A ALLOW-JP-INPUT -p all -s  1.21.0.0/16  -j RH-Firewall-1-INPUT
...(以下略)

/etc/rc.d/init.d/iptables の start() 内に追記。

if [ -n "$IPTABLES_MODULES" ]; then
	echo -n $"${IPTABLES}: Loading additional modules: "
	ret=0
	for mod in $IPTABLES_MODULES; do
	    echo -n "$mod "
	    modprobe $mod > /dev/null 2>&1
	    let ret+=$?;
	done
	[ $ret -eq 0 ] && success || failure
	echo
    fi
    
    # Load sysctl settings
    load_sysctl

    if [ -s /etc/sysconfig/iptables-allowjp ]
    then
        /bin/sh /etc/sysconfig/iptables-allowjp
    fi

    touch $VAR_SUBSYS_IPTABLES
    return $ret
}

/etc/sysconfig/iptables を修正。

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:ALLOW-JP-INPUT - [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -s 127.0.0.0/8 -j ACCEPT
-A INPUT -s 192.168.0.0/16 -j RH-Firewall-1-INPUT  #ローカルネットワーク許可
-A INPUT -j ALLOW-JP-INPUT
-A INPUT -j DROP
-A RH-Firewall-1-INPUT -i lo -j ACCEPT

iptablesを再起動する。

# service iptables restart

最後に、フィルターがうまく作動しているか確認する。

# iptables -nL

IPアドレスの割り当ては変更されることがあるので、cronで週一回程度、get-iptable-jp.sh を実行して iptablesを再起動するようにする。