iptablesで日本以外からの通信をDROPしつつログを取得する

 2014-09-16
SSHの認証失敗をモニタしてみると、思ったより賑やかだったので、有名なこれをやってみました。
 

序章

VPSでもないただの自宅鯖だし、特にどこかパブリックな場所に乗せているわけでも無く、完全に自分用に使っているので、まぁたまにログを見てんー、としているだけでしたが、SSHの認証失敗をモニタしてみると存外多かったので、やってみましたよっと。

参考:

iptables - 国内からの接続のみ許可して海外からの接続を遮断する パソコン鳥のブログ/ウェブリブログ :
http://vogel.at.webry.info/201306/article_2.html



基本的に、参考ページのものを使わせて貰います。先人の叡智をありがたく~。

setup_iptables.sh

#!/bin/bash -f
IPTABLES="/sbin/iptables"
IPLISTURL="http://nami.jp/ipv4bycc/cidr.txt.gz"
LOCALNET="192.168.0.0/16"


#### ==================================================
#### clear & set default settings
# all clear
$IPTABLES -F
$IPTABLES -Z
$IPTABLES -X

# set default policy
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP

# add new filter
$IPTABLES -N ACCEPT_FILTER
#$IPTABLES -N sshguard

# add new filter for SSH reject
$IPTABLES -N SSH-evil
$IPTABLES -A SSH-evil -m recent --name badSSH --set
$IPTABLES -A SSH-evil -j LOG --log-level warning \
--log-prefix "IPTABLES-DROP-SSHevil:" -m limit
$IPTABLES -A SSH-evil -j DROP
$IPTABLES -N SSH
$IPTABLES -A SSH -p tcp --syn -m recent --name badSSH --rcheck --seconds 600 -j LOG \
--log-level warning --log-prefix "IPTABLES-DROP-SSHevil:" -m limit
$IPTABLES -A SSH -p tcp --syn -m recent --name badSSH --rcheck --seconds 600 -j DROP
$IPTABLES -A SSH -p tcp --syn -m recent --name sshconn --rcheck --seconds 60 \
--hitcount 5 -j SSH-evil
$IPTABLES -A SSH -p tcp --syn -m recent --name sshconn --set
$IPTABLES -A SSH -p tcp --syn -j ACCEPT_FILTER

# accept localnet, echoback
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT
$IPTABLES -A INPUT -s ${LOCALNET} -j ACCEPT
$IPTABLES -A OUTPUT -s ${LOCALNET} -j ACCEPT
$IPTABLES -A INPUT -s 127.0.0.1/8 -j ACCEPT
$IPTABLES -A OUTPUT -s 127.0.0.1/8 -j ACCEPT

# setting tcp
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j LOG \
--log-level warning --log-prefix "IPTABLES-DROP-HalfScan:" -m limit
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW \
-j REJECT --reject-with tcp-reset

# setting already transfers
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -m state --state NEW,ESTABLISHED -j ACCEPT

# setting icmp
$IPTABLES -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type source-quench -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type redirect -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type parameter-problem -j ACCEPT

#### ==================================================



#### ==================================================
#### begin accept setting

# reject auth/IDENT ( for mail,ftp )
$IPTABLES -A INPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset

# accept ssh(tcp:22)
$IPTABLES -A INPUT -p tcp --dport 22 -m state --state NEW -j SSH

# accept ftp(tcp:21)
$IPTABLES -A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT_FILTER

# accept http,https(tcp:80,443)
$IPTABLES -A INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT_FILTER
$IPTABLES -A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT_FILTER

# accept DNS(tcp:53,udp:53) and mDNS(udp:5353)
$IPTABLES -A INPUT -p tcp --dport 53 -m state --state NEW -j ACCEPT_FILTER
$IPTABLES -A INPUT -p udp --dport 53 -m state --state NEW -j ACCEPT_FILTER
$IPTABLES -A INPUT -p udp --dport 5353 -m state --state NEW -j ACCEPT_FILTER

# accept samba(tcp:139,445,2869,5000,udp:137,138,445,1900)
$IPTABLES -A INPUT -p tcp --dport 139 -m state --state NEW -j ACCEPT_FILTER
$IPTABLES -A INPUT -p udp --dport 137 -m state --state NEW -j ACCEPT_FILTER
$IPTABLES -A INPUT -p udp --dport 138 -m state --state NEW -j ACCEPT_FILTER
$IPTABLES -A INPUT -p tcp --dport 445 -m state --state NEW -j ACCEPT_FILTER
$IPTABLES -A INPUT -p udp --dport 445 -m state --state NEW -j ACCEPT_FILTER
$IPTABLES -A INPUT -p udp --dport 1900 -m state --state NEW -j ACCEPT_FILTER
$IPTABLES -A INPUT -p tcp --dport 2869 -m state --state NEW -j ACCEPT_FILTER
$IPTABLES -A INPUT -p tcp --dport 5000 -m state --state NEW -j ACCEPT_FILTER

