Chinaunix首页 | 论坛 | 博客
  • 博客访问: 83377
  • 博文数量: 25
  • 博客积分: 2105
  • 博客等级: 大尉
  • 技术积分: 195
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-24 11:08
文章分类

全部博文(25)

文章存档

2013年(1)

2011年(3)

2010年(8)

2009年(13)

我的朋友
最近访客

分类: BSD

2009-05-12 10:57:05

   一个divert(4)栈都有一个绑定的指定端口,任何发送到该端口上数据包都将被转发。如果没有绑定端口,或者是divert模块没有被挂接,或者内核不支持divert栈,那么数据包将被丢弃。

   地址转换配置可以用以下命令:(译注:nat命令是一个内核级的地址转换工具,是从ipfw6.3开始新加入到FreeBSD中的,由于是用aliase库写的,所以翻译中,就直接译为:别名。)

     nat nat_number config nat-configuration

   在配置中可以用以下参数:

   ip ip_address

定义一个用来做别名的IP地址。
   if nic 

   用指定接口nic上的IP地址作为别名,如果接口上的地址改变,则自动改变相应的IP地址。

   log     在该NAT上启用日志记录功能。
   deny_in

   禁止所有的外部连接进入。

  
same_ports

   做地址转换时,尽量维持转换后的端口和本地的端口号一致。(译注:其实做地址转换的时候,同时也在进行端口的转换。)

  
unreg_only

   如果从本地来的数据包,不是源自私有IP地址空间,则被忽略。(译注:也就是必须来自192.168.0.0- 192.168.255.255,172.16.0.0-172.31.255.255,10.0.0.0-10.255.255.255这三段私有IP 地址。)

   reset  

复位地址转换列表。
   reverse

   使libalias以相反的方式进行地址转换。(译注:在libalias中有介绍,但是没看懂。)

      
proxy_only

   仅仅允许透明代理规则,不再进行包的地址转换。

   如果希望数据包在进行了地址转换后继续进入防火墙,需要设置内核变量net.inet.ip.fw.one_pass=0。如果想了解更多的 关于 alias模块的信息,请对照libalias的man页面。在Examples章节里,可以看到更多的关于nat的用法。

   重定向和反向地址转换(LSNAT)的语法和后面的natd的语法相近。查看“示例”可以看到如何进行重定向和反向地址转换。

   防火墙和相关的模块(dummynet,bridge)都受一系列内核变量的控制。这儿把它们集合在一起,解释一下默认的值(请用sysctl(8)来查看它实际的值)和它们的意义。

   net.inet.ip.dummynet.expire: 1

   将没有流量通过的一些过期的动态管道/队列删除。你可以把它设置为0,那样就只能在管道/队列数达到阙值时被删除掉。

   net.inet.ip.dummynet.hash_size: 64

   动态管道/队列的默认哈希表的大小。在配置管道/队列时,如果指定了no buckets,则使用这个值。

   net.inet.ip.dummynet.max_chain_len: 16

   在哈希链中,管道/队列的最大数目。在net.inet.ip.dummynet.expire=0时,管道/队列的数目超过阙值时,空的管道/队列将过期。这个阙值就是用max_chain_len*hash_size来决定。

   net.inet.ip.dummynet.red_lookup_depth: 256
   net.inet.ip.dummynet.red_avg_pkt_size: 512
   net.inet.ip.dummynet.red_max_pkt_size: 1500
       上面的三个,是在RED算法中,用来计算丢弃率的参数。
   net.inet.ip.fw.autoinc_step: 100
       当自动产生规则编号时的步进值。范围是1-1000。(译注:就是ipfw后不指定规则号时的自动编号)
   net.inet.ip.fw.curr_dyn_buckets: net.inet.ip.fw.dyn_buckets
       当前哈希表中的动态规则条目的数目。(只读)
   net.inet.ip.fw.debug: 1

控制ipfw调试信息的输出。
   net.inet.ip.fw.dyn_buckets: 256

哈希表中动态规则的条目数。必须是2的整数次幂,直到65536。它只有当所有的动态规则都失效时才起作用,所以在修改了它的值以后,建议用flush命令来确保改变了哈希表的大小。
   net.inet.ip.fw.dyn_count: 3
