原文2007年4月6日写在MSN SPACE上
 
下面一段脚本是我为公司网关上所写的包过滤防火墙。公司有路由器,但我还是喜欢用计算机装上LINUX来做防火墙,因为它可以自由的更改设置,而且配合SQUID代理能做到七层的过滤,使用QOS能进行带宽的控制,这对于硬件的路由器在价钱上可不是一个小数目。这几年使用下来没什么大的问题。
 
#!/bin/sh
#
# Firewall setup.
#
INSIDE_DEVICE=eth0
OUTSIDE_DEVICE=eth1
INSIDE_NETWORK=192.168.1.0
INSIDE_NETMASK=24
# 外部的IP,这里是得到动态IP,如果是静态的可以直接写上。
OUTSIDE_IP=`ifconfig eth1|grep inet|cut -f2 -d:|cut -f1 -d " "`
#
# 设置要对外服务的内部服务器IP
#
MAILSERVER_IP=192.168.1.10
WEBSERVER_IP=192.168.1.11
 
echo "0" > /proc/sys/net/ipv4/ip_forward
#
# Flushing the chains.
#
for i in `cat /proc/net/ip_tables_names`; do iptables -F -t $i ; iptables -X -t $i ; iptables -Z -t $i ; done
#
# Policy for chains DROP everything
#
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
#
# SYN-Flooding protection
# Looks good and nicked from a firewall script mentioned on floppyfw.something.
# Didn't work that well..
#
iptables -A syn-flood -j DROP
# Make sure NEW tcp connections are SYN packets
iptables -A INPUT -i ${OUTSIDE_DEVICE} -p tcp ! --syn -m state --state NEW -j DROP
#---------------内部外出的目的NAT设置-------------
#--使用代理请打开下面二条
#iptables -t nat -N inside-pre
#iptables -t nat -A inside-pre -p tcp -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} --dport 80 -j REDIRECT --to-port 3128
#---------------外部访问内部的目的NAT设置-------------
iptables -t nat -N outside-pre
iptables -t nat -A outside-pre -p tcp -d ${OUTSIDE_IP} --dport 80 -j DNAT --to ${MAILSERVER_IP}:80
iptables -t nat -A outside-pre -p tcp -d ${OUTSIDE_IP} --dport 81 -j DNAT --to ${WEBSERVER_IP}:80
iptables -t nat -A outside-pre -p tcp -d ${OUTSIDE_IP} --dport 25 -j DNAT --to ${MAILSERVER_IP}:25
iptables -t nat -A outside-pre -p tcp -d ${OUTSIDE_IP} --dport 110 -j DNAT --to${MAILSERVER_IP}:110
#---------------内部外出的源NAT设置-------------
iptables -t nat -N inside-post
iptables -t nat -A inside-post -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} -j SNAT --to ${OUTSIDE_IP}
#---------------内部到本机的设置-------------
iptables -N inside-in
iptables -A inside-in -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A inside-in -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} -j ACCEPT
#--用代理时请打开
#iptables -A inside-in -p tcp -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} --dport 3128 -j ACCEPT
#--用代理时请屏蔽
iptables -A inside-in -p tcp -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} --dport 80 -j ACCEPT
iptables -A inside-in -p icmp -m limit --limit 1/s --limit-burst 5 -j ACCEPT
#---------------外部到本机的设置-------------
iptables -N outside-in
iptables -A outside-in -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} -j DROP
iptables -A outside-in -p icmp -m limit --limit 1/s --limit-burst 5 -j ACCEPT
iptables -A outside-in -d ${OUTSIDE_IP} -j ACCEPT
#---------------内部到外部的转发设置-------------
iptables -N inside-fw
#iptables -A inside-fw -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
#--打开全部端口,不用这条请打开下面需出去的条目
iptables -A inside-fw -p tcp -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} --sport 1024:  -j ACCEPT
###使用SQUID请屏蔽下面一条
#iptables -A inside-fw -p tcp -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} --sport 1024: --dport 80 -j ACCEPT
#iptables -A inside-fw -p tcp -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} --sport 1024: --dport 20:21 -j ACCEPT
#iptables -A inside-fw -p tcp -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} --sport 1024: --dport 25 -j ACCEPT
#iptables -A inside-fw -p tcp -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} --sport 1024: --dport 53 -j ACCEPT
iptables -A inside-fw -p udp -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} --sport 1024: --dport 53 -j ACCEPT
#iptables -A inside-fw -p tcp -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} --sport 1024: --dport 110 -j ACCEPT
#iptables -A inside-fw -p tcp -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} --sport 1024: --dport 443 -j ACCEPT
iptables -A inside-fw -p icmp -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} -j ACCEPT
#---------------外部到内部的转发设置-------------
iptables -N outside-fw
iptables -A outside-fw -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A outside-fw -p tcp -d ${MAILSERVER_IP} --dport 80 -j ACCEPT
iptables -A outside-fw -p tcp -d ${WEBSERVER_IP} --dport 80 -j ACCEPT
iptables -A outside-fw -p tcp -d ${MAILSERVER_IP} --dport 25 -j ACCEPT
iptables -A outside-fw -p tcp -d ${MAILSERVER_IP} --dport 110 -j ACCEPT
#====================================
#INPUT
iptables -A INPUT -i ${INSIDE_DEVICE} -j inside-in
iptables -A INPUT -i ${OUTSIDE_DEVICE} -j outside-in
#FORWARD
iptables -A FORWARD -i ${INSIDE_DEVICE} -j inside-fw
iptables -A FORWARD -i ${OUTSIDE_DEVICE} -j outside-fw
#OUTPUT
iptables -A OUTPUT -o ${INSIDE_DEVICE} -d ${INSIDE_NETWORK}/${INSIDE_NETMASK} -j ACCEPT
iptables -A OUTPUT -o ${OUTSIDE_DEVICE} -j ACCEPT
#NAT
#--用作代理时打开
#iptables -t nat -A PREROUTING -i ${INSIDE_DEVICE} -j inside-pre
iptables -t nat -A PREROUTING -i ${OUTSIDE_DEVICE} -j outside-pre
iptables -t nat -A POSTROUTING -o ${OUTSIDE_DEVICE} -j inside-post
# And also accept talking to ourself.
iptables -A INPUT -i lo -j ACCEPT
#
# And, some attempt to get interactive sesions a bit more interactive
# under load:
#
iptables -A PREROUTING -t mangle -p tcp --sport ssh  -j TOS --set-tos Minimize-Delay
iptables -A PREROUTING -t mangle -p tcp --sport ftp -j TOS --set-tos Minimize-Delay
# iptables -A PREROUTING -t mangle -p tcp --sport ftp-data -j TOS --set-tos Maximize-Throughput
#
# Finally, list what we have
#
#
#iptables -L
# If broken DNS:
#iptables -L -n
#
The insert stuff into the kernel (ipsysctl) - section:
#
# Some of there goes under the "Better safe than sorry" - banner.
#

