ipfw 是 FreeBSD 内建的防火墙指令,我们可以用它来管理进出的网络交通。如果防火墙服务器是扮演着路由器 (gateway 例如上一篇中的 NAT 服务器) 的角色,则进出的封包会被 ipfw 处理二次,而如果防火墙扮演的是桥接器 (bridge) 的角色,则封包只会被处理一次。这个观念关系着我们以下所要介绍的语法,有的语法并不适用于桥接器。
另外,我们在设定防火墙时有二种模式,一种模式是预设拒绝所有联机,再一条一条加入允许的联机;另一种是预设接受所有联机,加入几条拒绝的规则。如果是非常强调安全性,应该是使用预设拒绝所有联机,再一条一条加入我们允许的规则。
我们会将 firewall 的设定写在 /etc/rc.firewall 中,每一条设定都是以先入为主 (first match wins) 的方式来呈现,也就是先符合的规则 (rules) 为优先。所有进出的封包都会被这些规则过滤,因此我们会尽量减少规则的数量,以加速处理的速度。
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命令可以利用的选项:
使用 list 时,列出数据包的计数器,show命令包含这个选项。
只显示动作和注释,不显示规则体。包含-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(数据包流程)一个数据包在几个内核变量的控制下,在协议栈的多个地方被防火墙检查。这些地方和变量如下图所示,要在头脑中保持下图,它对于规划一下正确的规则集是非常重要的。
net.inet(6).ip(6).fw.enable=1
net.link.ether.ipfw=1
net.link.bridge.ipfw=1
需要注意的是,在包通过不同栈的时候,头会被加上或剥离,可能会导致这些包被检查不到。例如:当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 -i
(对,在这儿,没有办法区别ether_demux和bdg_forward)
分页: [1] [2] [3]
TAG: