首页  |  IT相关文档  |  工具软件  |  网站建设  |  程式开发  |  图形设计  |  操作系统  |  服务器类  |  数据库类  |  网络安全  |  网络技术  |  计算机应用  |  站长之家  |  新华问问  |  图书城
 

热点文章

IT动态

·联想接手石药 柳传志承诺MBO
·eBay将于今夏重返中国网络拍卖市场
·iPhone将成为黑客攻击目标
·门户网站的重要传播手段
·杨致远出山能否挽救雅虎
·陈一舟解释空调停用事件 闭口不提
·Adobe发布视频演示软件Visual Comm
·IE8年底开始Beta 微软或将考虑对Wi
·微软与VMWare合作 虚拟产品可互相
·德国加强反恐 Gmail德国服务将关闭
·PCWorld公布博客站排行Top 100
·比尔·盖茨:10年可还清美国国债

GG搜索更多相关
 
当前位置:主页>操作系统>Linux教程>

Linux2.4内核下新型包过滤结构的使用

来源: 作者: 发布时间:2007-05-13

  一、包如何穿过(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.com"。第二种方法是指定其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"表示所有飞来资本机的包。
  
  指定协议
  协议可以用"-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扩展而成)。
  如果要跟踪或地址翻译(NAT),那么所有的片段都会再传给包过滤之前汇合在一起,所以无需担心片段问题。
  然而,要弄清楚过滤规则是如何处理片段的非常重要。对任一规则,如果需要察看的信息不能得到时,将作为不匹配处理。也就是说,第一个片段包的处理和其它的包一样,但第二个及以后的片段就不是这样了。那么,一条-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
  当该规则第一次引用时,包就会被记录下来;事实上,由于缺省的突发数为5,最初的5个包就会被记录下来。然后,再隔20分钟此规则才会再记录包,而不论这期间有多少包到达。而且,每20分钟如果没有匹配的包通过,则会回复一个突发数值;假如100分钟内再无这样的包触发该规则,那么突发次数就会完全恢复,回到初始时的状态。
  注:用户目前不能以大于59小时的复原时间来建立一个规则,所以,假如用户设定平均率为每天一次,则突发率一定要小于3。
  用户也可以用这个模块来避免高速率提高服务相应的切断服务的攻击(DoS)。
  Syn-flood protection:
  # iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j A
  
  Furtive port scanner:
  # iptables -A FORWARD -p tcp --syn --tcp-flags SYN,ACK,FIN,RST RST
  
  Ping of death
  # iptables -A FORWARD -p icmp --icmp-type echo-request -m li
  
  该模块的工作原理类似于"截流阀",参看下图:
      rate (pkt/s)
           ^    .---.
           |    / DoS          |    /      Edge of DoS -|.....:..........\.......................
     = (limit * |  /:        limit-burst) |  / :       \     .-.
           | / :       \    /           | /  :       \   /     End of DoS _|/....:...............:.../.......\..../.
     = limit  |   :        :`-     `--
    -----------+-----+--------------+------------> time (s)
      LOGIC => Match | Didnt Match | Match
  LOGIC => Match | Didnt Match | Match
  比如,用户以五个包突发来匹配每秒一个包,但包从每秒四个开始输入,延续三秒,然后等三秒再重新开始。
  <--Flood 1-->
  
    Total -              Line __--     YNNN
    Packets|            Rate __--      YNNN
        |          mum __--      YNNN
      10 |       Maxi ___--        Y
        |       ___--          Y
        |    ___--            Y
        | ___--   YNNN
        |-   YNNN
       5 |   Y
        |  Y                     Key: Y->Matched Rule
        | Y                     N->Didnt Match Rule
        | Y
        |Y
       0 +---------------------------------------------------------> Time(s)
        0  1  2  3  4  5  6  7  8  9  10  11  12
  
    0123456789101112
  用户会发现前五个包被允许超过每秒一个包,然后就引起限制了,如果有一个间歇,其它的突发也将被允许,但就不能通过规则设定的最高比率(在该触发使用后为每秒一个包)。
  
  Owner
  该模块为本机产生的包匹配不同特征的包创建者(creator)。它仅对OUTPUT链有效,而且,甚至某些可能没有拥有者的包(如ICMP ping响应)将被视为不匹配。
  --uid-owner userid
  如果包由一个进程以有效(数字式)user id创建,则为匹配。
  --uid-owner groupid
  如果包由一个进程以有效(数字式)group id创建,则为匹配。
  --pid-owner processid
  如果包由一个进程以process id创建,则为匹配。
  --sid-owner sessionid
  如果包由一个进程以session id创建,则为匹配。
  
  Unclean
  该试验性模块必须以"-m unclean"或"--match unclean"来显式指定。它会对保进行不同的随机判断监测。该模块尚未被核查过,所以不应该用于安全设备上。它没有提供选项设定。
  
  The State Match
  "state"扩展提供了非常有用的匹配判断标准,来进行"ip_conntrack"模块的连接跟踪分析。鼓励用户这样使用。
  指定"-m state"则允许另一个额外的"--state"选项,可以为一个逗号分隔的匹配陈述列表("!"标志用于反向指定)。这些陈述可以是:
  NEW
  一个建立新连接的包。
  ESTABLISHED
  一个属于现有连接(如已响应包)的包。
  RELATED
  一个与现有连接相关,但并不限于其中部分的包,如ICMP错误消息或建立FTP数据连接的包。
  INVALID
  一个因为某种原因不能被鉴别的包:这包括内存不足或不能响应任何已知连接的ICMP错误消息。通常这样的包都会被丢弃。
  
  目标(Target)
  上面已经介绍了对包可以进行的检查,还应该对一个匹配指定测试的包如何处理进行设定,这就是下面要讲的规则的目标。
  内建目标有两种:DROP和ACCEPT。如果一个包与一条规则相匹配,同时目标是二者之一,讲不继续进行后面的规则匹配,对其依据设定的目标进行处理。
  除了内建目标外,还有两种类型的目标:扩展和用户自定义键。
  
  用户自定义键
  iptables继承了ipchains一项很有用的功能,就是允许用户创建新链以扩展三个内建链(INPUT、OUTPUT和FORWARD)。通常,用户自定义链用小写以示区别。如何创建新的用户自定义链将在后文"整个链的操作"中介绍。
  当一个包与目标为用户自定义链的规则匹配时,包就会穿越用户自定义链中的规则。如果该链未能确定该包的处理,则一旦结束穿越该链,就会接着当前链中的下一个规则继续穿越下去。
  假设由两条链:INPUT(内建链)和test(用户自定义链),如图所示:
  `INPUT  `test
  -------------------------- --------------------------
  | Rule1: -p ICMP -j DROP | | Rule1: -s 192.168.1.1 |
  |------------------------| |------------------------|
  | Rule2: -p TCP -j test | | Rule2: -d 192.168.1.1 |
  |------------------------| --------------------------
  | Rule3: -p UDP -j DROP |
  --------------------------
  假设一个来自192.168.1.1的TCP包要到1.2.3.4去。它进入INPUT链,并受到Rule1的测试,但不匹配。但它匹配Rule2,且它的目标是test,所以下一个要检验的规则将从test开始。它与test中的Rule1匹配,但没有指定目标,所以再见眼下一条规则,也就是Rule2。但是并不匹配,这时到达该链的末端。然后回到INPUT链中,也就是刚才检验Rule2的位置,接着检查Rule3,依然不匹配。
  该包的路径如下图所示:
                v -----------------------
    `INPUT         |  / `test      v
    ------------------------|--/  ----------------|----
    | Rule1         | /|  | Rule1     |  |
    |-----------------------|/-|  |---------------|---|
    | Rule2         / |  | Rule2     |  |
    |--------------------------|  |---------------v----
    | Rule3         /--+___________________/
    -----------------------|---
                v
    v
  用户自定义链也可以再跳转到另一个用户自定义链(但不要形成回路:如果发现包处于回路就会被丢弃)。
  
  Iptables的扩展:新目标
  另一种类型的目标是扩展。目标的扩展由内核模块和可选的iptables扩展组成,以提供新的命令行选项。在缺省的netfilter发布版本中有几个扩展:
  LOG
  该模块提供内核记录匹配的包。塔提供的额外选项有:
  --log-level
  后接一个层次(level)号码或名称。合法的名称有(大小写相关):"debug"、"info"、"notice"、"warning"、"err"、"crit"、"alert"以及"emerg",对应的号码为7到0。各层次号码的含义请参看syslog.conf的man手册。
  --log-prefix
  后接一个最长为30个的串。该信息由记录信息开始时送出。
  该模块常用于一个限制目标后,所以注意不要使记录溢出。
  
  REJECT
  该模块除了向发送方发送一个"port unreachable"这样的ICMP错误消息外,和"DROP"是一样的。注意,在下列情况中,ICMP错误信息将不会送出(参看RFC 1122):
  ·被过滤的包就是一个ICMP错误消息,或是其它不明的ICMP类型;
  ·被过滤的包为一个无头(non-head)片段;
  ·目前已经发送太多到达该目的地的ICMP错误消息了。
  REJECT还提供"--reject-with"选项来更改其响应包(请参看说明文档)。
  
  特殊的内建目标
  有两种特殊的内建目标:RETURN和QUEUE。
  RETURN与切换到某一链的末尾的效果相同。对内建链的规则而言,则启用该链的策略;对用户自定义规则而言,则回到前一个链中继续穿越,下一条规则为跳转到当前链的那条规则的下一条规则。
  QUEUE也是一种特殊的目标,可以为用户空间(userspace)处理将包排队。要运行它,必须有下列两个功能组件:
  ·一个是"queue handler"处理用户空间与内核之间传送包的实质机制;
  ·另一个为用户空间的应用程序,用于接收(或者说控制)以及对决定对包如何处理。
  IPv4 iptables的标准中,queue handler为ip_queue模块,目前以实验性质与内核一起发布。
  下面是一个如何用iptables为用户空间处理进行包排队的简单例子:
  # modprobe iptable_filter
  # modprobe ip_queue
  # iptables -A OUTPUT -p icmp -j QUEUE
  用此规则,本机产生的对外ICMP包(如用ping创建)就会被送到ip_queue模块,然后尝试将包传给用户空间应用程序。如果没有用户空间应用程序在等待的话,该包就会被丢弃。
  要编写一个用户空间应用程序,需要使用libipq API。它也是和iptables一起发布的。程序例子可以在CVS中的测试套具(如redirect.c)中找到。
  ip_queue的状态可以用如下方法来检查:
  /proc/net/ip_queue
  队列的最大长度(如传送给用户空间且无需送回裁决包的数量)可以通过这样的方式来控制:
  /proc/sys/net/ipv4/ip_queue_maxlen
  最大队列长度缺省值为1024。一旦达到此限制,新的包就会被丢弃,直到队列长度跌回到低于限制值为止。好的协议,如TCP,会将丢弃的包作为拥塞,当队列满时进行阻挡。但是,在某一给定的情况下,如果缺省值太小,需要进行一些实验来决定理想的最大队列长度。
  
  整个链的操作
  iptables的一项非常有用的功能是,它能够将相关的规则组合到链中。用户可以为链任意命名,但建议使用小写字母以避免与内建链及目标相混淆。链名的最大长度为31个。
  
  创建新链
  假设新链名为test,这里使用"-N"或"--new-chain"选项:
  # iptables -N test
  #
  然后可以按上文所讲的方法为其加入一些规则。
  
  删除链
  删除链也非常简单,用"-X"或"--delete-chain"即可。
  # iptables -X test
  #
  要删除一条链有一些限制:它必须是空的(参看下文中的"清空链"),且它不能作为任何规则的目标。三条内建链是不能被删除的。
  如果删除链操作不指定某一条链,那么如果可能的话,全部用户自定义链都会被删除。
  
  清空链
  有一个简单的方法可以清空一条链中的所有规则,就是使用"-F"(或"--flush")命令。
  # iptables -F forward
  #
  如果不指定清空哪一条链,那么全部链都会被清空。
  
  列表显示链
  用户可以使用"-L"(或"--list")命令列表显示链中的所有规则。
  每一条用户自定义链中所列出的"refcnt"是指有多少规则是以该链为目标的。在该链被删除之前,这个数字必须为零(并且链为空)。
  如果没有提供链名称,所有链都会被列表显示,也包括空链。
  除了"-L"选项,还有三个选项可以使用。第一个是"-n"(numeric)选项,它很有用,因为它可以避免iptables尝试去查找IP地址,如果用户使用DNS,而DNS没有正确设定,或者DNS请求已经被过滤掉,这可能会造成严重的延迟。同时,它使TCP与UDP端口显示为数字而非名称。
  第二个是"-v"选项,它会显示出用户全部规则的细节,比如包的字节流量统计、TOS比较以及接口等。不使用"-v"选项时这些数值将被略掉。
  其中,包的字节流量统计可以分别使用"K"、"M"或"G"为单位来显示,分别代表1000、1,000,000以及1,000,000,000。使用"-x"(expand numbers)标志可以显示出完整的数字而无论它有多长。
  
  重置(清零)流量计数器
  可以用"-Z"(或"--zero")选项来重置流量计数器。
  例如:
  # iptables -L FORWARD
  # iptables -Z FORWARD
  #
  唯一的麻烦是,在进行重置操作之前,用户可能需要立即记住流量统计值。在前面的例子中,用户运行"-L"然后是"-Z"命令,在两个命令运行中间可能有一些包通过。因此,用户可以同时使用"-L"和"-Z",在读取计数器的同时重置计数器。
  
  设定策略
  在前面讨论包如何通过一个链的时候,已经讲述过当包到达内建链末端时的处理。这时,就由该链的策略来决定如何处理该包。只有内建链(INPUT、OUTPUT和FORWARD)才有策略设定,因为如果一个包跳转到一个用户自定义链的时候,则会回到上一个链中继续穿越。
  策略可以设置为ACCEPT或DROP。例如:
  # iptables -P FORWARD DROP
  
  三、使用ipchains和ipfwadm
  在netfilter发布版中,有ipchains.o和ipfwadm.o两个模块。用户只要将其中一个插入内核(注:它们和iptables.o、ip_conntrack.o以及ip_nat.o是不兼容的!)。然后用户就可以如往常一样地使用ipchains或ipfwadm了。
  
  四、整合地址翻译(NAT)和包过滤(Packet Filtering)
  要进行地址翻译(Network Address Translation,请参阅NAT HOWTO)以及包过滤是很常见的事情,好消息是,它们整合的非常好。
  在设计包过滤时,完全可以不用考虑NAT的工作。在包过滤中看到的源和目的地都是真正的源和目的地。例如,如果进行的是DNAT来通过10.1.1.1的8080端口发送连接到1.2.3.4的80端口,包过滤器将看到包指向10.1.1.1的8080端口(真正的目的地),而不是1.2.3.4的80端口。类似地,用户也可以忽略包伪装:包将看起来是来自真正的内部IP地址(即10.1.1.1),应答也看起来是会送该地址。
  用户可以使用"state"匹配扩展(match extension)而无需要包过滤器做额外的工作,因为无论如何,NAT都要求连接跟踪。为了增强在NAT HOWTO中那个简单的包伪装的例子,来禁止来自ppp0接口的任何新的连接,可以这样做:
  # 伪装ppp0输出包
  iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
  
  # 禁止新的和非法的来自ppp0的输入包和转发包
  iptables -A INPUT -i ppp0 -m state --state NEW,INVALID -j DROP
  iptables -A FORWARD -i ppp0 -m state --state NEW,INVALID -j DROP
  
  # 打开IP转发
  echo 1 > /proc/sys/net/ipv4/ip_forward
  
  五、ptables和ipchains的区别
  ·首先,内建链名称从小写换成大写,因为INPUT和OUTPUT链目前只能获得目的地为本机以及从本机产生的包。它们分别用来察看所有的输入和输出包。
  ·现在"-i"标志代表输入接口,并且只工作于INPUT和FORWARD链中。FORWARD和OUTPUT链中使用"-i"标志的规则需要换成"-o"。
  ·TCP和UDP端口现在需要用--source-port或--sport(或--destination-port/--dport)选项拼写出来并且必须置于"-p tcp"或"-p udp"选项之后,因为它们分别是载入TCP和UDP扩展的。
  ·以前TCP的"-y"标志现在改为"--syn",并且必须置于"-p tcp"之后。
  ·原来的DENY目标最后改为了DROP。
  ·可以在列表显示单个链的同时将其清空。
  ·可以在清空内建链的同时将策略计数器清零。
  ·列表显示链时可显示计数器的当前瞬时值。
  ·REJECT和LOG现在变成了扩展目标,即意味着它们成为独立的内核模块。
  ·链名可以长达31个。
  ·MASQ现在改为MASQUERADE,并且使用不同的语法。REDIRECT保留原名称,但也改变了所使用的语法。关于如何配置它们的详细资料请参看NAT-HOWTO。
  ·-o选项不再用于将包定向到用户空间设备了(参看上文中的"-i")。现在通过QUEUE目标来将包发送到用户空间。
  
  

 

评论 | 收藏 | | 打印 | 关闭
相关链接
     
 

Copyright 2006-2007 xhit.cn All Rights Reserved
有什么建议或意见请发信到admin@xhit.cn 皖ICP备07007336