//

iptables

iptablesの設定について

iptablesの設定についてIPTables Log Analyzerの記事だけ書いておいて、
iptablesそのものに触れてないのはどういうことだ、と思ったので
記事にしておきます。

これで完璧とは言えませんが、参考にはなるかなと。。。

ちなみに私はiptablesの制御はシェルスクリプトで行っています。
ポリシーの追加/削除/編集は全てシェルスクリプトを編集して、
編集後シェルスクリプトを実行する事で新しい設定の
iptablesが稼動する、という形です。

iptablesコマンドで追加していくのもいいのですが、
saveを忘れたり、突然の再起動等で巻き戻りが
発生したときの影響を考慮しています。

(1) FTPを利用する方向け
 ポリシー自体は後程記載しますが、iptables稼動環境下で
 FTPを利用する場合、iptablesのモジュールを読み込む必要があります。

# cd /etc/sysconfig
# vi iptables-config
<6行目>
IPTABLES_MODULES=""
---
IPTABLES_MODULES="ip_conntrack_ftp ip_nat_ftp"

# lsmod | grep conntrack
ip_conntrack_ftp       41361  1 ip_nat_ftp
ip_conntrack           91621  4 ip_nat_ftp,ip_nat,ip_conntrack_ftp,xt_state
nfnetlink              40457  2 ip_nat,ip_conntrack

(2) iptablesの設定シェルスクリプト
 参考までにどうぞ。

#!/bin/bash

#==============================================================================================
# iptables setting shell
#   Created by: RISLIM(rislim.jp)
#==============================================================================================

#==============================================================================================
# Variable Settings
#----------------------------------------------------------------------------------------------
IF01_NAME="eth0"
IF01_ADDR=`/sbin/ifconfig ${IF01_NAME} | grep "inet addr:" | cut -d: -f2 | cut -d' ' -f1`
IF01_MASK=`/sbin/ifconfig ${IF01_NAME} | sed -e 's/^.*Mask:([^ ]*)$/1/p' -e d`
IF01_BCST=`/sbin/ifconfig ${IF01_NAME} | grep "inet addr:" | cut -d: -f3 | cut -d' ' -f1`
IF01_NWAD="${IF01_ADDR}/${IF01_MASK}"

IPLIST_URI="http://nami.jp/ipv4bycc/mask.txt.gz"

SHELL_PATH="/root/shell"

#==============================================================================================
# Function Settings
#----------------------------------------------------------------------------------------------
IPLIST_GET(){
    cd ${SHELL_PATH}/tmp
    wget -q ${IPLIST_URI}
    gunzip -d mask.txt.gz

    if [ ! -f "${SHELL_PATH}/tmp/mask.txt" ]; then
       if [ -f "${SHELL_PATH}/env/mask.txt" ]; then
           echo "Use a backup"
       else
           exit 1
       fi
    fi

    /bin/mv ${SHELL_PATH}/tmp/mask.txt ${SHELL_PATH}/env/mask.txt
}

ACCEPT_COUNTRY_MAKE(){
    for addr in `cat ${SHELL_PATH}/env/mask.txt | grep ^$1 | awk '{ print $2 }'`
    do
        /sbin/iptables -A ACCEPT_COUNTRY -s ${addr} -j ACCEPT
    done
}

DROP_COUNTRY_MAKE(){
    for addr in `cat ${SHELL_PATH}/env/mask.txt | grep ^$1 | awk '{ print $2 }'`
    do
        /sbin/iptables -A DROP_COUNTRY -s ${addr} -m limit --limit 1/s -j ULOG --ulog-nlgroup 1 --ulog-prefix 'DENY_COUNTRY'
        /sbin/iptables -A DROP_COUNTRY -s ${addr} -j DROP
    done
}

#==============================================================================================
# Main
#----------------------------------------------------------------------------------------------

# iptables initialized
/etc/init.d/iptables stop

# iptables default policy settings
/sbin/iptables -P INPUT DROP
/sbin/iptables -P OUTPUT ACCEPT
/sbin/iptables -P FORWARD DROP