Current number of dynamic rules (read-only).
当前动态规则的数目。(只读)
   net.inet.ip.fw.dyn_keepalive: 1

对于状态保持规则的TCP连接,产生一个keepalive的包。对于生存期还剩下20秒的连接,将每隔5秒钟,就对双方都发送一个keepalive包。(译注:可能理解的不对,last的意思不是很明确)
   net.inet.ip.fw.dyn_max: 8192

动态规则的最大数目。当动态规则的数目达到这个值是,就必须等到老的动态规则过期。
   net.inet.ip.fw.dyn_ack_lifetime: 300
   net.inet.ip.fw.dyn_syn_lifetime: 20
   net.inet.ip.fw.dyn_fin_lifetime: 1
   net.inet.ip.fw.dyn_rst_lifetime: 1
   net.inet.ip.fw.dyn_udp_lifetime: 5
   net.inet.ip.fw.dyn_short_lifetime: 30

   这些变量控制着动态规则的生存期。以秒为单位。对于初始化的SYN交换,要短一些;到了双方都看见SYN的时候,要加长生存期;到交换FIN 和接收 RST时,又要减小。dyn_fin_lifetime和dyn_rst_lifetime这两个等待期必须都小于5秒。这些由防火墙强制执行。(译注: SYN和FIN,RST的意义,请参考TCP的三次握手。)

   net.inet.ip.fw.enable: 1

   启用防火墙。把它的值变为0,将禁用防火墙,既使把它编译到内核里也是一样。

   net.inet6.ip6.fw.enable: 1

对IPv6也同样提供上面的功能。
   net.inet.ip.fw.one_pass: 1
       当设置为1的时候,离开dummynet的管道或着ng_ipfw节点时,不再回到防火墙。否则,数据包将在上面的动作之后,又重新返回到防火墙,继续与下面的规则相匹配。
   net.inet.ip.fw.verbose: 1

    启用日志记录功能。

   net.inet.ip.fw.verbose_limit: 0

记录日志的次数。
   net.inet6.ip6.fw.deny_unknown_exthdrs: 1
       拒绝带有未知的IPv6扩展头的数据包。
   net.link.ether.ipfw: 0

控制第二层(数据链路层)的数据包能不能通过防火墙。默认不通过。
   net.link.bridge.ipfw: 0
       控制从桥上通过的数据包能不能通过IPFW。默认不能通过。

   IPFW有着广泛的应用范围,这儿只能举很少的一些例子。
 ==BASIC PACKET FILTERING(基本的包过滤)==

  下面这个命令将阻止所有的来自wolf.tambov.su主机,到cracker.evil.org的telnet端口的连接。

     ipfw add deny tcp from cracker.evil.org to wolf.tambov.su telnet
   下面这句将阻止123.45.67.0/24这个网络的IP对my.host.org主机的访问。
     ipfw add deny ip from 123.45.67.0/24 to my.host.org
   一个基本的、高效的限制访问的方法(不使用动态规则)如下:
     ipfw add allow tcp from any to any established
ipfw add allow tcp from net1 portlist1 to net2 portlist2 setup
ipfw add allow tcp from net3 portlist3 to net3 portlist3 setup
...
ipfw add deny tcp from any to any

  第一条规则将快速地匹配正常的TCP数据包,但是不能和初始化用的SYN包相匹配。初始化的SYN包只和setup规则相匹配,并且只匹配于选定的源/目的地址对。其它所有的初始化SYN包都被最后一句拒绝。

  如果你掌管一个或多个子网,那么你就可以利用地址集和”or”运算符写出短小精湛的规则,用来有选择地启动服务或禁掉某个机器。如下所示:

  
goodguys="{ 10.1.2.0/24{20,35,66,18} or 10.2.3.0/28{6,3,11} }"
badguys="10.1.2.0/24{8,38,60}"
     ipfw add allow ip from ${goodguys} to any
