Linux 2.4内核下新型包过滤结构的使用
一、包如何穿过(traverse)过滤
内核从"filter"表格的三个列表(lists)开始,这三个列表叫做firewall chains(防火墙链)或就叫做chains (链)。这三个链分别为INPUT、OUTPUT以及FORWARD。
这跟2.0和2.2内核有很大差别。
各链(chains)如下图所示:
_____
Incoming/ \ Outgoing
-->[Routing ]--->|FORWARD|------->
[Decision]\_____/ ^
| |
v ____
___/\
/ \ |OUTPUT|
|INPUT| \____/
\___/ ^
||
----> Local Process ----
其中三个圈代表前述的三个链,当一个包抵达上图其中的一个链时,相应的链就会被检验(examined)以决定如何处理这个包。如果链认为应该丢弃(DROP)这个包,则将该包丢弃;如果链认为应该接受(ACCEPT)该包,那么它将继续在图中穿越。
一个链(chain)其实就是众多规则(rules)钟的一个检查清单(checklist)。每一条规则的形式就像这样:"如果包的头是这样,就这样处理该包"。如果规则的设定和包不匹配,则交由链中的下一条规则继续处理。直到最后没有余下的规则可以参考,那么内核就会根据链的策略(policy)以决定如何处理。在一个安全性强的系统中,策略通常都会要求内核丢弃该包。
(1)当一个包进入时(假设通过Ethernet网卡),内核首先看包的目的地(destination):这被称为路由(routing)。
(2)如果目的地址为本机,这个包就按图时下行至INPUT链,如果能够通过,则进入后面的包处理过程。
(3)否则,如果内核没有启动转发功能,或者它不知道如何转发这个包,那么该包就会被丢弃。如果转发功能已经启动,同时包指向另一网络接口(如果连接有另一网络),那么这个包将按图示向右行至FORWARD链。如果该包未被接受,那么它将会被发送出去。
(4)最后一种情况:一个在本机运行的程序发送网络包,这时包会直接经过OUTPUT链,如果被接受,该包会继续被发送到它所指定的网络接口。
二、使用iptables
iptables很有用。上文中讲到的三个内建(built-in)链:INPUT、OUTPUT和FORWARD是不能删除的。下面看看如何管理整个链:
(1)建立一个新链(-N)
(2)删除一个空链(-X)
(3)改变一个内建链的策略(-P)
(4)列出一个链中的规则(-L)
(5)清楚一个链中的所有规则(-F)
(6)将一个链中的所有规则的包字节计数器请零(-Z)
下面的操作用于管理链中的规则:
(1)向一个链追加(append)一条新规则(-A)
(2)在链内指定位置插入一条新规则(-I)
(3)替换链内指定位置的一条规则(-R)
(4)删除链内指定位置的一条规则(-D)
(5)删除链内第一条规则(-D)
机器启动时的处理
iptables模块的文件名为"iptable_filter.o",第一次运行时,iptables就会被自动载入。它也可以永久性地建于内核中。
在运行任何iptables命令之前(注意,有些发布版可能会用它们的初始命令来运行iptables),内建链(INPUT、OUTPUT和FORWARD)将不带任何规则,所有链的策略都被设为ACCEPT。可以通过将iptable_filter模块选项设为"forward=0"来改变缺省的FORWARD链策略。
单一规则的操作
最常用的命令可能是append(-A)和delete(-D),其它如insert(-I)和replace(-R)命令只是它们的扩展而已。
每一条规则都限定了一组条件(conditions)来于特定的包比较,还规定了当包与所设条件相匹配时的处理(指目标"target")。例如,要丢弃所有来自127.0.0.1这个IP地址的ICMP包,则条件可设为:协议必须是ICMP且源地址必须是127.0.0.1,而目标应设为"DROP"。
127.0.0.1被称为"回路(loopback)"接口,即使机器没有真正的网络连接,也会有这个接口。用户可以使用"ping"命令来产生这样的包(它只是发送一个类型为8即应答请求的ICMP包,而所有愿意应答的协作主机将回送一个类型为0即应答响应的ICMP包)。这个命令常用于测试。
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl-64 time=0.2ms
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.2/0.2/0.2 ms
# iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
#
这里可以看到第一个ping成功了(这里的参数"-c 1"是告诉ping只发送一个包)。
然后为INPUT链添加一条规则,将来自127.0.0.1(-s 127.0.0.1)的ICMP协议(-p icmp)包送至目标DROP(-j DROP)。
接着用第二个ping来测试规则。程序将等待一段时间,超时后放弃等待响应。
删除规则有两种方法。对于上例中的唯一一条规则,可以这样删除:
第一种方法:指定位置来删除:
# iptables -D INPUT 1
#
这样就把第一条规则从INPUT链中删除。
第二种方法与上面的-A命令形式相同,但用-D来代替-A。如果链中又非常复杂的规则,又不想逐行数出需要删除的规则,可以用这种方法。
# iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP
#
在命令行中,其语法要求-D必须和-A(或-I、或-R)命令一致。如果在同一链中有多条相同的这样的规则,则只有第一条符合条件的规则被删除。
过滤
上面已经介绍过用"-p"来指定协议以及用"-s"来指定源地址,另外还有一些其它选项用于指定一个包的特征。下面将详细介绍。
指定源和目的IP地址
可以用四种方法来指定源("-s"或"--source"或"--src")和目的("-d"或"--destination"或"--dst")IP地址。最常用的方法是使用完整的名称,如"localhost"或"www.linuxhq"。第二种方法是指定其IP地址,如"127.0.0.1"。
第三种和第四种方法允许指定一组IP地址,例如"199.95.207.0/24"或"199.95.207.0/255.255.255.0",这两种设置都指定了所有从199.95.207.0到199.95.207.255之间的IP地址;而在数字后面的"/"符号用
于告诉系统哪部分IP有效。"/32"或"255.255.255.255"为缺省值(即所有IP值都符合条件)。全部用"/0"来指定IP 也是可行的,例如:
# iptables -A INPUT -s 0/0 -j DROP
#
不过这种方式非常少用,因为以上命令的效果和不指定"-s"的效果是一样的。
反向指定
许多标志,包括"-s"(或"--source")和"-d"(或"--destination"),可以在它们前面加上一个"!"符号来指定所有非(NOT)指定值的地址。例如,"-s !localhost"表示所有飞来资本机的包。
指定协议linux内核文件放在哪
协议可以用"-p"(或"--protocol")标志来指定。协议可以为一个号码(如果用户知道相应的IP协议数值的话),或是一个协议字符串,如"TCP"、"UDP"或"ICMP"等。协议字符串与大小写无关。
协议前也可以加上"!"符号,使之取饭。例如,"-p !TCP"指定所有非TCP的包。
指定接口
用"-I"(或"--in-interface")和"-O"(或"--out-interface")选项来指定接口。接口就是包进入("-I")或送出("-O")的物理设备。可以用ifconfig命令列出哪些接口是开启("up")的。
穿过INPUT链的包是不会通过输出接口的,所以,它不与任何在链中使用"-O"选项的规则匹配。同样,穿过OUTPUT链的包也不会通过输入接口,所以它不与任何在链中使用"-I"选项的规则匹配。
只有穿越FORWARD链的包才会同时通过输入和输出接口。
指定一个不存在的接口是完全合法的,在接口未开启("up")之前,这条规则是不会被比较的。这对于PPP(通常会是ppp0)或类似的连接是非常有用的。
如果接口是以一个"+"结尾的话,就代表所有以此字符串开头的接口(不管它们目前是否已开启)。例如,要制定一条规则来匹配所有的PPP接口的话,可以用-i PPP+选项。
接口名称前面可以用一个"!"符号来指定一个与指定接口不匹配的包。
指定包片段(fragements)
有时候,一个包可能会因为太大而不能一次传送,这时,包会被分割成片段,并以多个包来传送。而在接收端则对这些片段进行重组以还原整个包。
分割成片段传送的问题是,第一个起始片段含有整个包头项(IP+TCP、UDP和ICMP)可供检查,但后续的包只含包头的小部分(不带额外协议项的IP)。这样,就无法检查后续片段的协议表头(例如由TCP、UDP和ICMP扩展而成)。
如果要跟踪或网络地址翻译(NA T),那么所有的片段都会再传给包过滤之前汇合在一起,所以无需担心片段问题。
然而,要弄清楚过滤规则是如何处理片段的非常重要。对任一规则,如果需要察看的信息不能得到时,将作为不匹配处理。也就是说,第一个片段包的处理和其它的包一样,但第二个及以后的片段就不是这样了。那么,一条-p TCP -sport www(指定源端口为"www")的规则,将永远不和片段匹配(除了第一个片段以外)。反之,规则如-p TCP -sport !www亦然。
不过,用户可以用"-f"(或"--fragment")标志专门为第二及其后的片段制定一条规则。同样,也可以在"-f"前面加上一个"!"来指定一条规则不适用于第二及其后的片段。
通常,让第二及其后的片段通过被视为是安全的,因为如果过滤会影响第一个片段的话,那么也就可以避免在目标主机进行重组。但是,一些已知的bug显示,丢送片段包可以轻易地让主机停机。
需要注意的是,当进行这样的监测时,不完整的包(太短的TCP、UDP和ICMP包会让防火墙程序读不到端口或ICMP码和类型)会被丢弃。因此,TCP片段都由第8个位置开始。
例如,以下的规则将丢弃任何送给192.168.1.1的片段:
# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP
#
扩展iptables:新的匹配(matches)
iptables是可扩展的,也就是说,内核和iptables工具可以进行扩展以提供新的功能。
某些扩展是标准的,但有些则可以说是派生出来的。可以制作一些扩展,发布给其它的用户。
内核的扩展通常置于内核模块目录内,如/lib/modules/2.3.15/net。如果内核是用CONFIG_KMOD设定来编译的话,它们是在需要时载入的,所以无需手工插入它们。
然而,iptables程序的扩展则通常是置于/usr/local/lib/iptables/中的共享函数库,也有些发布版将它们置于/lib/iptables或/usr/lib/iptables中。
扩展有两种类型:新目标(target)和新匹配(match)。下面先介绍新目标。有些协议会自动提供新的测试(tests):目前由TCP、UDP和ICMP。
在命令后面使用"-p"选项载入扩展,然后就可以指定一个新测试了。当扩展选项允许的时候,使用"-m"来再入扩展,则可以显式指定一个新测试。
如果需要某个扩展的帮助资料,可以使用选项后接"-h"或"--help"将之载入("-p"、"-j"或"-m"),例如:# iptables -p tcp -help
#
TCP扩展
如果指定了"-p tcp",TCP的扩展会自动载入。它提供如下选项(并不匹配片段)。
--tcp-flags
后接一个"!"选项,有两个标志的字符串允许用户对指定的TCP标志进行过滤。第一个字符串是掩码:一个用户希望检查的标志列表。第二个字符串指定需要设定的内容。例如:
# iptables -A INPUT -protocol tcp --tcp-flags ALL SYN, ACK -
其中ALL表示所有的标志都要检查(ALL指"SYN,ACK,FIN,RST,URG,PSH"),但只有SYN 和ACK被设定。标志参数NONE代表无标志。
--syn
为"--tcp-flags SYN,RST,ACK SYN"的简写,其前面可以备选一个"!"符号。
--source-port
其后可以备选"!",然后是一个TCP端口或一个端口范围。端口可以为/etc/services所列端口名称或一个数字。如果是端口范围的话,可以是一对用":"符号分隔的端口名字,或一个端口后面带":"(指大于和等于指定端口),或一个端口前面带":"(指小于和等于指定端口)。
--sport
等同于"--source-port"。
--destination-port
-
-dport
与上同,只是他们使用来指定目的地而非源端口来比较。
--tcp-option
其后可以备选"!",然后为一个数字,用来比较一个TCP选项等于该数字的包。假如需要检查TCP选项,那些TCP包头不完整的包就会被自动丢弃。
一个TCP标志的说明
有时,允许单项而非双向的TCP连接会很方便。例如,用户可能想允许连接到外部WWW服务器,但却不希望来自该服务器的连接。
屏蔽来自该服务器的TCP包不是好办法,但不幸的是,TCP连接本来就要求包是双向传输的。
解决的方法是把那些要求连接的包过滤掉。这些包被称为SYN包(技术上讲,它们是带SYN设定的包,而FIN和ACK标记则未设定,简称为SYN包)。这样就可以防止那些外来的连接尝试了。
"--SYN"标记仅对被指定为TCP协议的规则起作用。例如,指定来自192.168.1.1的TCP链接请求:
-
p TCP -s 192.168.1.1 -syn
该标志也可以后接一个"!"来方向指定,指任一个非该类初始连接的包。
UDP扩展
如果"-p udp"被指定的话,这些扩展就会被自动载入。它提供了"--source-port"、"--sport"、"--destination-port"以及"--dport"这些选项,用法同上述的TCP设定。
ICMP扩展
如果"-p icmp"被指定的话,这个扩展就会被自动载入。它只提供一个新的选项:
--icmp-type
其后可以备选"!"选项,然后是一个icmp名称类型(如"host-unreachable")或者一个数字类型(如"3"),或者一对用"/"分隔的数字类型和编码(如"3/3")。使用"-p icmp --help"就可以得到可用的icmp类型名称清单。
其它匹配的扩展
在netfilter套件中的其它扩展则是展示性的扩展内容,可以用"-m"选项来调用。
mac
这一模块必须要显式地用"-m mac"或"--match mac"来指定。它用于匹配输入包的源Ethernet(MAC)地址,因而只对那些通过PREROUTING和INPUT链的包起作用。
--mac-source
其后可以备选"!",然后是一个用冒号分隔的十六进制Ethernet地址,如"--mac-source 00:60:08:91:CC:B7"。
limit
这个模块必须要显式地用"-m limit"或"--match limit"来指定。它用来限制一个匹配等级,例如抑制记录信息等。它只能比较一个每秒辞书的数值(缺省是每小时3个比较,允许5个突发(burst))。它有两个参数选项:
--limit
后接一个数值用于指定可允许的每秒最大平均比较数值。该数值可以用"/second"、"/minute"、"/hour"、"/day"或其中部分("5/second"和"5/s"是一样的)来显式指定设置单位。
--limit-burst
后接一个数值,指定引起上述限制之前的最大突发次数。
这个匹配常用于LOG目标,以进行比率限制(rate-limited)的记录。为了更好地了解它是如何工作的,先看一看下面的规则,这条规则是以缺省限制来记录包的:
# iptables -A FORWARD -m limit -j LOG

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。