# Loop-back interface all accept rule
/sbin/iptables -A INPUT -i lo -j ACCEPT

# Server -> External all accept rules
/sbin/iptables -A OUTPUT -s ${IF01_NWAD} -j ACCEPT

# Established/Related accept rule
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# TCP SYN Flood attack
sysctl -w net.ipv4.tcp_syncookies=1 > /dev/null
sed -i '/net.ipv4.tcp_syncookies/d' /etc/sysctl.conf
echo "net.ipv4.tcp_syncookies=1" >> /etc/sysctl.conf

# Smurf attack
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1 > /dev/null
sed -i '/net.ipv4.icmp_echo_ignore_broadcasts/d' /etc/sysctl.conf
echo "net.ipv4.icmp_echo_ignore_broadcasts=1" >> /etc/sysctl.conf

# ICMP Redirect deny
sed -i '/net.ipv4.conf.*.accept_redirects/d' /etc/sysctl.conf
for dev in `ls /proc/sys/net/ipv4/conf/`
do
    sysctl -w net.ipv4.conf.${dev}.accept_redirects=0 > /dev/null
    echo "net.ipv4.conf.${dev}.accept_redirects=0" >> /etc/sysctl.conf
done

# Source Routed deny
sed -i '/net.ipv4.conf.*.accept_source_route/d' /etc/sysctl.conf
for dev in `ls /proc/sys/net/ipv4/conf/`
do
    sysctl -w net.ipv4.conf.${dev}.accept_source_route=0 > /dev/null
    echo "net.ipv4.conf.${dev}.accept_source_route=0" >> /etc/sysctl.conf
done

# Flagment packet deny
/sbin/iptables -A INPUT -f -j ULOG --ulog-nlgroup 1 --ulog-prefix 'FRAGMENT'
/sbin/iptables -A INPUT -f -j DROP

# NetBIOS
/sbin/iptables -A INPUT -s ! ${IF01_NWAD} -p tcp -m multiport --dports 135,137,138,139,445 -j DROP
/sbin/iptables -A INPUT -s ! ${IF01_NWAD} -p udp -m multiport --dports 135,137,138,139,445 -j DROP
/sbin/iptables -A OUTPUT -d ! ${IF01_NWAD} -p tcp -m multiport --sports 135,137,138,139,445 -j DROP
/sbin/iptables -A OUTPUT -d ! ${IF01_NWAD} -p udp -m multiport --sports 135,137,138,139,445 -j DROP

# PoD Attacking Deny rules
/sbin/iptables -N LOG_PoD
/sbin/iptables -A LOG_PoD -m limit --limit 1/s --limit-burst 4 -j ACCEPT
/sbin/iptables -A LOG_PoD -j ULOG --ulog-nlgroup 1 --ulog-prefix 'PoD'
/sbin/iptables -A LOG_PoD -j DROP
/sbin/iptables -A INPUT -p icmp --icmp-type echo-request -j LOG_PoD

# Broadcast/Multicast Deny rules
/sbin/iptables -A INPUT -d 224.0.0.1 -j DROP
/sbin/iptables -A INPUT -d 255.255.255.255 -j DROP
/sbin/iptables -A INPUT -d ${IF01_BCST} -j DROP

# IDENT Reject rules
/sbin/iptables -A INPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset

# NTP(123/udp) Accept rules
/sbin/iptables -A OUTPUT -s ${IF01_ADDR} -p udp -m udp --dport 123 -m state --state NEW -j ACCEPT

# DNS(53/tcp, 53/udp) Accept rules
/sbin/iptables -A OUTPUT -s ${IF01_ADDR} -p tcp -m tcp --dport 53 -m state --state NEW -j ACCEPT
/sbin/iptables -A OUTPUT -s ${IF01_ADDR} -p udp -m udp --dport 53 -m state --state NEW -j ACCEPT

# iplist
/sbin/iptables -A OUTPUT -d 59.106.182.142 -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT
IPLIST_GET

# Accept Country Settings
/sbin/iptables -N ACCEPT_COUNTRY
ACCEPT_COUNTRY_MAKE JP

