Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2780807
  • 博文数量: 77
  • 博客积分: 10204
  • 博客等级: 上将
  • 技术积分: 5035
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-05 22:13
文章分类
文章存档

2013年(1)

2010年(1)

2009年(17)

2008年(58)

我的朋友

分类: BSD

2008-10-01 09:29:56

IPFW中文man

  ipfw是FreeBSD下的一个用户界面,它用来控制ipfw防火墙和流量整形。


  ipfw的配置,也叫做规则集,它是由一系列的规则组成的,这些规则的编号是从1到65535。通过ipfw的数据包可以来自协议栈的许多各个的地方(这主要依赖于数据包的来源和目的,某些数据包很可多次经过防火墙)。数据包在通过防火墙的时候,要和防火墙规则集逐条对比。如果发现匹配的规则,则执行相应规则的动作。

  在特定的规则动作和系统设置下,数据包在匹配完一个规则后,可能在某些规则之后重新进入防火墙。

  一个ipfw规则集总是包含一个默认的规则(编号为65535),这个默认规则匹配所有的数据包,不能修改或删除。根据内核配置的不同,这个默认规则或者是拒绝所以数据包通过,或者是允许所有数据包通过。

  如果规则集中存在一个或多个包含有keep-state(状态保持)或limit(限制)的规则,那么ipfw就表现为状态保持。例如:当这种规则匹配了一个数据包时,ipfw将创建一个动态规则,让后来的,同这个数据包的地址和端口参数严格一致的数据包,与这个动态规则相匹配。

  这些动态规则,都有一个有限的生存期。生存期在第一次遇到check-state、keep-state或者是limit规则时被检查。这些动态规则的典型应用,是用来保证合法的数据包在通过时开启防火墙。查看下面的“状态防火墙”和“示例”章节,获取更多关于状态保持的信息。

  包括动态规则在内的所有规则,都有几个相关的计数器:一个包计数器,一个字节计数器,一个记录计数器和一个用来提示最后匹配时间的时间戳。这些计数器都可以被ipfw命令显示和清零。

  可以用add命令来添加规则;可以用delete命令来删除单个或一组规则;可以用flush命令来删除所有的规则(set 31除外);可以用show和list命令来显示包括计数器在内的信息。最后,计数器可以被zero和resetlog命令清零。

  并且,每个规则隶属于32个不同的规则集中的一个。有一些ipfw的命令可以独立地操作这些规则集,例如:启动、禁止、交换规则集;把一个规则集中的所有规则移动到另一个规则集;删除一个规则集中的所有规则。这对于安装临时配置,或者是测试配置是非常有用的。查看“规则的规则集”一节,获取更多关于set的信息。      

  以下是ipfw命令可以利用的选项:

-a  使用 list 时,列出数据包的计数器,show命令包含这个选项。

-b  只显示动作和注释,不显示规则体。包含-c选项。

-c  进入或显示规则时,用紧凑格式输出。例如:在没有任何附加意义的情况下,不显示“ip from any to any”字符串。

-d  在list时,在显示静态规则的同时,显示动态规则。

-e  在list时,如果指定了-d选项,则显示过期的动态规则。

-f  对于有些会导致问题的命令,不要提出确认的询问。例如:flush命令。哪果一个进程没有相关的tty,这个是默认被包含的选项。(译注:没看懂这句话的意思,好像是如果不是在tty中输入的命令,比如在scripts中,默认是有-f的。)

-n  只检查命令的语法,不真正执行命令。

-N  尝试在输出中,解析地址和服务名。

-q   当新增 (add)、归零(zero)、重置日志(resetlog)或清除(flush) 时,不要显示任何回应信息(就像使用-f选项一样)。这对于在脚本里利用ipfw命令来调整防火墙规则(例如执行“sh /etc/rc.firewall”脚本)、或者是处理与一个远程登录相关的有多条ipfw命令的,是非常有用的。同时,它防止无意间,在规则中加入或删除一个列表而导致的错误。(译注:没看懂,好像下面是一个例子。)在正常的模式,默认内核配置下,一个flush命令会输出一个信息。因为所有的规则都被清除掉,这个消息又不能传送到登录的进程中,脚本后面的规则将无法执行,所以将导致远程连接中断。这时,只好回到计算机前去工作了。

