#!/bin/sh
# iptablesコマンドのパス
IPTABLES="/sbin/iptables"
# デフォルト外部(WAN側)インターフェース
DEFAULT_EXTIF="eth0"
# デフォルト内部(LAN側)インターフェース
DEFAULT_INTIF="eth1"
# 参照するNTPサーバ
NTP1="yyy.yyy.yyy.yyy"
NTP2="zzz.zzz.zzz.zzz"
# 非特権ポート
UNPRIVPORTS="1024:65535"
# TCP-SYN-Flood検出で一秒あたりに許される平均マッチ回数の最大値
TCPSYNLIMIT="5/s"
# TCP-SYN-Flood検出の最大バースト値
TCPSYNLIMITBURST="10"
# ログチェインで一秒あたりに許される平均マッチ回数の最大値
LOGLIMIT="2/s"
# ログチェインの最大バースト値
LOGLIMITBURST="10"
# Ping-Flood検出で一秒あたりに許される平均マッチ回数の最大値
PINGLIMIT="5/s"
# Ping-Flood検出の最大バースト値
PINGLIMITBURST="10"
## 外部インターフェース
# 検出
if [ "x$2" != "x" ]; then
EXTIF=$2
else
EXTIF=$DEFAULT_EXTIF
fi
# IPアドレスの取得
EXTIP="`/sbin/ifconfig $EXTIF | grep inet | cut -d : -f 2 | cut -d \ -f 1`"
if [ "$EXTIP" = '' ]; then
echo "Aborting: Unable to determine the IP-address of $EXTIF !"
exit 1
fi
# ゲートウェイ(ルータ)の検出
EXTGW=`/sbin/route -n | grep -A 4 UG | awk '{ print $2}'`
## 内部インターフェース
# 検出
if [ "x$3" != "x" ]; then
INTIF=$3
else
INTIF=$DEFAULT_INTIF
fi
# IPアドレスの取得
INTIP="`/sbin/ifconfig $INTIF | grep inet | cut -d : -f 2 | cut -d \ -f 1`"
if [ "$INTIP" = '' ]; then
echo "Aborting: Unable to determine the IP-address of $INTIF !"
exit 1
fi
# ネットマスクの取得
INTMASK="`/sbin/ifconfig $INTIF | grep Mask | cut -d : -f 4`"
# ネットワークアドレスの取得
INTLAN=$INTIP'/'$INTMASK
# iptablesの初期化
$IPTABLES -F
$IPTABLES -F -t mangle
$IPTABLES -F -t nat
$IPTABLES -X
$IPTABLES -X -t mangle
$IPTABLES -X -t nat
# デフォルトポリシをDROPに設定
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP
# パケットをインターフェース間でフォワード
echo 1 > /proc/sys/net/ipv4/ip_forward
# IP Spoofing attacksの拒否(ソースの妥当性確認)
echo 2 > /proc/sys/net/ipv4/conf/all/rp_filter
# ICMP ECHO requestのブロードキャストとマルチキャストを無視
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# SRR オプションを持ったパケットを受け取らない
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
# タイムスタンプを無効
echo 0 > /proc/sys/net/ipv4/tcp_timestamps
# ソケットの syn backlog queue があふれたときにsyncookieを送出
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
# ICMP redirect message を受け取らない
echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
# ブロードキャストフレームに対する偽物の応答の警告を抑止
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
# 有り得ないアドレスを持ったパケットをカーネルのログに記録
echo 1 > /proc/sys/net/ipv4/conf/all/log_martians
# ローカルポートの範囲
echo "32768 61000" > /proc/sys/net/ipv4/ip_local_port_range
## 対DoS
# FIN-WAIT-2 状態を維持する時間
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
# TCP がキープアライブメッセージを送出する間隔
echo 2400 > /proc/sys/net/ipv4/tcp_keepalive_time
# ウィンドウ調整を無効
echo 0 > /proc/sys/net/ipv4/tcp_window_scaling
# SACKを無効
echo 0 > /proc/sys/net/ipv4/tcp_sack
## ログチェイン
# 既知の接続に結び付けられないパケット
$IPTABLES -N LINVALID
$IPTABLES -A LINVALID -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-prefix "iptables INVALID DROP "
$IPTABLES -A LINVALID -j DROP
# 不正なtcp-flags
$IPTABLES -N LBADFLAG
$IPTABLES -A LBADFLAG -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-prefix "iptables BADFLAG DROP "
$IPTABLES -A LBADFLAG -j DROP
# TCP-SYN-Floods
$IPTABLES -N LSYNFLOOD
$IPTABLES -A LSYNFLOOD -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-prefix "iptables SYNFLOOD DROP "
$IPTABLES -A LSYNFLOOD -j DROP
# Ping-Floods
$IPTABLES -N LPINGFLOOD
$IPTABLES -A LPINGFLOOD -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-prefix "iptables PINGFLOOD DROP "
$IPTABLES -A LPINGFLOOD -j DROP
# その他のDROPパケット
$IPTABLES -N LDROP
$IPTABLES -A LDROP -p tcp -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-prefix "iptables TCP DROP "
$IPTABLES -A LDROP -p udp -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-prefix "iptables UDP DROP "
$IPTABLES -A LDROP -p icmp -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-prefix "iptables ICMP DROP "
$IPTABLES -A LDROP -f -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-prefix "iptables FRAGMENT DROP "
$IPTABLES -A LDROP -j DROP
# その他REJECTパケット
$IPTABLES -N LREJECT
$IPTABLES -A LREJECT -p tcp -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-prefix "iptables TCP REJECT "
$IPTABLES -A LREJECT -p udp -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-prefix "iptables UDP REJECT "
$IPTABLES -A LREJECT -p icmp -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-prefix "iptables ICMP REJECT "
$IPTABLES -A LREJECT -f -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-prefix "iptables FRAGMENT REJECT "
$IPTABLES -A LREJECT -p tcp -j REJECT --reject-with tcp-reset
$IPTABLES -A LREJECT -p udp -j REJECT --reject-with icmp-port-unreachable
$IPTABLES -A LREJECT -j REJECT
# TCPACCEPT
$IPTABLES -N TCPACCEPT
$IPTABLES -A TCPACCEPT -p tcp --syn -m limit --limit $TCPSYNLIMIT --limit-burst $TCPSYNLIMITBURST -j ACCEPT
$IPTABLES -A TCPACCEPT -p tcp --syn -j LSYNFLOOD
$IPTABLES -A TCPACCEPT -p tcp ! --syn -j ACCEPT
# 不正なフラグの組み合わせ
$IPTABLES -N CHECKBADFLAG
$IPTABLES -A CHECKBADFLAG -p tcp --tcp-flags ALL FIN,URG,PSH -j LBADFLAG
$IPTABLES -A CHECKBADFLAG -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LBADFLAG
$IPTABLES -A CHECKBADFLAG -p tcp --tcp-flags ALL ALL -j LBADFLAG
$IPTABLES -A CHECKBADFLAG -p tcp --tcp-flags ALL NONE -j LBADFLAG
$IPTABLES -A CHECKBADFLAG -p tcp --tcp-flags SYN,RST SYN,RST -j LBADFLAG
$IPTABLES -A CHECKBADFLAG -p tcp --tcp-flags SYN,FIN SYN,FIN -j LBADFLAG
$IPTABLES -A CHECKBADFLAG -p tcp --tcp-option 64 -j LBADFLAG
$IPTABLES -A CHECKBADFLAG -p tcp --tcp-option 128 -j LBADFLAG
# SMB
$IPTABLES -N SMB
$IPTABLES -A SMB -p tcp --dport 137:139 -j DROP
$IPTABLES -A SMB -p tcp --dport 445 -j DROP
$IPTABLES -A SMB -p udp --dport 137:139 -j DROP
$IPTABLES -A SMB -p udp --dport 445 -j DROP
$IPTABLES -A SMB -p tcp --sport 137:139 -j DROP
$IPTABLES -A SMB -p tcp --sport 445 -j DROP
$IPTABLES -A SMB -p udp --sport 137:139 -j DROP
$IPTABLES -A SMB -p udp --sport 445 -j DROP
## Inbound ICMP/Traceroute
$IPTABLES -N ICMPINBOUND
# Ping Flood対策
$IPTABLES -A ICMPINBOUND -p icmp --icmp-type echo-request -m limit --limit $PINGLIMIT --limit-burst $PINGLIMITBURST -j ACCEPT
$IPTABLES -A ICMPINBOUND -p icmp --icmp-type echo-request -j LPINGFLOOD
# ICMP-Redirectsを破棄
$IPTABLES -A ICMPINBOUND -p icmp --icmp-type redirect -j LDROP
# ICMP-Timestampを破棄
$IPTABLES -A ICMPINBOUND -p icmp --icmp-type timestamp-request -j LDROP
$IPTABLES -A ICMPINBOUND -p icmp --icmp-type timestamp-reply -j LDROP
# ICMP-address-maskを破棄
$IPTABLES -A ICMPINBOUND -p icmp --icmp-type address-mask-request -j LDROP
$IPTABLES -A ICMPINBOUND -p icmp --icmp-type address-mask-reply -j LDROP
# その他のICMPをACCEPT
$IPTABLES -A ICMPINBOUND -p icmp -j ACCEPT
## Outbound ICMP/Traceroute
$IPTABLES -N ICMPOUTBOUND
# ICMP-Redirectsを破棄
$IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type redirect -j LDROP
# ICMP-TTL-Expiredを破棄
$IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type ttl-zero-during-transit -j LDROP
$IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type ttl-zero-during-reassembly -j LDROP
# ICMP-Parameter-Problemを破棄
$IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type parameter-problem -j LDROP
# ICMP-Timestampを破棄
$IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type timestamp-request -j LDROP
$IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type timestamp-reply -j LDROP
# ICMP-address-maskを破棄
$IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type address-mask-request -j LDROP
$IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type address-mask-reply -j LDROP
# その他のICMPを許可
$IPTABLES -A ICMPOUTBOUND -p icmp -j ACCEPT
## INPUT-Chain
# 既知の接続に結び付けられないパケットを破棄
$IPTABLES -A INPUT -m state --state INVALID -j LINVALID
# 不正なフラグの組み合わせを破棄
$IPTABLES -A INPUT -p tcp -j CHECKBADFLAG
# ローカルのループバックトラフィックは許可
$IPTABLES -A INPUT -i lo -j ACCEPT
# ローカルアドレス宛をリジェクト
$IPTABLES -A INPUT -d 127.0.0.0/8 -j LREJECT
# 内部LANからファイアウォールまでのトラフィックを許可
$IPTABLES -A INPUT -i $INTIF -s $INTLAN -j ACCEPT
# 偽の内部LANを騙るトラフィックをリジェクト
$IPTABLES -A INPUT -s $INTLAN -j LREJECT
# ICMPフィルタ
$IPTABLES -A INPUT -i $EXTIF -p icmp -j ICMPINBOUND
# UDPのtracerouteを許可
$IPTABLES -A INPUT -p udp --dport 33434:33523 -j ACCEPT
# SMBのトラフィックを破棄
$IPTABLES -A INPUT -i $EXTIF -j SMB
# IDENT
$IPTABLES -A INPUT -i $EXTIF -p tcp --dport 113 -j REJECT --reject-with tcp-reset
# SSH
$IPTABLES -A INPUT -i $EXTIF -p tcp --dport 22 -j TCPACCEPT
# SMTP
$IPTABLES -A INPUT -i $EXTIF -p tcp --dport 25 -j TCPACCEPT
# DNS
$IPTABLES -A INPUT -i $EXTIF -p tcp --dport 53 -j TCPACCEPT
$IPTABLES -A INPUT -i $EXTIF -p udp --dport 53 -j ACCEPT
# NTP
$IPTABLES -A INPUT -i $EXTIF -s $NTP1 -p udp --sport 123 --dport 123 -j ACCEPT
$IPTABLES -A INPUT -i $EXTIF -s $NTP2 -p udp --sport 123 --dport 123 -j ACCEPT
# HTTP
$IPTABLES -A INPUT -i $EXTIF -p tcp --dport 80 -j TCPACCEPT
# HTTPS
$IPTABLES -A INPUT -i $EXTIF -p tcp --dport 443 -j TCPACCEPT
# POP-3
$IPTABLES -A INPUT -i $EXTIF -p tcp --dport 110 -j TCPACCEPT
# IMAP
#$IPTABLES -A INPUT -i $EXTIF -p tcp --dport 143 -j TCPACCEPT
# ルータからのSYSLOGを受信
$IPTABLES -A INPUT -i $EXTIF -s $EXTGW -p udp --dport 514 -j ACCEPT
# ESTABLISHED/RELATED接続を許可
$IPTABLES -A INPUT -i $EXTIF -m state --state ESTABLISHED -j ACCEPT
$IPTABLES -A INPUT -i $EXTIF -p tcp --dport $UNPRIVPORTS -m state --state RELATED -j TCPACCEPT
$IPTABLES -A INPUT -i $EXTIF -p udp --dport $UNPRIVPORTS -m state --state RELATED -j ACCEPT
# 上記以外は破棄
$IPTABLES -A INPUT -j LDROP
## Output-Chain
# ローカルのループバックトラフィックは許可
$IPTABLES -A OUTPUT -o lo -j ACCEPT
# 内部LANからのトラフィックを許可
$IPTABLES -A OUTPUT -o $INTIF -d $INTLAN -j ACCEPT
# ICMPフィルタ
$IPTABLES -A OUTPUT -o $EXTIF -p icmp -j ICMPOUTBOUND
# SMBのトラフィックを破棄
$IPTABLES -A OUTPUT -o $EXTIF -j SMB
# IDENT
$IPTABLES -A OUTPUT -o $EXTIF -p tcp --sport 113 -j REJECT --reject-with tcp-reset
# SSH
$IPTABLES -A OUTPUT -o $EXTIF -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
# SMTP
$IPTABLES -A OUTPUT -o $EXTIF -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
# DNS
$IPTABLES -A OUTPUT -o $EXTIF -p tcp --sport 53 -j ACCEPT
$IPTABLES -A OUTPUT -o $EXTIF -p udp --sport 53 -j ACCEPT
# NTP
$IPTABLES -A OUTPUT -o $EXTIF -d $NTP1 -p udp --sport 123 --dport 123 -j ACCEPT
$IPTABLES -A OUTPUT -o $EXTIF -d $NTP2 -p udp --sport 123 --dport 123 -j ACCEPT
# HTTP
$IPTABLES -A OUTPUT -o $EXTIF -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
# HTTPS
$IPTABLES -A OUTPUT -o $EXTIF -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
# POP-3
$IPTABLES -A OUTPUT -o $EXTIF -p tcp --sport 110 -m state --state ESTABLISHED -j ACCEPT
# IMAP
#$IPTABLES -A OUTPUT -o $EXTIF -p tcp --sport 143 -m state --state ESTABLISHED -j ACCEPT
# 非特権ポートからのTCP/UDPトラフィックを許可
$IPTABLES -A OUTPUT -o $EXTIF -s $EXTIP -p tcp --sport $UNPRIVPORTS -j ACCEPT
$IPTABLES -A OUTPUT -o $EXTIF -s $EXTIP -p udp --sport $UNPRIVPORTS -j ACCEPT
# 上記以外は破棄
$IPTABLES -A OUTPUT -j LDROP
## FORWARD-Chain
# 既知の接続に結び付けられないパケットを破棄
$IPTABLES -A FORWARD -m state --state INVALID -j LINVALID
# 不正なフラグの組み合わせを破棄
$IPTABLES -A FORWARD -p tcp -j CHECKBADFLAG
# SMBのトラフィックを破棄
$IPTABLES -A FORWARD -o $EXTIF -j SMB
# 内部LANから外部ネットまでの非特権ポートからの転送を許可
$IPTABLES -A FORWARD -i $INTIF -o $EXTIF -s $INTLAN -p tcp --sport $UNPRIVPORTS -j ACCEPT
$IPTABLES -A FORWARD -i $INTIF -o $EXTIF -s $INTLAN -p udp --sport $UNPRIVPORTS -j ACCEPT
$IPTABLES -A FORWARD -i $INTIF -o $EXTIF -s $INTLAN -p icmp -j ACCEPT
# 内部LANから外部ネットまでの非特権ポートへの転送を許可
$IPTABLES -A FORWARD -i $EXTIF -m state --state ESTABLISHED -j ACCEPT
$IPTABLES -A FORWARD -i $EXTIF -p tcp --dport $UNPRIVPORTS -m state --state RELATED -j TCPACCEPT
$IPTABLES -A FORWARD -i $EXTIF -p udp --dport $UNPRIVPORTS -m state --state RELATED -j ACCEPT
$IPTABLES -A FORWARD -i $EXTIF -p icmp -m state --state RELATED -j ACCEPT
# Path MTU Discovery Black Hole
#$IPTABLES -A FORWARD -o $EXTIF -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
# 上記以外は破棄
$IPTABLES -A FORWARD -j LDROP
## PREROUTING
## POSTROUTING
# Masquerade
$IPTABLES -A POSTROUTING -t nat -o $EXTIF -j MASQUERADE