# Deny Country Settings
/sbin/iptables -N DROP_COUNTRY
DROP_COUNTRY_MAKE CN
DROP_COUNTRY_MAKE KR
DROP_COUNTRY_MAKE TW
/sbin/iptables -A INPUT -j DROP_COUNTRY

# SSH(22/tcp)
/sbin/iptables -A INPUT -s (接続元IP) -d ${IF01_ADDR} -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT

# FTP(21/tcp)
/sbin/iptables -A INPUT -s (接続元IP) -d ${IF01_ADDR} -p tcp -m tcp --dport 21 -m state --state NEW -j ACCEPT

# SMTP(25/tcp)
/sbin/iptables -A INPUT -d ${IF01_ADDR} -p tcp -m tcp --dport 25 -m state --state NEW -j ULOG --ulog-nlgroup 1 --ulog-prefix 'INPUT 25'
/sbin/iptables -A INPUT -d ${IF01_ADDR} -p tcp -m tcp --dport 25 -m state --state NEW -j ACCEPT
/sbin/iptables -A OUTPUT -s ${IF01_ADDR} -p tcp -m tcp --dport 25 -m state --state NEW -j ACCEPT

# SMTPS(465/tcp, 587/tcp)
/sbin/iptables -A INPUT -d ${IF01_ADDR} -p tcp -m tcp --dport 465 -m state --state NEW -j ULOG --ulog-nlgroup 1 --ulog-prefix 'INPUT 465'
/sbin/iptables -A INPUT -d ${IF01_ADDR} -p tcp -m tcp --dport 465 -m state --state NEW -j ACCEPT_COUNTRY
/sbin/iptables -A INPUT -d ${IF01_ADDR} -p tcp -m tcp --dport 587 -m state --state NEW -j ULOG --ulog-nlgroup 1 --ulog-prefix 'INPUT 587'
/sbin/iptables -A INPUT -d ${IF01_ADDR} -p tcp -m tcp --dport 587 -m state --state NEW -j ACCEPT_COUNTRY

# POP3S(995/tcp)
/sbin/iptables -A INPUT -d ${IF01_ADDR} -p tcp -m tcp --dport 995 -m state --state NEW -j ULOG --ulog-nlgroup 1 --ulog-prefix 'INPUT 995'
/sbin/iptables -A INPUT -d ${IF01_ADDR} -p tcp -m tcp --dport 995 -m state --state NEW -j ACCEPT_COUNTRY

# HTTP(80/tcp)
/sbin/iptables -A INPUT -d ${IF01_ADDR} -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT

# HTTPS(443/tcp)
/sbin/iptables -A INPUT -d ${IF01_ADDR} -p tcp -m tcp --dport 443 -m state --state NEW -j ACCEPT

# ALL DROP
/sbin/iptables -A INPUT -m limit --limit 1/s -j ULOG --ulog-nlgroup 1 --ulog-prefix 'INPUT-DROP'
/sbin/iptables -A INPUT -j DROP
/sbin/iptables -A FORWARD -m limit --limit 1/s -j ULOG --ulog-nlgroup 1 --ulog-prefix 'FORWARD-DROP'
/sbin/iptables -A FORWARD -j DROP

# save
/etc/init.d/iptables save

# run
/etc/init.d/iptables start

#==============================================================================================
exit 0

※解説
24行目~38行目
 http://nami.jp/ipv4bycc/で公開されている
 「世界の国別 IPv4 アドレス割り当てリスト」をiptablesで使えるように
 準備する関数(IPLIST_GET)です。

40行目~45行目
 IPLIST_GETで用意したリストを使い、指定した国からの
 アクセスをACCEPT(許可)設定する関数(ACCEPT_COUNTRY_MAKE)です。
 関数実行時に許可する国を引数で渡します。

47行目~53行目
 IPLIST_GETで用意したリストを使い、指定した国からの
 アクセスをDROP(破棄)設定する関数(DROP_COUNTRY_MAKE)です。
 関数実行時に破棄する国を引数で渡します。
 また、ulogd経由でアクセス内容をMySQLに保管します。