ipfw add deny ip from ${badguys} to any
... normal policies ...
   verrevpath选项可以用来进行自动的反欺骗,一般的用法,是将带有verrevpath选项的规则放到最前面。
     ipfw add deny ip from any to any not verrevpath in

  这个规则丢弃掉所有的在错误的界面上出现的数据包。例如,一个源自被保护的内部网络地址的数据包,如果尝试通过外部的界面,则被丢弃处理。

  antispoof选项可以用在相似的情况,但是更为严格。可以把它用在规则的最前头。

     ipfw add deny ip from any to any not antispoof in

  如果数据包看起来源自于一个直连的网络,但是却出现在错误的界面,这样的包则被该规则丢弃。例如,一个包的源IP是192.168.0.0/24,配置为fxp0网卡,来自fxp1的源是192.168.0.0/24的包,将被丢弃掉。

   为了保护一个站点免受flood的攻击,包括虚假的TCP包攻击,可以使用动态规则:(译注:以前还真不知道有这个功能。)
     ipfw add check-state
ipfw add deny tcp from any to any established
ipfw add allow tcp from my-net to any setup keep-state
   这个创建的动态规则仅匹配于来自于内部网络的正规的SYN包。动态规则在第一次遇到check-state或keep-state时被检查。一个check-state规则通常放在规则集靠前的地方,来减少扫描规则集的负担。当然,你会有你自己的想法。
   为了限制用户的并发访问数量,可以用以下规则:
     ipfw add allow tcp from my-net/24 to any setup limit src-addr 10
ipfw add allow tcp from any to me setup limit src-addr 4

  第一条规则(假设运行在一个网关上)只允许每个在/24网络上的机器同时打开10个TCP连接。第二个规则一般应用于服务器,可以保证一个客户端的并发连接数不超过4个。

  小心:动态规则很容易导致DOS攻击,因为SYN-flood(syn洪水)可以打开数目众多的动态规则。可以用一系列内核变量的调整来操作防火墙,从而限制这种攻击的效果。(译注:可惜没说到底应该设置哪些内核参数。)

  用list命令查看记录和时间戳信息是一个很好的主意。

     ipfw -at list

  或者可以用一种没有时间戳的短格式:

     ipfw -a list

  这等同于:

     ipfw show

  下面这个规则,将来自192.168.2.0/24这个网络的数据包都转发到5000端口。(译注:怎么突然来了这么一段?本来讲动态规则的,思维的弯拐得太急了吧,有好几次都以为复制时出错了。)

     ipfw divert 5000 ip from 192.168.2.0/24 to any in

  下面的规则将演示ipfw和dummynet的一些应用,或者模拟应用。  

   这条规则以丢包率为5%的机率,随机丢掉进入的包:

ipfw add prob 0.05 deny ip from any to any in
   也一个可以利用dummynet模拟这个效果。
     ipfw add pipe 10 ip from any to any
ipfw pipe 10 config plr 0.05

  我们可以利用pipe来限制带宽,例如,在一个作为路由器的机器上,如果我们想用来限制来自本地192.168.2.0/24的客户端的流量:

     ipfw add pipe 1 ip from 192.168.2.0/24 to any out
ipfw pipe 1 config bw 300Kbit/s queue 50KBytes

  注意我们使用out修改符,所以这个规则不会使用两次。要记住,事实上,ipfw规则在流出和进入两个方向上都进行检查。

  我们也可以用来模拟双向的带宽限制,正确的做法如下:

     ipfw add pipe 1 ip from any to any out
ipfw add pipe 2 ip from any to any in
ipfw pipe 1 config bw 64Kbit/s queue 10Kbytes
ipfw pipe 2 config bw 64Kbit/s queue 10Kbytes

  上面的这个规则是非常有用的。例如,如果你想看到一个在住宅区里,用慢速设备上网的用户在上你心爱的网站,那么你就不要用同一条pipe规则来 限制两个方向的流量,除非你想模拟一个半工的连接(例如:AppleTalk,Ethernet,IRDA)。在某些配置里,没有必要使两个管道pipe 的配置相同,所以你可以模拟一个非对称的连接。

  如果想用RED队列管理算法来验证网络的性能:

     ipfw add pipe 1 ip from any to any
ipfw pipe 1 config bw 500Kbit/s queue 100 red 0.002/30/80/0.1

  流量整形的另一个典型应用是:在通信中加入一些延迟。这对于一些大量应用远程进程调用的程序来说,会有比较大的影响,在这些应用中,连接的重返时间限制经常比限制带宽更重要。

     ipfw add pipe 1 ip from any to any out