#
# 使用动态IP地址,拨号连接用
#
#echo 7 > /proc/sys/net/ipv4/ip_dynaddr
#
# 忽略子网广播消息
#
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
#
# 禁用源路由地址
#
/bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route
#
# Syncookies (if they are really needed any more?)
#
echo "1" > /proc/sys/net/ipv4/tcp_syncookies
#
# 过滤伪造包
#
if [ -f /proc/sys/net/ipv4/conf/all/rp_filter ]
 then
  # These two are redundant but I'll kepp'em here for now.
  # Will remind me that I can add the first one somewhere smart later.
  echo "1" > /proc/sys/net/ipv4/conf/default/rp_filter
  echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
  while read filter
   do
    echo "1" > $filter
  done < `find /proc/sys/net/ipv4/conf -name rp_filter -print`
 else
  echo "Anti spoofing is not available, the author of this floppy spoofed, mail him."
fi
#
# 不发送 ICMP 重定向报文
#
if [ -f /proc/sys/net/ipv4/conf/all/accept_redirects ]
 then
  echo "0" > /proc/sys/net/ipv4/conf/default/accept_redirects
  echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects
 else
  echo "Anti spoofing is not available, the author of this floppy spoofed, mail him."
fi
#
# 忽略回应地址是广播地址的主机生成的ICMP错误
#
/bin/echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
# Maximum limit of ip_conntrack
# This is RAM dependant so be careful with this.
# The max, which is the valuehere, needs around 32M RAM to work properly.
# echo "65535" > /proc/sys/net/ipv4/ip_conntrack_max
# 降低 ip_conntrack timeout 时间,原值为432000秒
echo "600" > /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_established
#
# This is commented out and will be an option when we have a "LOG_STUFF"
# config option.
# /bin/echo "1" > /proc/sys/net/ipv4/conf/all/log_martians
#
# Rules set, we can enable forwarding in the kernel.
#
echo "Enabling IP forwarding."
echo "1" > /proc/sys/net/ipv4/ip_forward
#---- End --------------
 
以上的代码已有删节,去除了精确的过滤,如对某一机器的过滤,对MSN,QQ等的过滤,MAC的过滤...