60行目
 現在、起動しているiptablesを一旦停止(初期化)します。

63行目~65行目
 デフォルトポリシーをそれぞれ設定します。

68行目
 ループバックアドレスへの受信を全て許可する設定です。

71行目
 サーバから外部へのアクセスを全て許可する設定です。

74行目、75行目
 接続済コネクションに対する全ての受信/送信を許可する設定です。
 (新規コネクションはstate NEWとなります)

77行目~123行目
 様々な攻撃に対する防御策です。

126行目
 IDENT(113/tcp)へのアクセスをREJECT(拒否)応答する設定。
 この設定がない場合、メールサーバのレスポンス低下に繋がる可能性があります。
 メールサーバとして稼動しないなら不要かもしれませんが、
 どちらにせよ閉じておいて問題ないと思います。

129行目
 NTP(123/tcp)の送信許可設定です。
 NTPクライアントとして稼動する場合、必要な設定になります。
 (送信全部許可してるのに、、、という突っ込みは受け付けません)

132行目、133行目
 名前解決(53/tcp, 53/udp)の送信許可設定です。

140行目、141行目
 国別アクセス許可設定です。
 日本国内からのアクセスをACCEPT_COUNTRYチェインに入れています。

144行目~146行目
 国別アクセス破棄設定です。
 ここでは中国、韓国、台湾からのアクセスを破棄しています。
 それぞれの国と交流ある方は注意して下さい。

151行目
 SSH(22/tcp)接続許可設定です。
 リモートからSSH接続する場合は、-s (接続元)のあとに
 接続元のIPアドレスを入れて設定して下さい。

154行目
 FTP(21/tcp)接続許可設定です。
 SSHと同様です。
 FTPデータ転送はip_conntrack_ftpで対応しています。

157行目、158行目
 SMTP(25/tcp)の送受信許可設定です。
 メールサーバとして稼動する場合必須です。
 メール送受信どちらもしない場合は、ACCEPTを
 DROPにすればよいと思います。

162行目~165行目
 SMTPSとOB25P対応の受信許可設定です。
 ここでいう受信とはクライアントからサーバに対する465/tcp及び
 587/tcpアクセスであり、サーバ間は通常は25/tcpで
 メール配送を行っています。
 尚、接続のルールについてACCEPT_COUNTRYチェインに渡しています。
 メールサーバでないのなら、ACCEPT_COUNTRYをDROPにします。

168行目、169行目
 POP3Sの受信許可設定です。
 こちらもACCEPT_COUNTRYチェインを利用しています。
 メールサーバでないのなら、ACCEPT_COUNTRYをDROPにします。

171行目、175行目
 HTTP(80/tcp)とHTTPS(443/tcp)の受信許可設定です。
 Webサーバとして公開する場合、必須の設定です。
 Webサーバでないのなら、ACCEPTをDROPにします。

178行目~181行目
 ここまでのポリシーに該当しなかったINPUTチェインと
 FORWARDチェインについて全ての通信を破棄する設定です。
 デフォルトDROPですが、ログを取得&明示的にDROPとしています。
 もし意図しない接続失敗が発生している場合は、
 iptablelogからINPUT-DROPタグとFORWARD-DROPタグを
 中心に何が問題なのかを調べる必要があります。

184行目
 ここまでの設定を保存します。
 保存することで、再起動時にiptablesの自動起動において
 保存した内容で設定が行われます。

あまり丁寧な説明では無かったですが、
参考になれば幸いです。

Instagr.am

Recent Posts

土山茜さん@ポートレート撮影
1月 6, 2013
By RISLIM
2013年。
1月 1, 2013
By RISLIM
神奈川県・滝『本棚』
10月 17, 2012
By RISLIM
神奈川県・滝『下棚』
10月 10, 2012
By RISLIM
神奈川県・滝『飛竜の滝』
10月 7, 2012
By RISLIM
にほんブログ村 IT技術ブログへ
Get Adobe Flash player