基于Linux系统的包过滤防火墙(2)(转)

基于Linux系统的包过滤防火墙(2)(转)[@more@]

  第2章、用用户空间命令iptables实现包过滤

  2.1 相关的TCP/IP知识

  2.1.1建立TCP连接(通过3次握手实现)

  假如服务器A和客户机B通信。

  (1)B->;A。当B要和A通信时,B首先向A发一个SYN标记的包,告诉A请求建立连接。只有当A收到B发来的SYN包,才可以建立连接,除此之外别无它法。因此,如果你的防火墙丢弃所有的发往外网接口的SYN包,那么你将不能让外部任何主机主动建立连接。

  (2)B

  (3)B->;A。B收到SYN/ACK包后,B发一个确认包(ACK),通知A连接已建立。至此,3次握手完成,一个TCP连接完成。

  需要注意的是,当3次握手完成、连接建立以后,TCP连接的每个包都会设置ACK位。这就是为何连接跟踪很重要的原因了,没有连接跟踪,防火墙将无法判断收到的ACK包是否属于一个已经建立的连接。

  2.1.2 结束TCP连接(通过4次握手实现)

  假如服务器A和客户机B通信。注意,由于TCP连接是双向连接,因此关闭连接需要在两个方向上做。

  (1)B->;A。当B要与A结束通信时,B首先向A发一个FIN标记的包,告诉A请求结束连接。由于连接还没有关闭,FIN包总是打上ACK标记。没有ACK标记而仅有FIN标记的包不是合法的包,并且通常被认为是恶意的。

  (2)B;A传输通道。不过A->;B可能还有数据包需要传送,所以A->;B传输通道仍旧继续畅通,直到传输完毕才会进入下一步。

  (3)B

  (4)B->;A。B送出ACK包给A进行确认。

  2.1.3 发送连接复位包结束TCP连接

  4次握手不是结束TCP连接的唯一方法。有时,如果主机需要尽快关闭连接(或连接超时,端口或主机不可达),RST包将被发送。注意,由于RST包不是 TCP连接中的必须部分,可以只发送RST包(即不带ACK标记)。但在正常的TCP连接中RST包可以带ACK确认标记。注意,RST包是可以不要收方进行确认的。

  2.1.4 无效的TCP标记

  至此,已经看到了SYN、ACK、FIN、和RST标记。另外,还有PSH和URG标记。

  最常见的非法组合是SYN/FIN包。注意,由于SYN包是用来初始化连接的,它不可能和FIN以及RST标记一起出现,这也是一个恶意攻击。

  当网络中出现别的一些组合(如SYN/FIN/PSH、SYN/FIN/RST、SYN/FIN/RST/PSH),很明显网络肯定受到了攻击。

  另外,已知的非法包还有FIN(无ACK标记)和“NULL”包。如同早先讨论的,由于ACK/FIN包的出现是为了结束一个TCP连接,那么正常的 FIN包总是带有ACK标记的。“NULL”包就是没有任何TCP标记的包(URG、ACK、PSH、RST、SYN、FIN都为0)。

  在正常的网络活动下,到目前为止TCP协议栈不可能产生带有上面提到的任何一个标记组合的TCP包。当你发现这些不正常的包时,肯定有人对你的网络不怀好意。

  2.1.5 ICMP类型

  ICMP是网间控制消息协议,用来在主机/路由器之间传递控制信息的协议。ICMP包可以包含诊断信息(ping 、 tracerouter)、错误信息(网络/主机/端口不可达),信息(时间戳timestamp,地址掩码address mask等)、或控制信息(source quench、redirect等)。

  使用包过滤可以拒绝指定的ICMP类型。

  此外,下面类型的ICMP信息建议丢弃。

  Redirect(5)、Alternate Host Address(6)、Router Advertisement(9)能用来转发通信。    

  Echo(8)、Timestamp(13)、Address Mask Request(17)能用来分别判断主机是否启动、本地时间和地址掩码。它们是和返回的信息类别有关的。其本身是不能被利用的,但它们泄漏出的信息对攻击者是有用的,所以建议丢弃这些类型的ICMP。

  关于ICMP类型的更详细的表述参见RFC792。

  2.2 iptables语法

  2.2.1 Iptables的优点

  → iptables允许建立状态(stateful)防火墙,就是在内存中保存穿过防火墙的每条连接。这种模式对于有效地配置FTP和DNS以及其它网络服务是必要的。

  →iptables能够过滤TCP标志任意组合报文,还能够过滤MAC地址。

  →系统日志比ipchains更容易配置,扩展性也更好。

  →对于网络地址转换(Network Address Translation)和透明代理的支持,Netfilter更为强大和易于使用。

  →iptables能够阻止某些DoS攻击,例如SYS洪泛攻击。

  2.2.2 Iptables的规则要素

  一条iptables规则基本上应该包含5个要素:

  →指定表(table)

  →指定操作命令(command)

  →指定链(chains)

  →指定规则匹配器(matcher)

  →指定目标动作(target)

  (1)表。Iptables从其使用的3个表而得名,分别是filter、nat、mangle。对于包过滤防火墙只使用filter表。表filter是默认的表,无需显示说明。

  (2)操作命令。包括添加、删除、更新等。

  (3)链。对于包过滤防火墙可操作filter表中的INPUT链、OUTPUT链和FORWARD链。也可以操作由用户自己定义的自定义链。

  (4)规则匹配器。可以指定各种规则匹配,如IP地址、端口、包类型等。

  目标动作。当规则匹配一个包时,真正要执行的任务用目标标识。最常用的内置目标分别是:

  →ACCEPT表示允许包通过

  →DROP表示被丢弃

  此外,包过滤防火墙还可以使用扩展的目标:

  →REJECT表示拒绝包,丢弃包的同时给发送者发送没有接受的通知。

  →LOG表示包的有关信息被记录日志。

  →TOS表示改写包的ToS的值。

  要使用上述的扩展目标,必须在内核中激活相应选项或者装载了相应的内核模块。

  2.2.3 Iptables工具的调用语法

  Iptables的语法非常复杂,要查看该工具的完整语法,应该查看其手册页。

  Iptables的语法通常可以简化为下面的形式:

  Iptables[-t table]CMD[chain][rule-matcher][-j target]

  其中:tables为表名,CMD为操作命令,chain为链名,rule-matcher为规则匹配器,target为目标动作。

  2.2.4 制定永久性规则

  iptables软件包提供了两个命令分别用于保存和恢复规则集。可以使用下在的命令转储在内存中的内核规则集。其中/etc/sysconfig/iptables是iptables守护进程调用的默认规则集文件:

  #/sbin/iptables-save >; /etc/sysconfig/iptables

  要恢复原来的规则库,需使用命令:

  #/sbin/iptables-restore < /etc/sysconfig/iptables

  为了使得用iptables命令配置的规则在下次启动机器时还能被使用,有两种主法。

  (1)使用iptables的启动脚本实现。Iptables的启动脚本/etc/rc.d/init.d/iptables每次启动时都使用/etc/sysconfig/iptables所提供的规则进行规则恢复,并可以使用如下的命令保存规则:

  #service iptables save

  (2) 在自定义脚本中用iptables命令直接创建规则集。可以直接用iptables命令编写一个规则脚本,并在启动时执行这个脚本。

  例如:若规则脚本的文件名为/etc/fw/rules,则可以在启动脚本/etc/rd.d/init.d/rc.local中加入下面的代码:

  if[-x /etc/fw/rules];then /etc/fw/rules;fi;

  这样,机器每次启动时即可执行该规则脚本。

  如果使用此种方式,建议使用ntsysv命令关闭系统的iptables守护进程。

  2.3 iptables命令使用举例

  2.3.1 链的基本操作

  (1)清除所有的规则。通常在开始配置包过滤防火墙之初清除所有的规则,重新开始配置,以免原有的规则影响新的设定。使用如下命令进行:

  1)    清除预设表filter中所有规则链中的规则。

  #iptables -F

  2)清除预设表filter中使用者自定义链中的规则。

  #iptables -X

  3)将指定链所有规则的包字节记数器清零。

  #iptables -Z

  (2)设置链的默认策略。一般地,配置链的默认策略有两种方法。

  1)    首先允许所有的包,然后再禁止有危险的包通过防火墙。即“没有被拒绝的都允许”。这种方法对于用户而言比较灵活方便,但对系统而言,容易引起严重的安全问题。

  为此,应该使用如下的初始化命令:

  #iptables -P INPUT ACCEPT

  #iptables -P OUTPUT ACCEPT

  #iptables -P FORWARD ACCEPT

  2)    首先禁止所有的包,然后再根据需要的服务允许特定的包通过防火墙。即“没有明确允许的都被拒绝”。这种方法最安全,但不太方便。为了使得系统有足够的安全性,一般采用此种策略进行iptables防火墙的配置。

  为此,应该使用如下的初始化命令:

  #iptables -P INPUT DROP

  #iptables -P OUTPUT DROP

  #iptables -P FORWAED DROP

  3)列出表/链中的所有规则。包过滤防火墙只使用filter表,此表为默认的表,因此可以使用下面的命令列出filter表中所有规则:

  #iptables -L

  使用上面的命令时,iptables将逆向解析IP地址,这将发费很多时间,从而造成信息出来的非常慢。为了解决这个问题,可以使用下面的带有-n参数的命令(-n参数用于显示数字化的地址和端口):

  #iptables -L -n

  4)向链中添加规则。下面的语句用于开放网络接口:

  #iptables -A INPUT -i lo -j ACCEPT

  #iptables -A OUTPUT -o lo -j ACCEPT

  #iptables -A INPUT -i eth0 -j ACCEPT 

  #iptables -A OUTPUT -o eth0 -j ACCEPT

  #iptables -A FORWARD -i eth0 -j ACCEPT

  #iptables -A FPRWAED -o eth0 -j ACCEPT

  5)使用用户自定义链。下面是一个用户自定义链的创建、修改和调用的简单命令序列:

  #iptables -N custom

  #iptables -A custom -s 0/0 -d 0/0 -p icmp -j DROP

  #iptables -A INPUT -s 0/0 -d 0/0 -j custom

  首先使用带-N参数的iptables命令新建了一个名为custom的用户逢定义链。然后使用带-A参数的命令添加了一条用户自定义的堵截规则,该规则丢弃全部的ICMP包。最后向默认的INPUT链加入一条规则,使所有的包都由custom自定义链处理。结果全部的ICMP包都将被丢弃。

  2.3.2 设置基本的规则匹配

  下面举例说明iptables的基本规则匹配(忽略目标动作):

  (1)指定协议匹配

  1)匹配指定的协议

  #iptables -A INPUT -p tcp

  2)匹配指定协议之外的所有协议

  #iptables -A INPUT -p !tcp

  (2)指定地址匹配

  1)指定匹配的主机

  #iptables -A INPUT -s 192.168.1.1

  2)指定匹配的网络

  #iptables -A INPUT -s 192.168.1.0/24

  3)匹配指定主机之外的地址。

  #iptables -A FORWARD -s ! 192.168.0.1

  4)匹配指定网络之外的网络

  #iptables -A FORWARD -s ! 192.168.0.0/24

  (3)指定网络接口匹配。

  1)指定单一的网络接口匹配。

  #iptables -A INPUT -i eth0

  #iptables -A FORWARD -o eth0

  2)指定同类型的网络接口匹配

  #iptables -A FORWARD -o ppp+

  (4)指定端口匹配

  1)指定单一的端口匹配。

  #iptables -A INPUT -p tcp-sport www

  #iptables -A INPUT -p tcp-sport 80

  #iptables -A INPUT -p tcp-sport 53

  #iptables -A INPUT -p udp-dport 53

  2)匹配指定端口之外的端口。

  #iptables -A INPUT -p tcp-dport ! 22

  3)匹配指定端口的范围。

  #iptables -A INPUT -p tcp-soprt 22:80

  4)匹配ICMP端口和ICMP类型。

  #iptables -A INPUT -p icmp --icmp-type 8

  5)指定ip碎片

  在TCP/IP通信过程中,每一个网络接口都有一个最大的传输单元(MTU),这个参数定义了可以通过的数据包的最大尺寸。如果一个数据包大于这个参数值时,系统会将其划分成更小的数个数据包(称之为ip碎片)来传输,而接收方则对这些ip碎片再进行重组以还原整个包。

  但是在进行包过滤的时候,ip碎片会导致这样一个问题:当系统将大数据包划分成ip碎片传送时,第一个碎片含有完整的包头信息(IP+TCP、UDP和 ICMP),但是后续的碎片只有包头的部分信息(如源地址、目的地址)。因此,检查后面的ip碎片的头部(就像有TCP、UDP和ICMP一样)是不可能的。假如有这样一条规则:

  #iptables -A FORWARD -p tcp -s 192.168.1.0/24 -d 192.168.2.100 --dport 80 -j ACCEPT

  并且这时的FORWARD的策略(policy)为DROP时,系统只会让第一个ip碎片通过,而丢掉其余的ip碎片,因为第一个碎片含有完整的包头信息,可以满足该规则的条件,而余下的碎片因为包头信息不完整而无法满足规则定义的条件,因而无法通过。

  可以通过-fragment/-f选项来指定第二个及其以后的ip碎片,以上面的例子为例,我们可以再加上这样一条规则来解决这个问题:

  #iptables -A FORWARD -f -s 192.168.1.0/24 -d 192.168.2.100 -j ACCEPT

  但是需要注意的是,现在已经有许多进行ip碎片攻击的实例(例如向Win98 NT4SP5,6 Win2K发送大量的ip碎片进行DoS攻击),因此允许ip碎片通过是有安全隐患的,对于这一点可以采用iptables的匹配扩展来进行限制。

  2.3.3 设置扩展的规则匹配

  要获得匹配的简要说明,可以使用如下的命令:

  #iptables -m name_of_match -help

  下面举例说明iptables的扩展规则匹配(忽略目标动作):

  (1)多端口匹配扩展。

  1)匹配多个源端口。

  #iptables -A INPUT -p tcp -m multiport-source-port 22,53,80,110

  2)匹配多个目的端口

  #iptables -A INPUT -p tcp -m multiport-destionation-port 22,53,80,110

  3)匹配多个端口(无论源源端口还是目的端口)。

  #iptables -A INPUT -p tcp -m multiport -port 22,53,80,110

  (2)指定TCP匹配扩展

  通过使用-tcp-flags选项可以根据tcp包的标志位进行过滤,该选项后接两个参数:第一个参数为要检查的标志位,可以是SYN、ACK、FIN、URG、PSH的组合,可以用ALL指定所有标志位:第二个参数是标志位值为1的标志。

  #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的才匹配。

  选项-syn是以上的一种特殊情况,相当于“--tcp-flags SYN,RST,ACK SYN“的简写。

  #iptables -p tc-syn

  (3)limit速率匹配扩展。

  1)指定单位时间内允许通过的数据包的个数。

  单位时间可以是/second、/minute、/hour、/day或使用第一个字母。例如:

  #iptables -A INPUT -m limit-limit 300/hour

  表示限制每小时允许通过300个数据包。

  2)指定触发事件的阀值。

  使用-limit-burst指定触发事件的阀值(默认是5),用来比对瞬间大量数据包的数量。

  #iptables -A INPUT -m limit-limit-burst 10

  上面的例子是用来比对一次同时涌入的封包是否超过10个,超过此上限的包将被直接丢弃。

  3)同时指定速率限制和触发阀值。

  #iptables -A INPUT -p icmp -m limit-limit 3/m-limit-burst 3

  假设均匀通过,平均每分钟3个,那么触发阀值burst保持为3个,如果每分钟通过的包的数目小于3,那么触发阀值burst将在每个周期(若每分钟允许通过3个,则周期数为20秒)后加1,但最大值为3。每分钟要通过的包的数量如果超过3,那么触发阀值burst将减掉超出的数值,例如第二分钟有4个包,那么触发阀值burst变成2,同时4个包都可以通过,第三分钟有6个包,则只能通过5个,触发阀值burst将变成0。之后,每分钟如果包数小于等于3,则触发阀值burst将加1,如果每分钟包数大于3,触发阀值burst将逐渐减小最终维持为0。

  即每分钟所允许的最大包数量为限制速率(本例为3)加上当前的触发阀值burst数。在任何情况下,都可以保证3个包通过,触发阀值burst相当于是允许额外的包数量。

  (4)基于状态的匹配扩展(连接跟踪)。 

  每个网络连接包括以下信息:源地址、目的地址、源端口、目的湍口,称为套接字对(socket pairs);协议类型、连接状态(TCP协议)和超时时间等。防火墙把这些信息称为状态(stateful),能够检测每个连接状态的防火墙叫作状态包过滤防火墙。它除了能够完成简单包过滤防火墙的包过滤工作外,还在自己的内存中维护一个跟踪连接状态的表,比简单包过滤防火墙具有更大的安全性。 iptables与ipchains的不同之处在于iptables可以使用连接状态信息,创建基于包的状态的规则匹配。

  基于状态匹配创建规则的命令格式如下:

  iptables -m state-state [!]state [,state,state,state]

  其中,state表是一个用逗号分割的列表,用来指定的连接状态可以是如下的4种:

  →NEW:该包想要开始一个连接(重新连接或将连接重定向)。

  →RELATED:该包是属于某个已经建立连接所建立的新连接。例如:FTP的数据传输连接和控制连接之间就是RELATED关系。

  →ESTABLISHED:该包属于某个已经建立的连接。

  →INVALID:该包不匹配于任何连接,通常这些包会被DROP。

  例如:

  1)在INPUT链添加一条规则,匹配已经建立的连接或由已经建立的连接所建立的新连接。即匹配所有的TCP回应包。

  #iptables -A INPUT -m state-state RELATED,ESTABLISHED

  2)在INPUTP链添加一条规则,匹配所有从非eth0接口来的连接请求包。

  #iptables -A INPUT -m state-state NEW -i ! eth0

  又如,对于ftp连接可以使用下面的连接跟踪:1)被动ftp连接模式。

  #iptables -A INPUT -p tcp-sport 1024: --dport 1024: -m state-state ESTABLES -j ACCEPT

  #iptables -A OUTPUT -p tcp-sport 1024: --dport 1024: -m state-state ESTABLISHED,RELATED -j ACCEPT

  2)主动ftp连接模式。

  #iptables -A INPUT -p tcp-sport 20 -m state-state ESTABLISHED,RELATED -j ACCEPT -m state-state ESTABLISHED -j ACCEPT

  (5)TOS匹配扩展。

  所有数据包的首部都有一个称为服务类型的专用字段。该字段用于当数据包经过路由器时区分优先顺序。

  使用ToS字段,可以使用某种类型的数据包优先于其它的数据包。有标记的数据包在路由器中进行不同的处理。设置ToS字段的工作是在网络层进行的。有关ToS的具体工作过程请参专考RFC1349。

  在数据包中设置ToS字段的主要原因是:对不同类型的数据包加以区分,从而在流量较高的网络上减少网络拥塞。

  数据包的ToS字段用一个字节表示。此字节的高3位舍弃不用,最低位使用固定值0,因此,有效位共有4个。有效位分别用来控制数据包的最小延时,最大吞吐量,最大可靠度和最小成本。其中,

  →最小延时:用于减少数据包从路由到达主机的时间。

  →最大吞吐量:用于提高数据传输量。适用于FTP数据端口,HTTP大文件传输和大量的POP3传输。

  →最大可靠度:用来试图减少数据重传。

  →最小成本:通常只在商业产品中使用。

  要创建与ToS字段匹配的规则,可以使用下面的语法:

  iptables [-t table]CMD[chain]-m tos tos_value [-j target]

  其中tos_value可以是0x02、0x04、0x06、0x08、0x10。

  例如:

  #iptables -A INPUT -p tcp -m tos 0x08

  表示匹配在ToS字段中设置了最大吞吐量的包。

  2.3.4 设置目标扩展

  要获得目标的简要说明,可以使用如下的命令:

  #iptables -j name_of_TARGET-help

  目标扩展由内核模块组成,而且iptables的一个可选扩展提供了新的命令行选项。在几个扩展是包含在默认netfilter发布中的。

  (1)设置包的ToS值。为了设置数据包的ToS值,需要使用ToS目标扩展。设置ToS的值,只能对FORWARD、OUTPUT和PREROUTING链进行。语法如下:

  iptables [-t table]CMD[chain][rule-matcher]-j TOS-set-tos tos_value

  其中tos_value可以是0x02、0x04、0x06、0x08、0x10。

  下面是使用ToS目标扩展设置ToS值的一些例子:

  #iptables -A OUTPUT -p tcp -m tcp-dport 21 -j TOS-set-tos 0x10

  #iptables -A OUTPUT -p tcp -m tcp-dport 22 -j TOS-set-tos 0x10

  #iptables -A OUTPUT -p tcp -m tcp-dport 110 -j TOS-set-tos 0x08

  (2)日志记录。iptables使用新的目标扩展LOG来实现日志记录。LOG目标用syslogd记录此包并继续传播。LOG目标扩展还可以使用如下的一些参数:

  → --log-level

  跟踪一个级别名称或数字。合适的名字是'debug'、'info'、'notice'、'warning'、'err'、'crit'、'alert' 和'emerg',相当于数字7到0。参考syslog.conf的手册可获取这些级别的说明。默认是'warning'。

  → --log-prefix

  跟踪一个最多29个字符的字符串,它被写入到log信息的开始处,这样可以方便地使用grep对日志进行过滤。

  另外,在使用LOG目标扩展的同时,还可以使用limit match,这样可以使记录有用日志的同时确保日志记录不会变得冗长。

  下面是使用LOG目标扩展的一些例子:

  #iptables -A FORWARD -m tcp -p tcp -j LOG

  #iptables -A FORWARD -m icmp -p icmp-sport echo-reply -j LOG

  #iptables -A INPUT -m limit-limit 3/m-limit-burst 3 -j LOG-log-prefix "INPUT packet died:"

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752019/viewspace-955589/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752019/viewspace-955589/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值