-S   当列出一个规则的时候,显示每条规则的规则集号。如果没有指定这个标识,则被禁止的规则不再显示。

-s [field]
           当显示pipe时,按照四个计数器之一排序显示。(对于所有的数据包、当前数据包或者是字节数)

-t   当列出时,显示最后匹配的时间戳。(显示用ctime()转化后的时间)

-T   当列出时,显示最后匹配的时间戳。(从新纪元到现在的秒数)。这个格式更容易被脚本处理。

  为了使配置更容易,规则可以写到一个文件里供ipfw处理,语法规则参照大纲栏最后一行(译注:指本文最前面的语法部分最后一行,即:“ipfw [-cfnNqS] [-p preproc [preproc-flags]] pathname”)。注意必须是绝对路径。这个文件会被逐行读取并且将作为ipfw工具的参数处理。      

  作为选择,你还可以使用-p preproc参数来使用预处理程序,其中路径是用管道来传入的。可以使用的预处理程序包括cpp和m4。如果preproc不是以"/"开头,那么将搜索PATH里的路径。在使用它的时候,要谨慎,因为在很多时候,ipfw启动时,系统文件可能没有挂接(比如:文件系统是通过NFS挂接的)。一旦使用了 -p参数,所有其它的参数,都被传送到预处理程序去等待处理。


  ipfw的pipe和queue命令用来配置流量整形,你可以下面的“TRAFFIC SHAPER (DUMMYNET) CONFIGURATION”节看到看到相关内容。

  如果系统的world和内核不能保持一致,ipfw的ABI将失效,以防你加入任何规则。这样能保证你的顺利地完成启动过程。你可以利用ipfw临时禁止的机会登录你的网络,来修复你的问题。


PACKET FLOW(数据包流程)


  一个数据包在几个内核变量的控制下,在协议栈的多个地方被防火墙检查。这些地方和变量如下图所示,要在头脑中保持下图,它对于规划一下正确的规则集是非常重要的。


                  ^    到上层             V
                  |                          |
                  +----------->-----------+
                  ^                          V
            [ip(6)_input]            [ip(6)_output]     net.inet(6).ip(6).fw.enable=1
                  |                          |
                  ^                          V
            [ether_demux]         [ether_output_frame]  net.link.ether.ipfw=1
                  |                          |
                  +-->--[bdg_forward]-->--+               net.link.bridge.ipfw=1
                  ^                          V
                  |         到设备           |



  如图所示,根据数据包的源和目的,以及系统配置的不同,同一个数据包穿过防火墙的次数在0和4之间变化。

  需要注意的是,在包通过不同栈的时候,头会被加上或剥离,可能会导致这些包被检查不到。例如:当ipfw被ether_demux()调用的时候,进入的包将包括MAC头;而当ipfw被ip_input()或者ip6_input()调用的时候,同一个数据包的MAC头将被剥离。

  还需要注意的是:不论检查发生在什么地方,也不论数据包源自哪里,每个数据包也整个规则进行对照。(译注:是整个规则集吗?有时候只对照一部分的时候就中止检查)。如果一个规则包含的一些匹配模型或动作不符合某处的要求(比如:在ip_input或ip6_input处匹配MAC头),那么匹配模型将不会被匹配。然而,带有not前缀操作符的匹配模型,总是可以和这些数据包相匹配。所以,如果有必要,在有很多地方可以选择的时候,有能力的程序员可以为写出的规则集选择一个合适的位置。skipto规则在这儿是非常有用的。例如:

           # packets from ether_demux or bdg_forward
           ipfw add 10 skipto 1000 all from any to any layer2 in
           # packets from ip_input
           ipfw add 10 skipto 2000 all from any to any not layer2 in
           # packets from ip_output
           ipfw add 10 skipto 3000 all from any to any not layer2 out
           # packets from ether_output_frame
           ipfw add 10 skipto 4000 all from any to any layer2 out

        (对,在这儿,没有办法区别ether_demux和bdg_forward)


