iptablesでファイアウォール

#はじめに
VPNを構築して数日。
ログを確認してみると、109.188.127.144からBruteForceAttack的なアクセスが。。。

ロシアの「Yota Clients」って所らしく、日本で言うところのドコモとかauみたいな企業っぽい？
その他にも単発でチラホラと、海外からつつかれてるようでした。
よく分からんけど、海外からのアクセスは遮断してしまうのが手っ取り早そう。。。
ということで、iptablesを設定してみました。
その時にやった事のメモです。

#やりたい事
1. 国外からのアクセスは一律ブロック
2. 国内からのアクセスは特定のポートを許可（VPN関連）
3. ローカルエリアからのアクセスは、特定のポートを許可（SSH等）
4. ipsecの認証処理（ポート:500）に連続してアクセスしてきた接続元はブロック

#接続元の判定について
ここを参考にしました。
[国内からの接続のみ許可して海外からの接続を遮断する](http://vogel.at.webry.info/201306/article_2.html)


```cron:crontab
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 5 * * * /root/tool/iptables/iptablesSetup.sh
```

※PATHは、cronのデフォルトでは「/usr/bin:/bin」だけなので追加してます。

```Bash:iptablesSetup.sh
# WHITE_LIST という名前でユーザ定義チェーンを作成
iptables -N WHITE_LIST

function loadWhiteList() {
    WhiteList="/root/tool/iptables/cidr.txt"
    # cidr.txt.gz を取得出来たら、WhiteListを更新
    wget -q -N http://nami.jp/ipv4bycc/cidr.txt.gz
    
    # cidr.txt.gz を取得出来たら、WhiteListを更新
    # ただし、ファイルサイズが0byteの場合は不正ファイルと判断して更新スキップ
    if [ -f cidr.txt.gz -a `ls -l cidr.txt.gz | awk '{print $5;}'` != "0" ]; then
        gzip -dc cidr.txt.gz | sed -n 's/^JP\t//p' > ${WhiteList}
        rm -f cidr.txt.gz
    fi

    # WhiteListをiptablesにロード
    if [ -f ${WhiteList} -a `ls -l ${WhiteList} | awk '{print $5;}'` != "0" ]; then
        #上記で抽出された日本のIPリストを１行づつ読み込み
        cat ${WhiteList} | while read address; do
            #INPUTチェーン（入力パケットが処理されるデフォルトチェーン）にて
            #送信元のIPが国内の物かチェック。
            #国内の物である場合はWHITE_LISTチェーンへ飛ばす
            iptables -A INPUT -s $address -j WHITE_LIST
        done
    fi
}
```

#連続してアクセスしてきた接続元のブロック

ここを参考にしました。
[iptables の ipt_recent で ssh の brute force attack 対策](http://www2s.biglobe.ne.jp/~nuts/labo/inti/ipt_recent.html)


```Bash:iptablesSetup.sh
# 前述の判定で、国内からの接続と判定されたパケットのみがここの処理に入ってくる
# WHITE_LISTチェーンでは、udpの500番宛のリクエストはIPSECチェーンへ飛ばす
iptables -A WHITE_LIST -p udp -m udp --dport 500 -j IPSEC

#ipsecbadconリストに登録されたIPは問答無用で破棄
iptables -A IPSEC -m recent --rcheck --name ipsecbadcon --rsource -j DROP
#ipsecconリストをチェックして10分間に10回アクセスしてきた輩はIPSECATTACKチェーンへ飛ばす
iptables -A IPSEC -m recent --rcheck --seconds 600 --hitcount 10 --name ipseccon --rsource -j IPSECATTACK
#接続回数が閾値に達していないアクセスはipsecconリストに登録しつつ接続許可
iptables -A IPSEC -m recent --set --name ipseccon --rsource
iptables -A IPSEC -j ACCEPT

#IPSECATTACKチェーンではipsecbadconリストに登録&syslogに記録して破棄
iptables -A IPSECATTACK -m recent --set --name ipsecbadcon --rsource
iptables -A IPSECATTACK -j LOG --log-prefix "IPTABLES:SET_IPSEC_BAD_CON " --log-level 6
iptables -A IPSECATTACK -j DROP
```

#ローカルエリア接続の設定
```Bash:iptablesSetup.sh
iptables -A INPUT -s 192.168.0.0/16 -j LOCAL_AREA

iptables -A LOCAL_AREA -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# DHCP NetBIOS
iptables -A LOCAL_AREA -p udp -m multiport --dport 67,137,138 -j ACCEPT
# DNS response
iptables -A LOCAL_AREA -p udp -m multiport --sport 53 -j ACCEPT
#上記以外のパケットは記録しつつ破棄
iptables -A LOCAL_AREA -j LOG --log-prefix "IPTABLES:LOCAL_AREA_DROP " --log-level 6
iptables -A LOCAL_AREA -j DROP
```

#完成系

ということで、完成系を晒すとこんな感じです。

```Bash:iptablesSetup.sh
function main() {
    #設定初期化
    iptables -F
    #カウンタのリセット
    iptables -Z
    #ユーザ定義チェインを初期化
    iptables -X
    iptables -P INPUT DROP
    iptables -P OUTPUT ACCEPT
    iptables -P FORWARD DROP

    iptables -N LOCAL_AREA
    iptables -N IPSEC
    iptables -N IPSECATTACK
    iptables -N WHITE_LIST

    iptables -A INPUT -i lo -j ACCEPT
    iptables -A INPUT -p icmp -j ACCEPT
    iptables -A INPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
    blockBroadCast
    iptables -A INPUT -s 192.168.0.0/16 -j LOCAL_AREA

    iptables -A LOCAL_AREA -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
    # DHCP NetBIOS
    iptables -A LOCAL_AREA -p udp -m multiport --dport 67,137,138 -j ACCEPT
    # DNS response
    iptables -A LOCAL_AREA -p udp -m multiport --sport 53 -j ACCEPT
    iptables -A LOCAL_AREA -j LOG --log-prefix "IPTABLES:LOCAL_AREA_DROP " --log-level 6
    iptables -A LOCAL_AREA -j DROP

    loadWhiteList
    iptables -A INPUT -j LOG --log-prefix "IPTABLES:NOT_IN_WHITE_LIST " --log-level 6
    iptables -A INPUT -j DROP

    iptables -A WHITE_LIST -p udp -m udp --dport 500 -j IPSEC
    iptables -A WHITE_LIST -p udp -m udp --dport 1701 -j ACCEPT
    iptables -A WHITE_LIST -p udp -m udp --dport 4500 -j ACCEPT

    iptables -A FORWARD -i ppp+ -j ACCEPT
    iptables -A FORWARD -o ppp+ -j ACCEPT
    iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

    iptables -A IPSEC -m recent --rcheck --name ipsecbadcon --rsource -j DROP
    iptables -A IPSEC -m recent --rcheck --seconds 600 --hitcount 10 --name ipseccon --rsource -j IPSECATTACK
    iptables -A IPSEC -m recent --set --name ipseccon --rsource
    iptables -A IPSEC -j ACCEPT

    iptables -A IPSECATTACK -m recent --set --name ipsecbadcon --rsource
    iptables -A IPSECATTACK -j LOG --log-prefix "IPTABLES:SET_IPSEC_BAD_CON " --log-level 6
    iptables -A IPSECATTACK -j DROP

    iptables -t nat -F
    iptables -t nat -Z
    iptables -t nat -X
    iptables -t nat -P PREROUTING ACCEPT
    iptables -t nat -P POSTROUTING ACCEPT
    iptables -t nat -P OUTPUT ACCEPT

    iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE

    service iptables save
}

function loadWhiteList() {
    WhiteList="/root/tool/iptables/cidr.txt"
    # cidr.txt.gz を取得出来たら、WhiteListを更新
    wget -q -N http://nami.jp/ipv4bycc/cidr.txt.gz
    if [ -f cidr.txt.gz -a `ls -l cidr.txt.gz | awk '{print $5;}'` != "0" ]; then
        gzip -dc cidr.txt.gz | sed -n 's/^JP\t//p' > ${WhiteList}
        rm -f cidr.txt.gz
    fi

    # WhiteListをiptablesにロード
    if [ -f ${WhiteList} -a `ls -l ${WhiteList} | awk '{print $5;}'` != "0" ]; then
        cat ${WhiteList} | while read address; do
            iptables -A INPUT -s $address -j WHITE_LIST
        done
    fi
}

function blockBroadCast() {
    iptables -A INPUT -d 255.255.255.255 -j DROP
    ip a | grep inet | grep brd | perl -pe "s/^.*brd ([^ ]+).*$/\1/" | while read address; do
        iptables -A INPUT -d ${address} -j DROP
    done
}
main
```

#その他の参考ページ
iptablesの各種チェーンの動きを理解するのに役立ったページ
[Linuxで作るファイアウォール](http://www.atmarkit.co.jp/ait/articles/0112/18/news002.html)
[natテーブルを利用したLinuxルータの作成](http://www.atmarkit.co.jp/ait/articles/0505/17/news131.html)

#その他

この設定を入れてから、下記のようなlogが記録されるようになりました。

```log:/var/log/kern.log
SRC=192.168.1.2 DST=192.168.1.199 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=55530 DF PROTO=TCP SPT=1420 DPT=21 
SRC=192.168.1.2 DST=192.168.1.199 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=55531 DF PROTO=TCP SPT=1420 DPT=21 
SRC=192.168.1.2 DST=192.168.1.199 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=692 DF PROTO=TCP SPT=3264 DPT=80 
SRC=192.168.1.2 DST=192.168.1.199 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=693 DF PROTO=TCP SPT=3264 DPT=80 
SRC=192.168.1.2 DST=192.168.1.199 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=39646 DF PROTO=TCP SPT=3196 DPT=8000 
SRC=192.168.1.2 DST=192.168.1.199 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=39647 DF PROTO=TCP SPT=3196 DPT=8000 
SRC=192.168.1.2 DST=192.168.1.199 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=15443 DF PROTO=TCP SPT=3911 DPT=8080 
SRC=192.168.1.2 DST=192.168.1.199 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=15444 DF PROTO=TCP SPT=3911 DPT=8080 
SRC=192.168.1.2 DST=192.168.1.199 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=14704 DF PROTO=TCP SPT=3896 DPT=3389
```

21とか80とか8080とかに対してローカルエリア内からポートスキャン?!
何事かと思ったらこういう事でした。。

[BUFFALO お客様サポート](http://faq.buffalo.jp/app/answers/detail/a_id/11807/kw/DOS攻撃)

手順通りにルータの設定を解除しました。