話題の記事

iptablesを設定して日本のIPだけを許可する

2013.03.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

shellを作ってみる

Webサーバを立ち上げる機会が増えてきたので、事前にできる限りの対策はやっておこうと思い、国単位でのアクセス制御をやってみたので自分用のメモとして残します。

世界の国別IPv4アドレス割り当てリストが公開されていますのでその情報を活用させてもらうことにします。

動作させた環境はAWS Amazon Linuxです。

※あくまでも以下はサンプルのシェルなので、適用する場合は自己責任でお願いします。自身すら入れなくなる可能性もあるのでご注意を。

#!/bin/sh

IPLIST=cidr.txt

# 初期化をする
iptables -F                     # Flush
iptables -X                     # Reset
#iptables -P INPUT DROP         # 受信はすべて破棄
iptables -P OUTPUT ACCEPT       # 送信はすべて許可
iptables -P FORWARD DROP        # 通過はすべて破棄

# サーバーから接続を開始した場合の応答を許可する。
iptables -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -s 127.0.0.1 -j ACCEPT

if [ -z "$1" ]; then
  date=`date -d '1 day ago' +%Y%m%d`
else
  date="$1"
fi

if [ -e $IPLIST ]; then
    mv $IPLIST "${IPLIST}_${date}"
fi

# 最新のIPリストを取得する
wget http://nami.jp/ipv4bycc/$IPLIST.gz
gunzip -d $IPLIST.gz

# ダウンロードしてきたIPリストで日本のIPだけを許可するようにする
sed -n 's/^JP\t//p' $IPLIST | while read ipaddress; do
    iptables -A INPUT -s $ipaddress -j ACCEPT
done

# iptablesによってDROPされたアクセスのログを取る
iptables -A INPUT -m limit --limit 1/s -j LOG --log-prefix '[IPTABLES INPUT DROP] : '
iptables -P INPUT DROP          # 受信はすべて破棄

#設定を保存する場合はコメントを外す
#/etc/init.d/iptables save

最新の日本に割り当てられたIPアドレス一覧などはAPNICより取得するのが望ましいでしょうね。.htaccessで制限する場合はこちらで.htaccessのリストがダウンロードできるようです。

Googlebotのアクセスを許可する場合はこちらにIPアドレスの掲載があるようなので必要に応じて許可するように設定する必要があります。

検証してみる

まずはEU (Ireland)リージョンに立ち上げているサーバから確認してみようと思いSSHでログインしてみました。そのサーバからリクエストを投げてみると。。。

# curl http://54.248.xxx.xxx/ (←実際は上のshellを実行したサーバのIPアドレスです)
[ec2-user@ip-10-227-206-239 ~]$ curl http://54.248.xxx.xxx
curl: (7) couldn't connect to host

どうやらブロックしてくれてるようです
iptablesによってDROPされたアクセスログを収集するようにしているので、そのログ内容を見てみたいと思います。