SYNTAX(语法规则)

  通常,每个关键字或者参数都是作为独立的命令行参数来提供的,前后都不能有空格。关键字是区分大小写的,而参数按照它们本身的含义,可以是,也可以不是区分大小写的。(例如,udi要区分大小写,而hostname没有必要区分大小写)

  在ipfw2中,为了提高可读性,可以在逗号后面加上一个空格。当然,你也可以把整个命令(包括参数)当作一个参数来处理(译注:就是加上双引号,作为一个字符串放到某个命令中)。例如,以下几种格式效果相同:

           ipfw -q add deny src-ip 10.0.0.0/24,127.0.0.1/8
           ipfw -q add deny src-ip 10.0.0.0/24, 127.0.0.1/8  (译注:127前面有个空格)


           
RULE FORMAT(规则格式)

  ipfw的规则格式如下:

           [rule_number] [set set_number] [prob match_probability] action
           [log [logamount number]] [altq queue] [{tag | untag} number] body

  规则的 body 部分用来设定包过滤的信息,具体细节如下:

        Layer-2 header fields                      第二层头段,什么时候可用      

        IPv4 and IPv6 Protocol                      TCP, UDP, ICMP, 协议等

        Source and dest. addresses and ports        源和目的。地址和端口

        Direction                                   数据包的流向,见“流量整形”一节

        Transmit and receive interface              传输和接收界面,用名字或地址表示
        
        Misc. IP header fields                     组合IP头字段,包括版本、服务类型、报文长度、唯一标识、分段标志、生存期

        IP options                          IP选项字段

        IPv6 Extension headers               IPv6扩展头,包括分片报头、中继选项报头、路由报头、路路由选择报头、IP层安全服务选项、Source routing rthdr0, Mobile IPv6 rthdr2(译注:最后两项不知道怎么翻译)

        IPv6 Flow-ID             IPv6的流量标识
        
        Misc. TCP header fields               组合tcp头字段,有TCP标志(syn,fin,ack,rst等)、序列号、回复号,窗口等。

        TCP options              TCP的选项
        
        ICMP types                              ICMP包
        
        ICMP6 types                             ICMP6包
        
        User/group ID                          本地栈所归属的用户和组
        
        Divert status                          是不是源自一个divert接口(例如:natd(8))

  需要注意,上面的很多信息中,比如源MAC和IP地址、TCP/UDP端口等,是比较容易伪造的,所以只对这些信息进行过滤不能保证达到预期的效果。


  rule_number
  每个规则都有规则号,规则号从1-65535。65535是保留的默认规则。ipfw将按规则号的顺序依次检查这些规则。可以有多个规则用同一个规则号,在这种情况下,将按照它们的添加顺序依次检查或列出。如果一个规则没有指定规则号,内核将自动赋于一个规则号,使它成为默认规则前的最后一个规则(即小于65535)。自动添加的规则号有个步进值,在不大于65535的情况下,每次添加规则时,都自动加上这一步进值。它默认是100,对应于net.inet.ip.fw.autoinc_step这个内核变量。

  set set_number

  每个规则都对应于一个规则集编号,规则集编号取值为:0-31。规则集可以单独地被禁止或启用,所以,它对于规则集的原子操作是
