[网络管理]
在LINUX系统上构建防火墙
在LINUX系统上用netfilter/iptables构建防火墙
cloud/2003.11.04
mail:flashc@21cn.com
欢迎转载,转载请保留上述信息,本人水平有限,文中如有差错,敬请指出。
netfilter/iptables是linux 2.4内核里一个全新设计的防火墙,功能非常强大,配置非常灵活,合理的使用iptables用户空间配置工具可以一个强大的状态跟踪的防火墙。我个人水平有限,文中如有遗漏的有用的过滤规则,欢迎大家指出,补充进去。本文只实现了基本的入侵防御,如果你想进行更细粒度的数据包检测日志,那么就可能不太适合你了。
首先,你要确保你的内核编译了相应的netfilter/iptables模块,一般情况下,我习惯采取编译进核心的方式,编译成模块在使用时需要加载,觉得比较麻烦,而且编译进核心的话,核心大小也不会增加太大,这里假设netfilter/iptables模块已经编译进了内核,关于编译内核的资料,大家到网上查找去吧,很多的。这里我就不废话了。以下的命令在系统restart后就会自动消失,你可以写成一个shell脚本,放到/etc/init.d ,做一个简单的start/stop参数传递就可以了。这里我主要针对单一的服务器环境做的配置,如果你的网络连接着内部网络和DMZ区域,配置大体上也是相同的。
echo 0 >; /proc/sys/net/ipv4/tcp_ecn #关闭IP包头中的明确拥塞通知标志
echo 0 >; /proc/sys/net/ipv4/ip_forward #关闭IP转发
echo 1 >; /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts #忽略广播类型的ping,默认情况下LINUX系统响应广播类型的ping
echo 1 >; /proc/sys/net/ipv4/conf/*/rp_filter #防止IP欺骗,*在这里表示你的网卡接口
echo 1 >; /proc/sys/net/ipv4/conf/*/accept_source_route #禁止IP源路由
echo 0 >; /proc/sys/net/ipv4/conf/all/accept_redirects #禁止ICMP重定向
echo 1 >; /proc/sys/net/ipv4/tcp_syncookies #打开syn cookies功能
iptables -P INPUT DROP #给filter表(不使用-t选项,默认是filter表)的INPUT链指定一个缺省的过滤政策-禁止所有进入的包,如果数据包进入INPUT链后没有找到匹配的规则, 那么将使用缺省设置的DROP政策
iptables -A INPUT -i ! eth0 -j ACCEPT #如果你的机器有多个网络接口,那么这个规则将除了eth0接口(这里假设eth0是对外接口)的其他接口的进入INPUT链的数据包允许通过,就是容许内部网络的数据和防火墙的内部网卡通信啦
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT #设置一个INPUT链的规则,允许连接状态是ESTABLISHED和RELATED的数据包通过(建立连接的数据包和与先前连接相关的数据包,这个就是状态跟踪了,内核在加载或编译了这个模块后会在/proc/net/ip_conntrack里面维护一个当前连接的状态表
iptables -A INPUT -f -m limit --limit 100/s --limit-burst 100 -j ACCEPT #设置进入INPUT链的IP碎片限制,达到100个数字后,限制每秒100个碎片进入,防止IP碎片攻击
iptables -A INPUT -p icmp -m limit --limit 1/s --limit-burst 10 -j ACCEPT #设置INPUT链的ICMP连接限制,在达到10次后限制每秒允许1个ICMP数据包通过,就是防止常说的死亡之ping攻击了
iptables -A INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT #容许进入目标端口为80的,连接状态为NEW的数据包通过,就是对外开放80端口,如果需要发布其他的服务,重复这条命令,修改一下端口号就ok了
iptables -A INPUT -p tcp -i eth0 -j REJECT --reject-with tcp-reset
iptables -A INPUT -p udp -i eth0 -j REJECT --reject-with icmp-port-unreachable #这两句话是防止扫描的,主要是对其他和上面规则不匹配的连接一律应答标准TCP连接复位和ICMP端口不可到达响应,注意,如果需要添加其他的规则必须加到这两条命令的上面,否则是无效的
iptables -P OUTPUT DROP #设置OUTPUT链的缺省策略为DROP
iptables -A OUTPUT -p tcp -j ACCEPT
iptables -A OUTPUT -p udp -j ACCEPT
iptables -A OUTPUT -p icmp -j ACCEPT #允许对外的tcp/udp/icmp数据流出
# iptables -A OUTPUT -m state ESTABLISHED,RELATED -j ACCEPT #只容许连接状态为ESTABLISHED和RELATED的数据包出去,这句命令适合单独的服务器使用,因为对出去的数据限制太严(先声明我没试过,但估计应该可以)
# iptables -A OUTPUT -p tcp -s 1.2.3.4 --sport 80 --dport 1024: -j ACCEPT #允许源IP地址为1.2.3.4,源端口为80的数据,目标端口为1024以上的数据流出,适合单独的服务发布使用
查看规则表:
iptables -v -L (-t tables)
清空规则表:
iptables -F (-t tables)
附:
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE #用于动态IP NAT的,MASQUERADE是一种特殊的SNAT,使用MASQUERADE目标可以自动寻找到外网IP地址,适合拨号的动态IP使用
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to 1.2.3.4 #这个命令和上句相反,静态IP的SNAT映射使用
iptables -A INPUT -p tcp -s 192.168.0.0/24 --dport www -i eth1 -j REDIRECT --to-port 3128 #透明代理使用,将从eth1网卡进入的来源为192.168.0.0/24子网内的发往目标端口为80的连接请求重定向到本机的3128端口,当然,前提条件是你在本机的3128端口配置运行了web代理软件(如squid或oops)
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destnation 192.168.1.1:80 #适合对外发布在内部服务器上运行的服务,将到达本机的80端口的连接请求重定向到192.168.1.1的80端口,还可使用-d选项指定目标IP地址匹配