# grep "IPTABLES INPUT DROP" /var/log/messages
Mar 13 10:44:24 ip-10-156-93-145 kernel: [  310.800505] [IPTABLES INPUT DROP] : IN=eth0 OUT= MAC=12:31:50:04:5e:67:fe:ff:ff:ff:ff:ff:08:00 SRC=54.228.39.117 DST=10.156.93.145 LEN=60 TOS=0x00 PREC=0x00 TTL=47 ID=46020 DF PROTO=TCP SPT=60856 DPT=80 WINDOW=14600 RES=0x00 SYN URGP=0
Mar 13 10:44:25 ip-10-156-93-145 kernel: [  311.798058] [IPTABLES INPUT DROP] : IN=eth0 OUT= MAC=12:31:50:04:5e:67:fe:ff:ff:ff:ff:ff:08:00 SRC=54.228.39.117 DST=10.156.93.145 LEN=60 TOS=0x00 PREC=0x00 TTL=47 ID=46021 DF PROTO=TCP SPT=60856 DPT=80 WINDOW=14600 RES=0x00 SYN URGP=0
Mar 13 10:44:27 ip-10-156-93-145 kernel: [  313.802103] [IPTABLES INPUT DROP] : IN=eth0 OUT= MAC=12:31:50:04:5e:67:fe:ff:ff:ff:ff:ff:08:00 SRC=54.228.39.117 DST=10.156.93.145 LEN=60 TOS=0x00 PREC=0x00 TTL=47 ID=46022 DF PROTO=TCP SPT=60856 DPT=80 WINDOW=14600 RES=0x00 SYN URGP=0
Mar 13 10:44:31 ip-10-156-93-145 kernel: [  317.814157] [IPTABLES INPUT DROP] : IN=eth0 OUT= MAC=12:31:50:04:5e:67:fe:ff:ff:ff:ff:ff:08:00 SRC=54.228.39.117 DST=10.156.93.145 LEN=60 TOS=0x00 PREC=0x00 TTL=47 ID=46023 DF PROTO=TCP SPT=60856 DPT=80 WINDOW=14600 RES=0x00 SYN URGP=0
Mar 13 10:44:39 ip-10-156-93-145 kernel: [  325.830041] [IPTABLES INPUT DROP] : IN=eth0 OUT= MAC=12:31:50:04:5e:67:fe:ff:ff:ff:ff:ff:08:00 SRC=54.228.39.117 DST=10.156.93.145 LEN=60 TOS=0x00 PREC=0x00 TTL=47 ID=46024 DF PROTO=TCP SPT=60856 DPT=80 WINDOW=14600 RES=0x00 SYN URGP=0
Mar 13 10:44:56 ip-10-156-93-145 kernel: [  341.862083] [IPTABLES INPUT DROP] : IN=eth0 OUT= MAC=12:31:50:04:5e:67:fe:ff:ff:ff:ff:ff:08:00 SRC=54.228.39.117 DST=10.156.93.145 LEN=60 TOS=0x00 PREC=0x00 TTL=47 ID=46025 DF PROTO=TCP SPT=60856 DPT=80 WINDOW=14600 RES=0x00 SYN URGP=0

/var/log/messagesのブロックIPアドレスを見てみると54.228.39.117のアドレスで来ているようです。AWSのリージョン毎の公開IPアドレス一覧(2013年3月4日時点)を見ると確かにEU (Ireland)で割り当てられている範囲にありました。東京リージョンの公開IPアドレス一覧も追加されているようなので、許可するようにiptables側に追加設定しておきます。

先ほどのサンプルshellのsed~doneの後にAmazon EC2のAsia Pacific (Tokyo) に割り振られているIPレンジを追加しておきます。ELBを利用している場合はそのIPを許可させておく必要があるので追加します。

# Amazon EC2のAsia Pacific (Tokyo) に割り振られているIPレンジを許可する
iptables -A INPUT -s 46.51.224.0/19 -j ACCEPT
iptables -A INPUT -s 54.248.0.0/15 -j ACCEPT
iptables -A INPUT -s 103.4.8.0/21 -j ACCEPT
iptables -A INPUT -s 175.41.192.0/18 -j ACCEPT
iptables -A INPUT -s 176.34.0.0/18 -j ACCEPT
iptables -A INPUT -s 176.32.64.0/19 -j ACCEPT
iptables -A INPUT -s 54.250.0.0/16 -j ACCEPT #←このIPレンジが追加されていました。

# ELB IPアドレス許可(下記IPは利用環境により変わる可能性あり)
iptables -A INPUT -s 10.146.59.208 -j ACCEPT
iptables -A INPUT -s 10.146.70.15 -j ACCEPT

まとめ

日本のIPアドレスを踏み台にしてこられるとスルーされてしまうので、日々チェックを行いながら運用する必要があるので継続したログ監視等は必要です。あとはこのshellをcronに組み込んで定期的に実行するのもよいかもしれません。