ipfw add pipe 2 ip from any to any in
ipfw pipe 1 config delay 250ms bw 1Mbit/s
ipfw pipe 2 config delay 250ms bw 1Mbit/s

  对“每个流量”进行限制的队列有很多用途,一个简单的应用是用来计算数据包的个数和:

     ipfw add pipe 1 tcp from any to any
ipfw add pipe 1 udp from any to any
ipfw add pipe 1 ip from any to any
ipfw pipe 1 config mask all

  上面的一组规则将对所有的连接创建一个队列(和收集统计信息)。因为管道没有限制,所以唯一的效果就是对数据做出统计。需要注意,要使用3个规 则,而不是仅仅最后一个。这是因为当IPFW匹配IP包的时候,不考虑端口,所以,在第三句里,我们看不到连接中端口的信息。  另外广泛的应用是在一个 网络中,对于“每个主机”出口的流量进行限制,要比对于“每个网络”的限制好得多。

     ipfw add pipe 1 ip from 192.168.2.0/24 to any out
ipfw add pipe 2 ip from any to 192.168.2.0/24 in
ipfw pipe 1 config mask src-ip 0x000000ff bw 200Kbit/s queue 20Kbytes
ipfw pipe 2 config mask dst-ip 0x000000ff bw 200Kbit/s queue 20Kbytes

  在下面的示例中,我们需要把流量带宽分成好几类,我们需要把不同的主机/网络对应于不同的类中。我们为每一类创建一个管道pipe,并且做好相 应的配置。然后我们创建一个单一的表,并且填上IP子网和地址。对每一个子网/主机,我们设置了和准备使用管道相同的号码。然后,我们就可以用一条规则来 分开这些流量:

     ipfw pipe 1 config bw 1000Kbyte/s
ipfw pipe 4 config bw 4000Kbyte/s
...
ipfw table 1 add 192.168.2.0/24 1
ipfw table 1 add 192.168.0.0/27 4
ipfw table 1 add 192.168.0.2 1
...
ipfw add pipe tablearg ip from table(1) to any

  使用fwd运用,表项将包含主机名和IP地址:

     ipfw table 1 add 192.168.2.0/24 10.23.2.1
ipfw table 1 add 192.168.0.0/27 router1.dmz
...
ipfw add 100 fwd tablearg ip from any to table(1)

  自动创建一个规则集,比如:set 18

     ipfw set disable 18
ipfw add NN set 18 ... # 可以重复
ipfw set enable 18

  要自动删除一个规则集,可以简单在用以下命令:

     ipfw delete set 18

  要测试一个规则集,先禁用它,然后再重新控制,测试一下有没有错误:

     ipfw set disable 18
ipfw add NN set 18 ... # repeat as needed
ipfw set enable 18; echo done; sleep 30 && ipfw set disable 18

  如果事情进展顺利,可以在“sleep”前按ctrl+C将其中断,则规则集就是处在激活的状态。否则,如果你不能操作你的机器,规则集将在睡眠一段时间后自动禁止,又可以回复到以前的状态。

  要查看规则集中的规则:

     ipfw set 18 show

  要查看被禁用的规则集中的规则:

     ipfw -S set 18 show

  要将某个集合的计数器清除:

     ipfw set 18 zero NN

  要删除某个规则集中的某个规则:

     ipfw set 18 delete NN

  首先,把所有流量重定向到nat 123例程。

    
ipfw add nat 123 all from any to any

  然后,配置例程nat 123,以ip地址192.168.0.123作地址转换,还要阻止所有进入的连接、尝试在两端保持相同的端口号、在IP地址改变时清除地址转换列表、并且还要记录通信/链接统计。

     ipfw nat 123 config ip 192.168.0.123 log deny_in reset same_ports

  或者改变例程nat 123的地址,地址转换表将被清除(参阅reset选项)

     ipfw nat 123 config ip 10.0.0.1

  要查看nat 123的配置:

     ipfw nat 123 show config

  要查看例程111-999的记录:

     ipfw nat 111-999 show

  要查看所有例程的配置:

     ipfw nat show config

  一个混杂模式的重定向规则,看起来应该如下:

     ipfw nat 123 config redirect_addr 10.0.0.1 10.0.0.66
