事实上,每一个主要的Linux版本中都有不同的防火墙软件套件。Iptabels(netfilter)应用程序被认为是Linux中实现包过虑功能的第四代应用程序。第一代是Linux 内核1.1版本所使用的Alan Cox从BSD Unix中移植过来的ipfw。
在2.0版的内核中,Jos Vos和其它一些程序员对ipfw进行了扩展,并且添加了ipfwadm用户工具。在2.2版内核中, Russell和Michael Neuling做了一些非常重要的改进,也就是在该内核中,Russell添加了帮助用户控制过虑规则的ipchains工具。后来,Russell又完成了其名为netfilter(http://www.netfilter.org)的内核框架。这些防火墙软件套件一般都比其前任有所改进,表现越来越出众。
Netfilter/iptables已经包含在了2.4以后的内核当中,它可以实现防火墙、NAT(网络地址翻译)和数据包的分割等功能。 netfilter工作在内核内部,而iptables则是让用户定义规则集的表结构。netfilter/iptables是从ipchains和 ipwadfm(IP防火墙管理)演化而来的,为了简单起见,下文中,我就将其统一称为iptables。
iptables的其它一些好的用法是为Unix、Linux和BSD个人工作站创建一个防火墙,当然也可以为一个子网创建防火墙以保护其它的系统平台。 iptables只读取数据包的头,所以不会给信息流增加负担,此外它也无需进行验证。如果要想获得更好的安全性,可以将其和一个代理服务器(比如 squid)相结合。
概述
在众多的网络防火墙产品中,Linux操作系统上的防火墙软件特点显著。它们和Linux一样,具有强大的功能,大多是开放软件,不仅可免费使用而且源代码公开。这些优势是其他防火墙产品不可比拟的。选用这类软件确实是最低硬件需求的可靠、高效的解决方案。但用户最关心的还是安全系统的性能,有关部门根据网络安全调查和分析曾得出结论:网络上的安全漏洞和隐患绝大部分是因网络设置不当引起的。使用Linux平台上的这些优秀软件同样也存在这样的问题。要使系统安全高效地运行,安装人员和管理人员必须能够理解该软件产品的运行机制并能深入分析所采用的防火墙设置策略会不会被人利用。本文仅对Linux平台上的IP包过滤防火墙软件Ipchains进行探讨。
一。防火墙的基本模型
基于TCP/IP协议簇的Internet网际互联完全依赖于网络层以上的协议栈(网络层的IP协议、传输控制协议TCP/UDP协议和应用层协议)。考虑到网络防火墙是为了保持网络连通性而设立的安全机制,因此防火墙技术就是通过分析、控制网络以上层协议特征,实现被保护网络所需安全策略的技术。构建防火墙有三类基本模型:即应用代理网关、电路级网关(Circuit Level Gateway)和网络层防火墙。它们涉及的技术有应用代理技术和包过滤技术等。
应用代理网关允许内部网络上的用户通过防火墙非直接地访问Internet。它根据用户的请求代替用户与目的地进行连接。由于应用代理网关在应用层进行代理,所以它可以对应用协议进行控制,而且还可以在应用级进行记录。它比网络级防火墙的安全措施更加严格,因为它能提供更详细的审计报告、跟踪用户和应用进程以及IP包的参数。然而,采用应用层防火墙对网络性能有较大影响。由于对任何用户的请求都要求应用代理进程为其提供应用服务,所以速度较慢,并且不如网络层防火墙那样透明以及维护不便等。在Linux上实现这种防火墙模型的软件有squid等。
电路级网关与应用代理网关类似,但进行的代理通常与应用无关。这样就失去了详尽记录和精确定义规则的能力。电路级网关是一台运行网关应用程序的设备,它只支持TCP/IP应用,使用TCP端口实现网络资源和用户应用程序之间的通信。它还要求客户端使用特殊软件才能为应用到应用的通信服务。SOCKS是Linux上实现这类防火墙模型的软件。
网络层的IP包过滤防火墙在IP包水平上工作。它根据在每个包中的源地址、目的地址和包类型等信息控制包的流动。更彻底的过滤过程是检查包中的源、目的端口号以及连接状态等信息。这种防火墙比较安全,但缺少足够的记录信息。它可以阻止外部网络访问被保护的内部网络,但不能记录谁访问了公开的系统,以及谁从内部网络访问Internet。在Linux内核中支持IP包过滤,所以不需要增加其他软件就可以构建包过滤防火墙,Ipchains软件包是Linux平台上一个功能强大的包过滤策略管理软件,用于设置可靠的防火墙系统。
二、不应该过滤的包
在开始过滤某些不想要的包之前要注意以下内容:
● ICMP包
ICMP包可用于检测TCP/IP失败的情形。如果阻挡这些包将导致不能得到“Host unreachable”或“No route to host”等信息。ICMP包还用于MTU发现,某些TCP实现使用了MTU发现来决定是否进行分段。MTU发现通过发送设置了不进行分段的位的包探测,当得到的ICMP应答表示需要分段时,再发送较小的包。如果得不到ICMP包(“destination unreachable”类型的包),则本地主机不减少MTU大小,这将导致测试无法停止或网络性能下降。
● 到DNS的TCP连接
如果要拦阻出去的TCP连接,那么要记住DNS不总是使用UDP。如果从DNS服务器过来的回答超过512字节,客户端将使用TCP连接,并仍使用端口53接收数据。若禁止了TCP连接,DNS大多数情况下会正常工作,但可能会有奇怪的延时故障出现。如果内部网络的DNS查询总是指向某个固定的外部DNS服务器,可以允许本地域端口到该服务器的域端口连接。
● 主动式FTP的TCP连接
FTP有两种运作方式,即传统的主动式(active)方式和目前流行的被动式(passive)方式。在主动式FTP模式下,FTP 服务器发送文件或应答LS命令时,主动和客户端建立TCP连接。如果这些TCP连接被过滤,则主动方式的FTP将被中断。如果使用被动方式,则过滤远地的TCP连接没有问题。因为数据连接是从客户端到服务器进行的(包括双向的数据)。
三、针对可能的网络攻击
防火墙的性能是否优良关键在于其配置能否防护来自外界的各种网络攻击。这要求网络管理者能针对可能的网络攻击特点设定完善的安全策略。以网络常见的“ping of death”攻击为例,“ping of death”攻击通过发送一个非法的大ICMP包使接收者的TCP堆栈溢出从而引起混乱。针对这种攻击可将防火墙配置为阻挡ICMP分段。因为普通的ICMP包大都不需要到分段的程度,阻挡ICMP分段只拦阻大的“ping”包。 这种防护策略也可用于针对其他协议安全缺陷的网络攻击。
什么是Iptables?
iptables 是建立在 netfilter 架构基础上的一个包过滤管理工具,最主要的作用是用来做防火墙或透明代理。Iptables 从 ipchains 发展而来,它的功能更为强大。Iptables 提供以下三种功能:包过滤、NAT(网络地址转换)和通用的 pre-route packet mangling。包过滤:用来过滤包,但是不修改包的内容。Iptables 在包过滤方面相对于 ipchians 的主要优点是速度更快,使用更方便。NAT:NAT 可以分为源地址 NAT 和目的地址 NAT。
Iptables 可以追加、插入或删除包过滤规则。实际上真正执行这些过虑规则的是 netfilter 及其相关模块(如 iptables 模块和 nat 模块)。Netfilter 是 Linux 核心中一个通用架构,它提供了一系列的 “表”(tables),每个表由若干 “链”(chains)组成,而每条链中可以有一条或数条 “规则”(rule)组成。
系统缺省的表为 “filter”,该表中包含了 INPUT、FORWARD 和 OUTPUT 3 个链。
每一条链中可以有一条或数条规则,每一条规则都是这样定义的:如果数据包头符合这样的条件,就这样处理这个数据包。当一个数据包到达一个链时,系统就会从第一条规则开始检查,看是否符合该规则所定义的条件: 如果满足,系统将根据该条规则所定义的方法处理该数据包;如果不满足则继续检查下一条规则。最后,如果该数据包不符合该链中任一条规则的话,系统就会根据该链预先定义的策略来处理该数据包。
? table,chain,rule
iptables 可以操纵3 个表:filter 表,nat 表,mangle 表。
NAT 和一般的 mangle 用 -t 参数指定要操作哪个表。filter 是默认的表,如果没有 -t 参数,就默认对 filter 表操作。
Rule 规则:过滤规则,端口转发规则等,例如:禁止任何机器 ping 我们的服务器,可以在服务器上设置一条规则:
iptables -A INPUT -s ! 127.0.0.1 -p icmp -j DROP
从 –s 开始即是一条规则,-j 前面是规则的条件,-j 开始是规则的行为(目的)。整条命令解释为,在filter 表中的 INPUT 规则链中插入一条规则,所有源地址不为 127.0.0.1 的 icmp 包都被抛弃。
Chain 规则链:由一系列规则组成,每个包顺序经过 chain 中的每一条规则。chain 又分为系统 chain和用户创建的 chain。下面先叙述系统 chain。
filter 表的系统 chain: INPUT,FORWAD,OUTPUT
nat 表的系统 chain: PREROUTING,POSTROUTING,OUTPUT
mangle 表的系统 chain: PREROUTING,OUTPUT
每条系统 chain 在确定的位置被检查。比如在包过滤中,所有的目的地址为本地的包,则会进入INPUT 规则链,而从本地出去的包会进入 OUTPUT 规则链。
所有的 table 和 chain 开机时都为空,设置 iptables 的方法就是在合适的 table 和系统 chain 中添相应的规则。
--------------------------------------------------------------
IPTABLES 语法:
表: iptables从其使用的三个表(filter、nat、mangle)而得名, 对包过滤只使用 filter 表, filter还是默认表,无需显示说明.
操作命令: 即添加、删除、更新等。
链:对于包过滤可以针对filter表中的INPUT、OUTPUT、FORWARD链,也可以操作用户自定义的链。
规则匹配器:可以指定各种规则匹配,如IP地址、端口、包类型等。
目标动作:当规则匹配一个包时,真正要执行的任务,常用的有:
ACCEPT 允许包通过
DROP 丢弃包
一些扩展的目标还有:
REJECT 拒绝包,丢弃包同时给发送者发送没有接受的通知
LOG 包有关信息记录到日志
TOS 改写包的TOS值
为使FORWARD规则能够生效,可使用下面2种方法的某种:
[root@rhlinux root]# vi /proc/sys/net/ipv4/ip_forward
[root@rhlinux root]# echo "1" > /proc/sys/net/ipv4/ip_forward
[root@rhlinux root]# vi /etc/sysconfig/network
[root@rhlinux root]# echo "FORWARD_IPV4=true" > /etc/sysconfig/network
--------------------------------------------------------
iptables语法可以简化为下面的形式:
iptables [-t table] CMD [chain] [rule-matcher] [-j target]
--------------------------------------------------------
常用操作命令:
-A 或 -append 在所选链尾加入一条或多条规则
-D 或 -delete 在所选链尾部删除一条或者多条规则
-R 或 -replace 在所选链中替换一条匹配规则
-I 或 -insert 以给出的规则号在所选链中插入一条或者多条规则. 如果规则号为1,即在链头部.
-L 或 -list 列出指定链中的所有规则,如果没有指定链,将列出链中的所有规则.
-F 或 -flush 清除指定链和表中的所由规则, 假如不指定链,那么所有链都将被清空.
-N 或 -new-chain 以指定名创建一条新的用户自定义链,不能与已有链名相同.
-X 或 -delete-chain 删除指定的用户定义帘,必需保证链中的规则都不在使用时才能删除,若没有指定链,则删除所有用户链.
-P 或 -policy 为永久帘指定默认规则(内置链策略),用户定义帘没有缺省规则,缺省规则也使规则链中的最后一条规则,用-L显示时它在第一行显示.
-C 或 -check 检查给定的包是否与指定链的规则相匹配.
-Z 或 -zero 将指定帘中所由的规则包字节(BYTE)计数器清零.
-h 显示帮助信息.
-------------------------------------------------------------
常用匹配规则器:
-p , [!] protocol 指出要匹配的协议,可以是tcp, udp, icmp, all, 前缀!为逻辑非,表示除该协议外的所有协议.
-s [!] address[/mask] 指定源地址或者地址范围.
-sport [!] port[:port] 指定源端口号或范围,可以用端口号也可以用/ETC/SERVICES文件中的名子.
-d [!] address[/mask] 指定目的地址或者地址范围.
-dport [!] port[:port] 指定目的端口号或范围,可以用端口号也可以用/ETC/SERVICES文件中的名子.
-icmp-type [!] typename 指定匹配规则的ICMP信息类型(可以使用 iptables -p icmp -h 查看有效的ICMP类型名)
-i [!] interface name[+] 匹配单独或某种类型的接口,此参数忽略时,默认符合所有接口,接口可以使用"!"来匹配捕食指定接口来的包.参数interface是接口名,如 eth0, eht1, ppp0等,指定一个目前不存在的接口是完全合法的,规则直到接口工作时才起作用,折中指定对于PPP等类似连接是非常有用的."+"表示匹配所有此类型接口.该选项只针对于INPUT,FORWARD和PREROUTING链是合法的.
-o [!] interface name[+] 匹配规则的对外网络接口,该选项只针对于OUTPUT,FORWARD,POSTROUTING链是合法的.
[!] --syn 仅仅匹配设置了SYN位, 清除了ACK, FIN位的TCP包. 这些包表示请求初始化的TCP连接.阻止从接口来的这样的包将会阻止外来的TCP连接请求.但输出的TCP连接请求将不受影响.这个参数仅仅当协议类型设置为了TCP才能使用. 此参数可以使用"!"标志匹配已存在的返回包,一般用于限制网络流量,即只允许已有的,向外发送的连接所返回的包.
----------------------------------------------------------
如何制定永久规则集:
/etc/sysconfig/iptables 文件是 iptables 守护进程调用的默认规则集文件.
可以使用以下命令保存执行过的IPTABLES命令:
/sbin/iptables-save > /etc/sysconfig/iptables
要恢复原来的规则库,可以使用:
/sbin/iptables-restore < /etc/sysconfig/iptables
iptables命令和route等命令一样,重启之后就会恢复,所以:
[root@rhlinux root]# service iptables save
将当前规则储存到 /etc/sysconfig/iptables: [ 确定 ]
令一种方法是 /etc/rc.d/init.d/iptables 是IPTABLES的启动脚本,所以:
[root@rhlinux root]# /etc/rc.d/init.d/iptables save
将当前规则储存到 /etc/sysconfig/iptables: [ 确定 ]
以上几种方法只使用某种即可.
若要自定义脚本,可直接使用iptables命令编写一个规则脚本,并在启动时执行:
例如若规则使用脚本文件名/etc/fw/rule, 则可以在/etc/rc.d/rc.local中加入以下代码:
if [-x /etc/fw/rule]; then /etc/fw/sule; fi;
这样每次启动都执行该规则脚本,如果用这种方法,建议NTSYSV中停止IPTABLES.
----------------------------------------------------------
实例:
链基本操作:
[root@rh34 root]# iptables -L -n
(列出表/链中的所有规则,包过滤防火墙默认使用的是filter表,因此使用此命令将列出filter表中所有内容,-n参数可加快显示速度,也可不加-n参数。)
[root@rh34 root]# iptables -F
(清除预设表filter中所有规则链中的规则)
[root@rh34 root]# iptables -X
(清除预设表filter中使用者自定义链中的规则)
[root@rh34 root]# iptables -Z
(将指定链规则中的所有包字节计数器清零)
------------------------------------------------------------
设置链的默认策略,默认允许所有,或者丢弃所有:
[root@rh34 root]# iptables -P INPUT ACCEPT
[root@rh34 root]# iptables -P OUTPUT ACCEPT
[root@rh34 root]# iptables -P FORWARD ACCEPT
(以上我们在不同方向设置默认允许策略,若丢弃则应是DROP,严格意义上防火墙应该是DROP然后再允许特定)
---------------------------------------------------------------
向链中添加规则,下面的例子是开放指定网络接口(信任接口时比较实用):
[root@rh34 root]# iptables -A INPUT -i eth1 -j ACCEPT
[root@rh34 root]# iptables -A OUTPUT -o eth1 -j ACCEPT
[root@rh34 root]# iptables -A FORWARD -i eth1 -j ACCEPT
[root@rh34 root]# iptables -A FORWARD -o eth1 -j ACCEPT
--------------------------------------------------------------
使用用户自定义链:
[root@rh34 root]# iptables -N brus
(创建一个用户自定义名叫brus的链)
[root@rh34 root]# iptables -A brus -s 0/0 -d 0/0 -p icmp -j DROP
(在此链中设置了一条规则)
[root@rh34 root]# iptables -A INPUT -s 0/0 -d 0/0 -j brus
(向默认的INPUT链添加一条规则,使所有包都由brus自定义链处理)
----------------------------------------------------------------
基本匹配规则实例:
匹配协议:
iptables -A INPUT -p tcp
(指定匹配协议为TCP)
iptables -A INPUT -p ! tcp
(指定匹配TCP以外的协议)
匹配地址:
iptables -A INPUT -s 192.168.1.1
(匹配主机)
iptables -A INPUT -s 192.168.1.0/24
(匹配网络)
iptables -A FORWARD -s ! 192.168.1.1
(匹配以外的主机)
iptables -A FORWARD -s ! 192.168.1.0/24
(匹配以外的网络)
匹配接口:
iptables -A INPUT -i eth0
iptables -A FORWARD -o eth0
(匹配某个指定的接口)
iptables -A FORWARD -o ppp+
(匹配所有类型为ppp的接口)
匹配端口:
iptables -A INPUT -p tcp --sport www
iptables -A INPUT -p tcp --sport 80
(匹配单一指定源端口)
iptables -A INPUT -p ucp --dport 53
(匹配单一指定目的端口)
iptables -A INPUT -p ucp --dport ! 53
(指定端口以外)
iptables -A INPUT -p tcp --dport 22:80
(指定端口范围,这里我们实现的是22到80端口)
---------------------------------------------------------------------------------
指定IP碎片的处理:
[root@rh34 root]# iptables -A FORWARD -p tcp -s 192.168.1.0/24 -d 192.168.1.234 --dport 80 -j ACCEPT
[root@rh34 root]# iptables -A FORWARD -f -p tcp -s 192.168.1.0/24 -d 192.168.1.234 --dport 80 -j ACCEPT
[root@rh34 root]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.1.0/24 192.168.1.234 tcp dpt:http
ACCEPT tcp -f 192.168.1.0/24 192.168.1.234 tcp dpt:http
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
----------------------------------------------------------------------------------
设置扩展的规测匹配:
(希望获得匹配的简要说明,可使用: iptables -m name_of_match --help)
多端口匹配扩展:
iptables -A INPUT -p tcp -m multiport --source-port 22,53,80
(匹配多个源端口)
iptables -A INPUT -p tcp -m multiport --destination-port 22,53,80
(匹配多个目的端口)
iptables -A INPUT -p tcp -m multiport --port 22,53,80
(匹配多个端口,无论是源还是目的端口)
-----------------------------------------------------------------------------
TCP匹配扩展:
iptables -A INPUT -p tcp --tcp-flags SYN,FIN,ACK SYN
(表示SYN、ACK、FIN的标志都要被检查,但是只有设置了SYN的才匹配)
iptables -A INPUT -p tcp --tcp-flags ALL SYN,ACK
(表示ALL:SYN、ACK、FIN、RST、URG、PSH的标志都被检查,但是只有设置了SYN和ACK的才匹配)
iptables -p tcp --syn
(选项--syn是以上的一种特殊情况,相当于“--tcp-flags SYN,RST,ACK SYN”的简写)
--------------------------------------------------------------------------------
limit速率匹配扩展:
[root@redhatlinux9 root]# iptables -A FORWARD -m limit --limit 300/hour
(表示限制每小时允许通过300个数据包)
[root@redhatlinux9 root]# iptables -A INPUT -m limit --limit-burst 10
(--limit-burst指定触发时间的值(默认为5),用来比对瞬间大量数据包的数量。)
(上面的例子用来比对一次同时涌入的数据包是否超过十个,超过此上限的包将直接被丢弃)
[root@redhatlinux9 root]# iptables -A FORWARD -p icmp -m limit --limit 3/m --limit-burst 3
(假设均匀通过,平均每分钟3个,那么触发值burst保持为3。如果每分钟通过的包的数目小于3,那么触发值busrt将在每个周期(若每分钟允许通过3个,则周期数为20秒)后加1,但最大值为3。每分钟要通过的包数量如果超过3,那么触发值busrt将减掉超出的数值,例如第二分钟有4个包,那么触发值变为2,同时4个包都可以通过,第三分钟有6个包,则只能通过5个,触发值busrt变为0。之后,每分钟如果包数量小于等于3个,则触发值busrt将加1,如果每分钟包数大于3,触发值busrt将逐渐减少,最终维持为0)
(即每分钟允许的最大包数量等于限制速率(本例中为3)加上当前的触发值busrt数。任何情况下,都可以保证3个包通过,触发值busrt相当于是允许额外的包数量)
---------------------------------------------------------------------------------
基于状态的匹配扩展(连接跟踪):
每个网络连接包括以下信息:源和目的地址、源和目的端口号,称为套接字对(cocket pairs);协议类型、连接状态(TCP协议)和超时时间等。防火墙把这些叫做状态(stateful)。能够监测每个连接状态的防火墙叫做状态宝过滤防火墙,除了能完成普通包过滤防火墙的功能外,还在自己的内存中维护一个跟踪连接状态的表,所以拥有更大的安全性。
其命令格式如下:
iptables -m state --state [!] state [,state,state,state]
state表示一个用逗号隔开的的列表,用来指定的连接状态可以有以下4种:
NEW:该包想要开始一个连接(重新连接或将连接重定向)。
RELATED:该包属于某个已经建立的连接所建立的新连接。例如FTP的数据传输连接和控制连接之间就是RELATED关系。
ESTABLISHED:该包属于某个已经建立的连接。
INVALID:该包不匹配于任何连接,通常这些包会被DROP。
例如:
[root@redhatlinux9 root]# iptables -A INPUT -m state --state RELATED,ESTABLISHED
(匹配已经建立的连接或由已经建立的连接所建立的新连接。即匹配所有的TCP回应包)
[root@redhatlinux9 root]# iptables -A INPUT -m state --state NEW -i ! eth0
(匹配所有从非eth0接口来的连接请求包)
下面是一个被动(Passive)FTP连接模式的典型连接跟踪
[root@redhatlinux9 root]# iptables -A INPUT -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED -j ACCEPT
[root@redhatlinux9 root]# iptables -A OUTPUT -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT
下面是一个主动(Active)FTP连接模式的典型连接跟踪
[root@redhatlinux9 root]# iptables -A INPUT -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@redhatlinux9 root]# iptables -A INPUT -p tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT
--------------------------------------------------------------------------------------
日志记录:
格式为: -j LOG --log-level 7 --log-prefix "......"
[root@redhatlinux9 root]# iptables -A FORWARD -m tcp -p tcp -j LOG
[root@redhatlinux9 root]# iptables -A FORWARD -m icmp -p icmp -f -j LOG
[root@redhatlinux9 root]# iptables -A FORWARD -s 192.168.1.0/24 -d 10.10.10.0/24 -p tcp --sport 80 -j LOG
[root@redhatlinux9 root]# iptables -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-prefix "INPUT packet died:"
[root@redhatlinux9 root]# iptables -A INPUT -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "New net syn:"