# accept snmp(udp:161)
$IPTABLES -A INPUT -p udp --dport 161 -m state --state NEW -j ACCEPT_FILTER

# accept vnc(tcp:5900-5909)
$IPTABLES -A INPUT -p tcp --dport 5900:5909 -m state --state NEW -j ACCEPT_FILTER

#### end accept setting
#### ==================================================


# add new filter for CN,US,KR DROP filter
$IPTABLES -N DROP-CN
$IPTABLES -A DROP-CN -j LOG --log-level warning \
--log-prefix "IPTABLES-DROP-CN:" -m limit
$IPTABLES -A DROP-CN -j DROP
$IPTABLES -N DROP-US
$IPTABLES -A DROP-US -j LOG --log-level warning \
--log-prefix "IPTABLES-DROP-US:" -m limit
$IPTABLES -A DROP-US -j DROP
$IPTABLES -N DROP-KR
$IPTABLES -A DROP-KR -j LOG --log-level warning \
--log-prefix "IPTABLES-DROP-KR:" -m limit
$IPTABLES -A DROP-KR -j DROP


# add country filter
$IPTABLES -F ACCEPT_FILTER # clear
TEMPFILE="/tmp/IPLISTURL"
curl -s ${IPLISTURL} | \
gunzip > ${TEMPFILE}
cat ${TEMPFILE} | \
sed -n 's/^CN\t//p' | \
while read address
do
$IPTABLES -A ACCEPT_FILTER -s $address -j DROP-CN
done

cat ${TEMPFILE} | \
sed -n 's/^US\t//p' | \
while read address
do
$IPTABLES -A ACCEPT_FILTER -s $address -j DROP-US
done

cat ${TEMPFILE} | \
sed -n 's/^KR\t//p' | \
while read address
do
$IPTABLES -A ACCEPT_FILTER -s $address -j DROP-KR
done

cat ${TEMPFILE} | \
sed -n 's/^JP\t//p' | \
while read address
do
$IPTABLES -A ACCEPT_FILTER -s $address -j ACCEPT
done


# deny others
$IPTABLES -A ACCEPT_FILTER -j LOG --log-level warning \
--log-prefix "IPTABLES-DROP-others(NotJP?):" -m limit
$IPTABLES -A ACCEPT_FILTER -j DROP

\rm -f ${TEMPFILE}


なにやってんの?

  • デフォルトポリシーをDROPに設定します。
  • ローカルネットのIPからのアクセスやループバックインターフェースの通信は許可します。
  • SSH(tcp:22)へのアクセスが妙に多いIPアドレスは10分間DROPさせます。
  • 突然届くSYNフラグのないTCPパケットはDROPさせます。
  • 必要なポートへのアクセスはACCEPT_FILTERのチェインへ飛ばします。
  • ACCEPT_FILTERにて、日本国内のIPからのアクセスをACCEPTします。
  • ACCEPT_FILTERにて、中国、アメリカ、韓国のIPからのアクセスをそれぞれDROPします。(この三国が多いらしい。)
  • ACCEPT_FILTERにて、上記の条件に一致しなかったIPはDROPします。
  • DROPする際に、ログを採取します。

sambaは適当に多めにポート空けてます。たぶん要らないものもあると思いマス。
sambaはルータで通してないのでどうせ外からアクセス来ないので・・・。

実行してiptablesの設定が問題なければ、内容をセーブしておきます。これをやんないと再起動時にiptablesの設定が戻ります。(安全だね!)
 root# iptables-save
上記で、とりあえず現在の設定が再起動時も復帰されるようになります。・・が、IPアドレスのレンジなどが変わってたりするとアレなので、再起動時にスクリプトを実行するように仕込んでおきました。
 root# crontab -e

@reboot sleep 1m;/hogehgoe/bin/setup_iptables.sh
まーそんなにしょっちゅう変更されるもんでもないと思うので、念のため、です。

ログを取る ~syslogとlogrotateにお願い~

/etc/rsyslog.d/iptables.confを作成して下記のように記載
:msg, contains, "IPTABLES-DROP-"  -/var/log/iptables.log

ファイルを保存したら、rsyslogを再起動しておく
 root# service rsyslog restart
これで、/var/log/iptables.logが作成されて、ログが落ちていくハズ。

/etc/logrotate.d/syslogを下記のように編集します。
/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
/var/log/sftp.log
/var/log/iptables.log
{
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
これで古いログはファイルが切り離されたり圧縮されたりします。logrotateはcronで動いているのでしばらくしたら反映される、はず。


というわけで、しばらくログを見ながら、効果のほどを確認、しまうー。

 
コメント












管理者にだけ表示を許可する
トラックバック
トラックバックURL:
http://wbbwbb.blog83.fc2.com/tb.php/172-e0fba1ab
≪ トップページへこのページの先頭へ  ≫