至关重要的。它还可以轻松地删除掉一组规则。如果一个规则没有指定规则集编号,它默认的规则集编号就是0。规则集编号31是个特殊的规则集,它不能被禁止,也不能用ipfw的flush命令删除,它是默认规则的规则集。规则集编号31可以用ipfw delete set 31命令删除。(译注:这在远程调试排斥式防火墙时特别有用,防止把自己锁在外面。)


 prob match_probability

  这个语句只用来指定可能性(从0到1之间浮点值)。这在很多随机丢包的应用中,或者(在同dummynet联用的情况下)模拟多路径条件下无序包传递的效果中,是非常有用的。

  注意:在检查时,这个条件比其它所有条件都先被检查,包括会有副作用的keep-state或者check-state。

 log [logamount number]

  当一个包匹配到一个有log关键字的规则时,一条消息会被syslogd记录到一个LOG_SECURITY设备中。记录动作只会在同时满足下面两个条件时才发生:1、内核选项net.inet.ip.fw.verbose等于1(当编译内核时带着IPFIREWALL_VERBOSE参数时,这是默认值);2、所记录的包数量还达不到logamount number所指定的数量。如果没有指定logamuont,则记录的包的上限受内核变量net.inet.ip.fw.verbose_limit的限制。在这两种情况中,logamount取值为零时,则取消记录数量的限制。

  当记录数量达到上限时,可以通过重置记录计数器或包计数器的方式再重新开始记录。详细情况请查看resetlog命令。

    注意:记录的时间是在所有的包检测条件都完成之后,并且在采取相应的动作(接受、拒绝等)之前。

tag number

  当一个包和一个带有tag关键字的规则相匹配时,一个指定的数字标签就被附加到这个包上,数字标签的范围是1-65534。这个标签作为一个内部的记号(它不会从线路上发送出去),以便后来可以区分这些数据包。这有时候非常有用,比如:提供接口之间相互信任和开启一个基于安全的过滤。一个包可以同时有多个标签。标签是“顽固的”,意思就是只要标签被应用到某个数据包上,那么它就一直存在,直到被明确地解除为止。这个标签在内核中一直存在,但是一旦数据包离开内核,标签就会消失。例如:在当把数据包发送到网络或者发送到divert栈时,标签就会消失。

  要检查已经存在的标签,可以用tagged规则选项,要删除存在的标签,用untag关键字。

  注意:既然标签是在内核空间内一直存在的,所以它们就可以被内核的网络子系统(使用mbuf_tags设备)设置或者是取消,而不仅仅依靠ipfw的tag和untag关键字。例如:可以存在一个netgraph(4)节点做流量分析,并且给数据包打上标签,以供后面的防火墙进行检查。

   untag number
  
  当一个数据包匹配一个带有untag关键字的规则时,将在这个数据包所附加的标签中查找untag number所指定的标签号,如果找到,则将其删除。对于数据包上的其它标签号,则原封不动。

     altq queue(译注:交错队列, Alternate Queuing,参见PF文档)

  当一个数据包匹配了一个带有altq关键字的规则时,将被附加上一个指定队列(见altq(4))的ALTQ标识符。注意,ALTQ标签只适用于从ipfw“向外出”的数据包,而不是被防火墙拒绝或者准备到divert界面的数据包。还要注意的是,当处理数据包的时候,如果没有足够内存,那么数据包将不会被打上标签,所以,一个明智的做法,是使你的“默认”ALTQ队列规则记录下这种情况。如果有多个altq规则匹配于同一个数据包,那么只加上第一条规则的ALTQ类别标签。那样做的效果是:在规则集中靠前的altq队列规则能起到流量整形的作用,而靠后的规则只达到过滤的效果。例如:把还有ALTQ标签的、check-state和keep-state规则放到规则集的后部,有提供真正的包过滤的作用。

  在IPFW使用altq的名字来检查队列之前,你必须用pfctl(8)工具来设置队列。一旦重置ALTQ命令,那么包含队列标识符的规则将过期,需要被重新读取才能生效。过期的队列标识符将会产生错误的分类。

  所有的ALTQ系统进程都可以被ipfw的enable altq和disable altq命令启用或关闭。ALTQ流量整形有真实规则动作,永远附加在ALTQ标签之后,和net.inet.ip.fw.one_pass毫无关系。
 
原创:CU lsstarboy
阅读(1510) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~