redirect_port tcp 192.168.0.1:80 500
redirect_proto udp 192.168.1.43 192.168.1.1
redirect_addr 192.168.0.10,192.168.0.11
10.0.0.100 # LSNAT
redirect_port tcp 192.168.0.1:80,192.168.0.10:22
500 # LSNAT

  它也可以被分成以下几句规则:

     ipfw nat 1 config redirect_addr 10.0.0.1 10.0.0.66
ipfw nat 2 config redirect_port tcp 192.168.0.1:80 500
ipfw nat 3 config redirect_proto udp 192.168.1.43 192.168.1.1
ipfw nat 4 config redirect_addr
192.168.0.10,192.168.0.11,192.168.0.12
10.0.0.100
ipfw nat 5 config redirect_port tcp
192.168.0.1:80,192.168.0.10:22,192.168.0.20:25 500
   cpp(1), m4(1), altq(4), divert(4), dummynet(4), if_bridge(4), ip(4),
ipfirewall(4), ng_ipfw(4), protocols(5), services(5), init(8),
kldload(8), reboot(8), sysctl(8), syslogd(8)
   ipfw工具第一次出现在FreeBSD2.0中。dummynet(4)从FreeBSD2.2.8开始被引入。状态保持在FreeBSD4.0时被引入。ipfw2出现在2002年夏天。
   Ugen J. S. Antsilevich,
Poul-Henning Kamp,
Alex Nash,
Archie Cobbs,
Luigi Rizzo.
   API based upon code written by Daniel Boulet for BSDI.
   In-kernel NAT support written by Paolo Pisati  as part
of a Summer of Code 2005 project.
   Work on dummynet(4) traffic shaper supported by Akamba Corp.

  语法经过多年的发展,有时候比较容易混淆。不幸的是,向后兼容性阻碍了在定义语法时就清除错误。

 
!!! 警告 !!!

  不正确的配置,会导致你的计算机停止了所有的服务,进入不可使用的状态,使你不得不到机器前面去操作。

  被转发的分段的包,是在转发界面中,在转发之前重新封装的。用在这些包上的动作,就是匹配了第一个分段包的那个规则的动作。

  一个包被转发到用户空间后,将被插入到一个用户空间的进程中,这将会失去一些包的属性。如果包的长度小于8字节,并且用户进程保存和重用 sockaddr_in(就像natd(8)),包的源界面名将被保留;否则,将会消失。如果一个包以这种方式被重新插进来,后来的规则会有错误的应用, 所以,在制定规则的顺序时,按照转发的顺序进行,是很重要的。

  Dummynet在遇到IPv6的link-local地址时,会丢掉所有的包。

  使用uid或gid的规则可能会达不到预期的效果。典型地,进入的SYN包就没有一个相关的uid或gid,因为它们不属于任何的TCP连接。并且,如果相关的进程使用setuid(2)或其它类似的系统调用,数据包相关的uid/gid也会不是预期的值。

  规则语法受命令行的环境影响,其它的一些匹配模式必须用反斜杠或引号来进行转义。  受libalias(3)架构的限制,ipfw 地址转换不兼容tcp的TSO(tcp segmentation offloading,分段卸载)。所以,当在网络中使用nat的时候,请使用ifconfig工具将网卡的TSO禁止。

  已经习惯了用ipfw,觉得ipfw其实很不错,但手册上的介绍有些少,所以想弄个中文的man。但是由于本人英文和计算机都是半路出家,纯属个人爱好而自学的,所以各方面的水平都深欠火候,欢迎E文好和计算机专业的同学帮助翻译和改正。

在翻译中,受到“杜比立体声”和“FinalBSD”的帮助,一起表示感谢。

  翻译是一项非常枯燥的工作,为了尊重他人劳动,转载时请注明作者:来自chinaunix的lsstarboy。email:lsstar#sina.com

阅读(1574) | 评论(0) | 转发(0) |
0

上一篇:ipfw 中文手册(2)

下一篇:五子棋竞赛规则

给主人留下些什么吧!~~