#!/bin/sh
#
# firewall starting firewall
#
# chkconfig: 2345 98 01
# description: setting firewall
##########################################################################
# 设定参数
##########################################################################
INNER_NET=192.168.0.0/24 # LAN 局域网 自由设定
FWALL_IP=192.168.0.1 # 防火墙的IP 你的机器的真实IP
INNER_PORT=eth1 # 局域网端IP
OUTER_PORT=ppp0 # Wan端IP
IPTABLES="/sbin/iptables" # iptables 命令
MODPROBE="/sbin/modprobe" # modprobe 命令
##########################################################################
# 模块的加载和设定为内核工作
##########################################################################
$MODPROBE ip_tables
$MODPROBE iptable_filter
$MODPROBE ip_conntrack
$MODPROBE iptable_nat
$MODPROBE ip_nat_ftp
$MODPROBE ip_conntrack_ftp
$MODPROBE ipt_state
$MODPROBE ipt_MASQUERADE
$MODPROBE ipt_LOG
$MODPROBE ipt_REJECT
$MODPROBE ipt_limit
# 允许IP masquerade(变换)
echo 1 > /proc/sys/net/ipv4/ip_forward
# 忽视ping的broadcast
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# 检查源IP
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f; done
# 记录不可能的(虚假)IP
for f in /proc/sys/net/ipv4/conf/*/log_martians; do echo "1" > $f; done
# 忽视ICMP redirect message
for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do echo 1 > $f; done
##########################################################################
# 初始化规则
##########################################################################
$IPTABLES -P INPUT DROP # 清空INPUT原始定义
$IPTABLES -P OUTPUT DROP # 清空OUPUT原始定义
$IPTABLES -P FORWARD DROP # 清空FORWARD原始定义
$IPTABLES -F # flash chain
$IPTABLES -F -t nat
$IPTABLES -X # 删除用户定义的Chain
##########################################################################
# 用户定义的chain
##########################################################################
#
# 记录并丢弃非法的包
#
$IPTABLES -N DROPPACKET # DROPPACKT chain的生成
$IPTABLES -A DROPPACKET -j LOG --log-prefix "INVALID_PACKET: " \
--log-level=3 -m limit --limit 1/s --limit-burst 10
$IPTABLES -A DROPPACKET -j DROP
#
# 检查SYNFlood攻击的chain
#
$IPTABLES -N SYNFLOOD # SYNFLOOD chain的生成
# 没有超过限定值的话返回
$IPTABLES -A SYNFLOOD -m limit --limit 10/s --limit-burst 20 -j RETURN
# 超过限定值,就视为SYNFLOOD攻击,记录并丢弃
$IPTABLES -A SYNFLOOD -m limit --limit 1/s --limit-burst 10 -j LOG \
--log-level=1 --log-prefix "SYNFLOOD: "
$IPTABLES -A SYNFLOOD -j DROP
#
# 记录非法的Flag TCP,并丢弃
#
$IPTABLES -N DROPFLAGS # DROPFLAGS chain的生成
$IPTABLES -A DROPFLAGS -j LOG --log-prefix "INVALID_FLAGS: " \
--log-level=3 -m limit --limit 1/s --limit-burst 10
$IPTABLES -A DROPFLAGS -j DROP
#
# 检查TCP Flag的非法组合
#
$IPTABLES -N CHKFLAGS
$IPTABLES -A CHKFLAGS -p tcp --tcp-flags ACK,FIN FIN -j DROPFLAGS
$IPTABLES -A CHKFLAGS -p tcp --tcp-flags ACK,PSH PSH -j DROPFLAGS
$IPTABLES -A CHKFLAGS -p tcp --tcp-flags ACK,URG URG -j DROPFLAGS
$IPTABLES -A CHKFLAGS -p tcp --tcp-flags FIN,RST FIN,RST -j DROPFLAGS
$IPTABLES -A CHKFLAGS -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROPFLAGS
$IPTABLES -A CHKFLAGS -p tcp --tcp-flags SYN,RST SYN,RST -j DROPFLAGS
$IPTABLES -A CHKFLAGS -p tcp --tcp-flags ALL ALL -j DROPFLAGS
$IPTABLES -A CHKFLAGS -p tcp --tcp-flags ALL NONE -j DROPFLAGS
$IPTABLES -A CHKFLAGS -p tcp --tcp-flags ALL FIN,PSH,URG -j DROPFLAGS
$IPTABLES -A CHKFLAGS -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROPFLAGS
$IPTABLES -A CHKFLAGS -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROPFLAGS
#
# 拒绝 Microsoft 网络相关的FORWARD
#
$IPTABLES -N CHKMSNET
$IPTABLES -A CHKMSNET -p tcp --dport 42 -j DROP # wins dup
$IPTABLES -A CHKMSNET -p tcp --dport 135 -j DROP # MS-RPC
$IPTABLES -A CHKMSNET -p udp --dport 135 -j DROP # MS-RPC
$IPTABLES -A CHKMSNET -p udp --dport 137:138 -j DROP # MS browse
$IPTABLES -A CHKMSNET -p udp --dport 137:138 -j DROP # MS browse
$IPTABLES -A CHKMSNET -p tcp --dport 139 -j DROP # SMB
$IPTABLES -A CHKMSNET -p tcp --dport 445 -j DROP # DHSMB
##########################################################################
# INPUT Chain
##########################################################################
# Localhost的话,全部许可
$IPTABLES -A INPUT -i lo -j ACCEPT
# 检查包的正确性
$IPTABLES -A INPUT -m state --state INVALID -j DROPPACKET
# 检查包是否是SYN攻击
$IPTABLES -A INPUT -p tcp --syn -j SYNFLOOD
# TCP FLAG的检查
$IPTABLES -A INPUT -p tcp -j CHKFLAGS
# 许可LAN内的连接
$IPTABLES -A INPUT -i $INNER_PORT -s $INNER_NET -j ACCEPT
# 许可已经建立的连接
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 检查是否是IP伪装
$IPTABLES -A INPUT -i $OUTER_PORT -s $INNER_NET -j DROP
#
# 许可的服务(对外部公开的服务,在下面记述)
#
$IPTABLES -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT # SSH
$IPTABLES -A INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT # HTTP
$IPTABLES -A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT # HTTPS
$IPTABLES -A INPUT -p tcp --dport 53 -m state --state NEW -j ACCEPT # DOMAIN(DNS)
$IPTABLES -A INPUT -p udp --dport 53 -m state --state NEW -j ACCEPT # DOMAIN(DNS)
$IPTABLES -A INPUT -m state --state NEW -m tcp -p tcp --dport 20000:30000 -j ACCEPT # PASV_PORTS
$IPTABLES -A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT # FTP
# 拒绝AUTH请求
$IPTABLES -A INPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset
# icmp(IN)
$IPTABLES -A INPUT -p icmp --icmp-type echo-request -s $INNER_NET -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type echo-reply -s $INNER_NET -j ACCEPT
$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 time-exceeded -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type parameter-problem -j ACCEPT
# 除了上面以外所有的包,都记录下来,并通过Default Policy丢弃
$IPTABLES -A INPUT -j LOG --log-prefix "UNDEFIND_INPUT: " \
--log-level=3 -m limit --limit 1/s --limit-burst 10
##########################################################################
# OUTPUT Chain
##########################################################################
# 许可由localhost出来的包
$IPTABLES -A OUTPUT -o lo -j ACCEPT
# TCP FLAG的检查
$IPTABLES -A OUTPUT -p tcp -j CHKFLAGS
# 许可从服务器到Lan的连接
$IPTABLES -A OUTPUT -o $INNER_PORT -s $FWALL_IP -j ACCEPT
# 检查Microsoft网络
$IPTABLES -A OUTPUT -j CHKMSNET
# 许可已经连接的包
$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 许可由服务器到互联网的新加连接
$IPTABLES -A OUTPUT -m state --state NEW -j ACCEPT
# icmp(OUT)
$IPTABLES -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type fragmentation-needed -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type source-quench -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type parameter-problem -j ACCEPT
# 除了上面以外所有的包,都记录下来,并通过Default Policy丢弃
$IPTABLES -A OUTPUT -j LOG --log-prefix "UNDEFIND_ICMP: " --log-level=3 \
-m limit --limit 1/s --limit-burst 10
##########################################################################
# IP变换
##########################################################################
# 检查Microsoft网络
$IPTABLES -A FORWARD -j CHKMSNET
# 许可Lan内机器的IP变换
$IPTABLES -t nat -A POSTROUTING -o $OUTER_PORT -s $INNER_NET -j MASQUERADE
# 从外部到Lan的连接,许可已经连接的FROWARD
$IPTABLES -A FORWARD -i $OUTER_PORT -o $INNER_PORT -d $INNER_NET -m state \
--state ESTABLISHED,RELATED -j ACCEPT
# 许可LAN到外部的连接
$IPTABLES -A FORWARD -i $INNER_PORT -o $OUTER_PORT -s $INNER_NET -m state \
--state NEW,ESTABLISHED,RELATED -j ACCEPT
exit 0