<% dim ModuleName,InfoID,ChannelShortName,CorrelativeArticle,InstallDir,ChannelDir,Keyword,PageTitle,ArticleIntro,Articlecontent Keyword=stripHTML("原理,内核") PageTitle=stripHTML("ipfw规则") ArticleIntro=stripHTML("") Articlecontent=stripHTML("PACKET FLOW(包的流程) ipfw可以从协议堆里的很多地方被调用,在个别系统参数的控制下,最重要的要明白,何时为了设计固有的规则表才发生。ipfw被调…") ModuleName = stripHTML("classical") InfoID = stripHTML("30246") ChannelShortName=stripHTML("文章") InstallDir=stripHTML("http://www.77169.com/") ChannelDir=stripHTML("classical") %> ipfw规则 - 华盟网 - http://www.77169.com
您现在的位置: 华盟网 >> 知识库 >> 操作系统 >> FreeBSD >> 原理与内核 >> 正文

ipfw规则

2005/9/1 作者:unknown 来源: unknown
导读 <% if len(ArticleIntro)<3 then Response.Write Articlecontent 'Response.Write "Articlecontent" else Response.Write ArticleIntro 'Response.Write "ArticleIntro" end if %>
PACKET FLOW(包的流程)
ipfw可以从协议堆里的很多地方被调用,在个别系统参数的控制下,最重要的要明白,何时为了设计固有的规则表才发生。ipfw被调用的如下表示,一起的还有
控制它的sysctl 变量

^ to upper layers V
| |
+----------->-----------+
^ V
[ip_input] [ip_output] net.inet.ip.fw.enable=1
| |
^ V
[ether_demux] [ether_output_frame] et.link.ether.ipfw=1
| |
+-->--[bdg_forward]-->--+ net.link.ether.bridge_ipfw=1
^ V
| to devices |


有图所示,数据包穿过防火墙的次数可以在0-4之间变化,这依赖于数据包的源,目的地和系统配置。在每一个位置里,包只被属于自己所在层区域的配置检验。也就是说,来访的数据包包含MAC头,当ipfw在
规则表总是在执行的,无论是ipfw的调用的地方,还是包来源的地方。如果一个规则包含一些匹配模式或对调用地方无效的行为(例如当ipfw在ip_input处被调用,去匹配一个MAC头)匹配模式将不匹配。无论如何,一个没有操作数的模式将导致,此模式永远匹配那些有歹意的数据包。这是程序员的责任,如果需要,写一个恰当的规则表,以区分有可能涉及到的地方,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_demu and bdg_forward 之间没有任何区别。

规则格式:
ipfw规则的格式如下:
[rule_number] [set set_number] [prob match_probability]
action [log [logamount number]] body
body部分的设置是为了过滤信息包的,有以下几种:

Layer-2 header fields 当用到的时候
IPv4 Protocol TCP, UDP, ICMP, etc.
Source and dest. addresses and ports
Direction See Section PACKET FLOW
Transmit and receive interface 由名字或地址决定
Misc. IP header fields 版本,服务器种类,数据包长, 度 鉴定,片断标记(非零 IP 抵消),存活时间
IP options:
Misc. TCP header fields TCP flags (SYN, FIN, ACK, RST,
etc.), 序号, 确认号, 窗口
TCP options:
ICMP types 对于ICMP的数据包
User/group ID 当数据包能被联系到本地的计算机上
注意上面的信息,举例来说,源MAC或者是IP地址和TCP/UDP端口,容易受到欺骗,所以当过滤这些领域的数据包时,不能保证可以得到预期的效果。
rule_number
每一条规则都有一个规则号,范围是1..65535,还有一些近来被保留的默认规则。规则是按规则号有序的被察看。多种规则可以有同样的号码,在这种情况下,被察看,或列出,也是依照他们在设置中的顺序。如果一条加入的规则,没有特殊的号码,内核将自动分配一个号码,排在除默认规则的所有规则的最后面,这个自动的号码是由最后一个非默认的规则号给于赋值的如果这个号码与最后一个冲突,则最后一个号码的规则奖被取代(因为自动的序列号可能会超过最大范围)。
set set_number
每一条规则都有一个设置号,范围是0..31,和一些最近为默认规则所保留。这个设置号可以个别的激活或段掉,所以对于子规则的操作,这个是最基本也是最重要的了。他也可以用在单一的规则的删除里,如果一个输入的规则没有设置号,那么将自动赋值0给它!
prob match_probability
一个匹配只是被公开的和一个指定的概率(浮动点在0-1)。这个可以用在一个应用的数字上,例如像任意包的丢失,或模拟多路经引导无序的包传输的效果。
log [logamount number]当一个数据包用关键字匹配一个规则的时候,工具LOG_SECURITY 将这个信息保存到syslogd( 8) 里。记录信息只在变量net.inet.ip.fw.verbose设置为1的情况下出现(这个是被默认的当内核被命令IPFIREWALL_VERBOSE 编译的时候)并且迄今为止被记录的包的号码,他们的那些规则没有超出他们记录的变量。如果没有变量被指定,那么这个限定的从变量net.inet.ip.fw.verbose_limit中提取。
一旦限定被延伸,记录将由清除的计算器或那个进入的包的计算器重新激活。看resetlog 命令。
RULE ACTIONS
一个规则可以用以下的某一种行为设置,就是要执行的那部分当数据包匹配规则躯干的时候。
allow | accept | pass | permit
允许包去匹配规则。停止搜索。
check-state
检查包所依靠的规则。如果一个匹配被发现,则执行规则里联带的行为,另外移动倒下一个规则。Check-state 规则没有躯干。如果一个非Check-state 的规则被发现,则动态的规则将在第一或限定的规则里找。
count 更新计算,为了所有的数据包去匹配规则。寻找下一个规则。
deny | drop
匹配这个规则的要丢弃数据包。搜索结束。
divert port
匹配这个规则的要将数据包转向到此规则提到的端口去,搜索停止。
fwd | forward ipaddr[,port]
改变下一跳在被匹配的数据包到一个ip地址去,这个可以是ip也可以是主机名。
如果ip是本地地址,则被匹配的数据包将被转移到一个本地计算记的端口(或是包上的端口数,如果那个没有被说明在规则里)
如果ip地址是外部的,则端口号(如果被指出)被忽略 ,并且发送到远端的地址,用路由器在本地路由表里寻找那个ip。
一个fwd规则不匹配2层包(那些在ether_input, ether_output, or bridged上的包)
fwd行为不根本改变包的内容。详细说,不更改目的地址,所以数据包被发送到另一个系统通常是被系统拒绝的,除非有一个匹配规则在那个系统上来捕捉他们!至于数据包传送到本地,socket上的本地地址将被放置到数据包的最初的目的地址上,这个使进入的netstat看上去更怪异,但是制定成使用透明的代理服务器了。
pipe pipe_nr
通过的包到虚拟pipe(为了宽带限制的延迟)。看TRAFFIC SHAPER CONFIGURATION。搜索结束,不管出口是从管道并且如果net.inet.ip.fw.one_pass 值没有被设置,数据包仍被传递到下一个防火墙规则。
queue queue_nr
传递包到虚拟queue(为了宽带限制的使用WF2Q)。
rejec 被拒绝,跟无法找到主机一样。
reset 被丢弃的包若是一个tcp包,就试图发送一个tcp重组信息。搜索结束。
skipto number
跳读所有后来的规则号,继续搜索第一个号码和更高的那个。
tee port
发送一个匹配这个规则的拷贝到divert socket邦定的端口。搜索结束,最初的包被接受。
unreach code
按规则丢弃的数据包,发送一个ICMP的带编码的不能得到的提示,这个编码是0-255的一个数字,或者以下列的其中一个:网名,主机名,协议,端口,碎片,失败,网络未知,主机未知,独立的,网络禁用的,主机禁用的,到子网,到子机,过滤禁止,主机优先权或者优先权终止。搜索结束。
RULE BODY
规则的躯干包含0或更多的参数(例如,明确的来源和目的地址或端口,协议选项,进出的接口等等。)那些数据包必须匹配除了别的规则。通常,连接模式都是由操作项固定的。也就是所有的匹配都是按顺序的进行匹配,个别的模式可以由非操作项给于相反的匹配结果。例如 :
ipfw add 100 allow ip from not 1.2.3.4 to any
再有,可供选择的匹配模式能由扩号内输入的模式进行建造,例如:
ipfw add 100 allow ip from { x or not y or z } to any
只有扩号内一种模式被允许。要小心,有一些内核对扩号有特殊的含义,所以明智的办法就是放一个斜杠“\”在他们前面来杜绝这种情况。
一个规则的躯干通常必须有来源和目的地址,关键字"any"可用在不同的地方标示,满足的条件是任意的。
规则的躯干有下列格式:
[proto from src to dst] [options]
第一部分(protocol from src(源) to dst(目的))是用ipfw1兼容的。在ipfw2,任何匹配模式(包括MAC地址,IPv4 protocols,,地址和端口)可以在选项部分被指定。
规则部分有以下含义:
proto: protocol | { protocol or ... }
一个IPv4 协议(或一个,或多个)由号码或名字指定(察看/etc/protocols)。ip或所有的关键字意味着将匹配所有的协议。
src and dst: ip-address | { ip-address or ... } [ports]
一个单独的ip地址,一个或包含多个的,由端口设置决定他们的走向。
ip-address:
一个指定的地址(或地址设置)在下列方法的其中一个里由非操作项控制。
any 匹配任何ip。
me 匹配系统接口的任何ip。在数据包被分析的时候,会查询ip列表的。
numeric-ip | hostname
匹配一个单独的ip地址或主机名,主机名也可以添加防火墙列表的。
addr/masklen
匹配所有的ip地址或主机名(带掩玛的ip段)例如,1.2.3.4/25 ,将匹配所有的ip从1.2.3.0到1.2.3.127。
addr/masklen{num,num,...}
还有一种如下例:1.2.3.4/24{128,35,55,89},此规则则匹配以下ip地址:
1.2.3.128 1.2.3.35 1.2.3.55 1.2.3.89 .
这种格式是特殊用于处理单独规则里面少量的地址。
ports: [not] {port | port-port} [,...]
支持端口号的协议(例如:TCP and UDP),随意的端口号可以被指定,一个,多个,胡哦这是一个范围,用“,”隔开(不能有空格),并且一个随意的没有具体的项。“-”符号指定带边界的范围。
服务器(from /etc/services)的名字可以用数字的端口值代替。端口的长度被限制到30,或一个范围内,尽管这个范围在规则里很大。
"\"可以劈开用"-"在shell里的冲突(有的服务器有自己的定义)。
ipfw add count tcp from any ftp\\-data-ftp to any
一个非零的包的碎片(也就是不是第一段的)将不匹配规则规则。看关于碎片设置的详细资料。
RULE OPTIONS (匹配模式)
附加的匹配模式可以被用在规则里面。0或者其他所谓的设置都可以出现在规则里,前置由非操作数和可能的区域里的组决定。
以下匹配模式可以使用:
bridged
指匹配过渡的数据包。
dst-ip ip address
匹配ip包,看谁的目的地址是清单里的其中一个。
dst-port source ports
匹配ip包,看谁的目的端口是清单里的其中一个。
established
匹配那些有RST or ACK bits设置的TCP包。
frag 匹配那些片断或者不是第一段的ip数据包,注意,这些包不具备下一个协议头(e.g. TCP, UDP),所以这些玄想不能被匹配。
gid group
匹配所有被组(组可以是指定的名字或数字)承认的TCP or UDP包。
icmptypes types
匹配所有的列在ICMP类表里的ICMP包。列表可以是一个指定的范围,或者是逗号隔开的个别类型。这里支持的ICMP类型有:
echo reply (0), destination unreachable (3), source quench (4),
redirect (5), echo request ( 8) , router advertisement (9), router
solicitation (10), time-to-live exceeded (11), IP header bad
(12), timestamp request (13), timestamp reply (14), information
request (15), information reply (16), address mask request (17)
and address mask reply (1 8) .
in | out
分别的匹配进出的包,进和出是互斥的(实际上,出就是执行不进)。
ipid id
匹配IP包里的Id值。
iplen len
匹配ip包的总长度,包括头和数据。
ipoptions spec
匹配谁的ip头包含用逗号隔开的设置,支持以下几种:
ssrr (strict source route), lsrr (loose source route), rr (record
packet route) and ts (timestamp). 没有详细说明则用"!"表示。
ipprecedence precedence
匹配有优先权的IP。
iptos spec
匹配带有被逗号隔开的服务类型表的ip,支持以下几种:
lowdelay (IPTOS_LOWDELAY), throughput (IPTOS_THROUGHPUT),
reliability (IPTOS_RELIABILITY), mincost (IPTOS_MINCOST),
congestion (IPTOS_CE). 没有详细说明则用"!"表示。
ipttl ttl
匹配ip的存活时间
ipversion ver
匹配ip的版本号
keep-state
在匹配时,防火墙将创建一个动态规则,它的默认的行为就是去匹配双向的通信,在源和IP/port使用同样协议的的目的地之间。这个规则有一定寿命,这个存活时间在每次要匹配的包被找到后重新更新。
layer2 仅匹配2层的包,例如通过ipfw的从ether_demux() and ether_output_frame().
limit {src-addr | src-port | dst-addr | dst-port} N
防火墙只允许像设置里的那个数N连接,一个或多个的源和目的地址都会被定义。
{ MAC | mac } dst-mac src-mac
匹配带有MAC的源和目的地址,详细的就像一些关键字,或者是6个被逗号隔开的数字,例如下:
MAC 10:20:30:40:50:60/33 any
注意MAC地址的规则(目的地第一,源第二)他们同样也在信息里,只是对应的习惯用IP地址罢 了。
mac-type mac-type
匹配跟内网类型一样的数据包。mac类型也用同样的方法被定义就像端口号。你可用象征的名字为你知道的含义,像vlan, ipv4, ipv6.这个值也可以被直接输入,像10近制,16近制,他们输出总是按16近制,除非-N设置启用,那么那些符号将被试图启用。
proto protocol
匹配ipv4的通用协议。
recv | xmit | via {ifX | if* | ipno | any}
匹配接受的包,分别的转输或是通过,接口被将由精确的名字(ifX)和设备名字(if*)所定义,还可以由ip或一些其它的接口定义。
via这个关键字就是说,所有的接口总是要被检查的。如果是recv or xmit取代了via则表示只接受,或只转发,这就有可能匹配包是基于接受和转发的接口上的。例如:
ipfw add deny ip from any to any out recv ed0 xmit ed1
recv接口可以测试在通过他们所进出的包,所以只要xmit在使用中,出就会被请求(没有进)。

一个包可以没有接受或转发接口:数据包从本地主机出来,是没有接受接口的,一会儿就回到达没有转发接口的本地主机。
setup 匹配只带SYN字节不带ACK字节的TCP包,
src-ip ip-address
匹配ip包里有源ip在地址列表里的
src-port ports
匹配ip包里有源端口在端口列表里的
tcpack ack
仅TCP包,匹配TCP头带有ack字样的包。
tcpflags spec
仅TCP包,匹配TCP头带有逗号隔开的字样的包,支持以下几种:

fin, syn, rst, psh, ack and urg. The absence of a particular
flag may be denoted with a `!'. A rule which contains a tcpflags
specification can never match a fragmented packet which has a
non-zero offset. See the frag option for details on matching
fragmented packets.
tcpseq seq
仅TCP包,匹配TCP头带号码区有seq字样的包。
tcpwin win
仅TCP包,匹配TCP头带window区有win字样的包。
tcpoptions spec
仅TCP包,匹配TCP头包含逗号隔开的选想说明,支持以下几种:

mss (maximum segment size), window (tcp window advertisement),
sack (selective ack), ts (rfc1323 timestamp) and cc (rfc1644
t/tcp connection count). 空缺用`!'表示。
uid user
匹配所有用户收发数据包,用户可以由名字或认证数字来匹配。
SETS OF RULES
每一条规则都是32不同条例中的其中一个,0-31,31为保留的默认规则。
默认的情况下,,规则将被设置为0,除非你输入新规则是,在N上有所改动,设置可以被个别激活或者停止,所以这种办法允许一个很简单的方法去贮存防火墙的多种配置,很快的可以在它们之间互相转换。激活/停止的命令为:
ipfw set disable number ... [enable number ...]

各种各样的激活或者停止,可以分别指定。命令的执行在所有指定的设置中很微小,默认情况下。所有设置为激活的。
当你停止一个设置,他的规则则表现为在防火墙上没有任何配置,只有一种情况例外:
由源规则(父规则)创建一个动态的规则,在他被停止之前,一直运行,直到他们中断为止。为了删除动态规则,你不得不将他们俩个规则全都删除;
规则的号码可以用命令更改
ipfw set move {rule rule-number | old-set} to new-set
同样你也可以交换两个规则
ipfw set swap first-set second-set
( See the EXAMPLES Section on some possible uses of sets of rules.)

STATEFUL FIREWALL
Stateful的作用是让防火墙能动态的创建一个规则,为了描述当匹配包所给出的模式的流程。这个的实现是通过规则的check-state, keep-state and limit得设置得到的。
当一个数据包匹配keep-state or limit规则时,动态规则将被创建,这个动态规则将匹配所有的包所给出的src-ip/src-port dst-ip/dst-port之间的协议(这里所使用的源地址和目的地地址都指最初的地址,但是后来他们将完全一样)动态规则在第一次的check-state,keep-state or limit将被选中,并执行匹配,此匹配跟父规则一样。
注意,这些不是附加的属性,除了动态规则检查的协议,ip地址和端口。
动态规则典型的应用是保持一个关闭的防火墙设置,但是让第一个从内网来的TCP SYN包将安装一个为流程动态规则,所以那些包允许通过防火墙:

ipfw add check-state
ipfw add allow tcp from my-subnet to any setup
ipfw add deny tcp from any to any
类似的途径可以为UDP使用,一个从内网来的UDP包,将安装一个动态规则去允许防火墙作应答:

ipfw add check-state
ipfw add allow udp from my-subnet to any
ipfw add deny udp from any to any
(See Section EXAMPLES for more examples on how to use dynamic rules.)


TRAFFIC SHAPER CONFIGURATION
ipfw也同样是塑造通信的用户接口。这个塑造器由划分的包进到流程中按照用户指定的在ip头不同区域的掩码,包同样属于流程,也通向2个不同的目标,(named pipe or queue)名字管道和列队。
一个管道就像一个给定的宽带, 传播延迟,列队大小和包丢是的比率。包是按照自身的参数通过管道的

一个列队,就是一个提取过程,执行WF2Q+方针()列队使没一个流程跟weight和reference管道发生联系。 然后,所有的流程按照管道WF2Q+方针按预定的比率指向预定的同样的管道。
ipfw管道的配置格式如下:

pipe number config pipe-configuration

ipfw列队的配置格式如下

queue number config queue-configuration

管道配置的参数如下:

bw (bandwidth) | (device)
Bandwidth, 标准[K|M]{bit/s|Byte/s}.

默认值0意味着无限带宽。这个单位必须跟数字,例如:

ipfw pipe 1 config bw 300Kbit/s

如果一个设备的名字是数字代替定义的,则发送时间由被定义的设备给出。在这个时候只有通道设备支持此函数,以建立端对端协议的连接。

delay ms-delay
传播延迟是用毫秒为标准。此值为轮到下一次时间启动的值(例如,10ms,它是最习惯去运行配置为HZ=1000内核的值,去减少间隔时间到1ms或更少),默认为0时,表示没有延迟。

以下设置参数可以用在queue(列队等待)上:

pipe pipe_nr
连接一个列队到指定的通道。多样的类对(通常是不同的大小)可以被联接到同一个通道。

weight weight
指定的大小用来作匹配这个列队的流程。这个大小必须是一个范围1..100, 和默认值1.

以下参数可以对双通道,和多列队进行配置。

buckets hash-table-size
指定哈西表大小,是为了储存不同的列队。由net.inet.ip.dummynet.hash_size默认为64,允许范围是16到1024。

mask mask-specifier
dummynet可使你建立单一流程的列队。一个可识别的流程,是由ip地址的演化而成的,端口和协议类型和管道设置里一样。带有同样标示的包在演化后,进到同样的列队。可用的掩码定义为以下几种:

dst-ip mask, src-ip mask, dst-port mask, src-port mask, proto
mask or all, 后面的这个表示所有有意义的所有领域的所有字节。当用在管道的配置里时,每一个流程被指派一个和管道速度一样的速度。当用在列队配置的时候,每一个流程被指派一个和列队大小一样的大小,并且所有流程按他们大小比例分享在同样的管道的带宽

noerror
当一个包从管道或列队中丢失,这个错误将报给呼叫路由得知,同样的方法,当一个列队装置填满后也会发生。设置这个选项,报告数据包被成功接收,这个使需要一些试验的设备,在你想模拟丢失或堵塞在源端的路由器地方。

plr packet-loss-rate
包的丢失机率,packet-loss-rate是一个0-1之间的浮点数,0就是没丢失,1是完全丢失,丢失机率内在表现为31bits.
queue {slots | sizeKbytes}
列队大小,用slots or KBytes表示。默认值为50 slots,这个是典型的局域网设备的Queue大小。注意,那个是适用比较慢的连接,你应该保持你的queue大小短一些,或者你的通信会受到由queue延迟的影响,例如:最大值为50的局域网的数据包(1500 bytes),这就意味着600Kbit或queue20s在一个30Kbit/s的管道上。你如果从接口处得到一个带有太大MTU的数据包,就会导致连接失败,例如:回环接口有一个16kb的包。

red | gred w_q/min_th/max_th/max_p
使用RED (自动搜索)运算法则。w_q and max_p是0-1之间的浮点数(不包括0),当min_th and max_th是整数的时候指定了queue管理的极限(极限使用字节来计算,如果queue使用字节来定义的话,用slots是另外一种情况了)。网络也支持RED的变量(gred).这些系统控制变量常用于控制RED的行为:

net.inet.ip.dummynet.red_lookup_depth
定义当连接空闲下来,计算queue平均值的精度(默认为256,必须大于0)

net.inet.ip.dummynet.red_avg_pkt_size
定义期望的数据包的平均大小(默认为512,必须大于0)。

net.inet.ip.dummynet.red_max_pkt_size
定义期望的数据包的最大值,仅当queue极限用字节表示的时候使用(默认为1500,必须 大于0)

CHECKLIST
当计划规则时候的一些注意事项:
1:记住你的过滤包的走向,一个出,一个进。更多的连接需要包在两个方向进行
2:记住测试的时候非常小心。这是一个好建议当接近控制台的时候。如果你不能使用控制台,用一个自动生成的源文件/usr/share/examples/ipfw/change_rules.sh.
3:不要忘记回环接口(127.0.0.1)

FINE POINTS
1:有一个环境使破碎的文件完全丢弃掉。如果TCp头包含一个小于20字节的包,则丢弃,UDP头必须包含一个完整的8个字节的包,否则丢弃,ICMP包则丢弃那些ICMP头不包含4个字节的包,充分的指定 ICMP类型,编码,和检查总数。这些包完全被记录下来,例如:``pullup failed''因为在包里没有足够好的数据去产生有用的日志文件。

2:其它类型的包则无条件的丢弃,一个带碎片TCP包。这是一个有效的包,但是只有一个有用,试图绕过防火墙。当日志被激活,这些包被丢弃就像被规则-1丢弃一样。

3:如果记录整个网络的日志,装载ipfw的kld版本,她不像你想象的那么简单。介绍以下命令行:
kldload /modules/ipfw.ko && \
ipfw add 32000 allow ip from any to any

Along the same lines, doing an

ipfw flush

in similar surroundings is also a bad idea.

3:ipfw过滤器列表不可以被修改,如果系统的安全级别为3或更高(see init( 8) for information on system security levels).

PACKET DIVERSION
一个转向插座跃向指定的端口将接收到的所有包转到那个端口。如果没有socket 被邦定到指定端口,或者内核不支持,包将被丢弃。

SYSCTL VARIABLES
内核变量的设置将控制防火墙的行为和联合模块( dummynet, bridge )。这里一起介绍他们,包括他们的默认值:

net.inet.ip.dummynet.expire: 1
一旦如果没有了没完的通信,就删除动态pipes/queue。你可以停止这个,将变量设置为0,这个情况下,仅在极限到头的时候删除pipes/queue。

net.inet.ip.dummynet.hash_size: 64
动态pipes/queue的默认哈示表。这个默认值是当没有buckets 被指定当配置pipe/queue时。

net.inet.ip.dummynet.max_chain_len: 16
pipes/queues 在hash bucket里最大的目标值。max_chain_len*hash_size习惯用于测试将被关闭的,甚至net.inet.ip.dummynet.expire=0的空pipes/queues 的极限。

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之间。

net.inet.ip.fw.curr_dyn_buckets: net.inet.ip.fw.dyn_buckets
动态规则的哈希表里的buckets当前值(只读的)

net.inet.ip.fw.debug: 1
由ipfw控制的调试信息。

net.inet.ip.fw.dyn_buckets: 256
动态规则的哈希表里的buckets值,必须是2的幂数,最大到65536。他仅在所有的动态的规则停止的时候起作用,所以你仔细考虑是否使用Flush命令,来确定调整哈希表的大小。

net.inet.ip.fw.dyn_count: 3
动态规则的当前号。

net.inet.ip.fw.dyn_keepalive: 1

Enables generation of keepalive packets for keep-state rules on
TCP sessions. A keepalive is generated to both sides of the con-
nection every 5 seconds for the last 20 seconds of the lifetime
of the rule.
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秒之内,keepalives的重复周期。防火墙会强制执行这个的.

net.inet.ip.fw.enable: 1
激活防火墙,如果设置为0,则关闭防火墙,即使编译也没用。

net.inet.ip.fw.one_pass: 1
设置时,从dummynet(man dummynet)管道出来的包不再通过防火墙,另外,包会被放到防火墙的下一条规则里去。
注意:bridged and layer 2管道出来的包不管设置如何,将不会被放到防火墙里面了。

net.inet.ip.fw.verbose: 1
激活详细信息。

net.inet.ip.fw.verbose_limit: 0
限制由详细的防火墙产生的信息号。

net.link.ether.ipfw: 0
控制layer-2的包是否允许ipfw,默认为"不是"。

net.link.ether.bridge_ipfw: 0
控制bridged的包是否允许ipfw,默认为"不是"。

IPFW2 ENHANCEMENTS
这部分介绍在ipfw1里没涉及到的一些重要的特性。列举的是对你设置规则有一定影响的内容。你可以考虑使用这些特性,以便你设置规则的时候有更多的有效途径。

Handling of non-IPv4 packets
ipfw1将依照规则接受所有非IPv4 的包(仅当net.link.ether.bridge_ipfw=1的时候)像ipfw1一样完成同样的行为,你可以使用以下条例,可以当作你规则栏里的第一条:

ipfw add 1 allow layer2 not mac-type ip

layer2选项可能被看作多余的,但是由是必需的,从layer3到防火墙的包没有了MAC头,则MAC类型的ip模式总要舍去,并且非操作数将使这个规则变成全部通过。

Address sets
ipfw1不支持地址设置 (看addr/masklen{num,num,...} ).

ipfw1 and ipfw2较小的区别就是,以前指定的允许的地址,像ipno:mask,这里的mask可以是代替bit设置的任意的bitmask 。ipfw2不再支持此语法。

Port specifications
ipfw1 仅允许一个端口范围,当指定TCP and UDP端口时,ipfw2将限制由15个变为10个。同样在ipfw1里,你只能定义端口,在规则被请求tcp or udp包的时候,用ipfw2你可以提出一个端口的详细说明在匹配所有包的规则里,并且匹配将被尝试仅仅在那些包所带的协议里包括端口的标识符。

ipfw1里要求第一个端口的进入,是被指定的,就像port:mask ,mask可以是任意的16-bit mask.这个语法也是在ipfw2里不用的。

Or-blocks
ipfw1 不支持 Or-blocks.

keepalives
ipfw1 不产生keepalives为数据。像一个因果关系,它可以导致一个空闲区域的停止,因为
动态规则的存活时间终止了。

Sets of rules
ipfw1 不执行规则的设置。

MAC header filtering and Layer-2 firewalling.
ipfw1 不在MAC头区域进行过滤,也不被调用当包从ether_demux()和ether_output_frame()过来。sysctl变量net.link.ether.ipfw在这里也不起作用。

Options
以下设置在ipfw1不支持:

dst-ip, dst-port, layer2, mac, mac-type, src-ip, src-port.

还有ipfw1规则里不支持的:

ipid, iplen, ipprecedence, iptos, ipttl, ipversion, .Cm tcpack,
tcpseq, tcpwin.

Dummynet options
以下设置为dummynet pipes/queues不支持:
The following option for dummynet pipes/queues is not supported:

noerror.

EXAMPLES
这里仅仅给出很小的一个例子的设置。

BASIC PACKET FILTERING
这个命令加进一个条目,拒绝所有来自cracker.evil.org telnet wolf.tambov.su的端口的tcp包:

ipfw add deny tcp from cracker.evil.org to wolf.tambov.su telnet

这个是拒绝所有的来自此网的用户访问我的主机:

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包,这些包只由setup规则匹配,也仅仅对source/destination有选择性的。所有其它的SYN包将由最后的拒绝规则丢弃掉。

如果你管理一个或更多的子网,你可以用ipfw2语法的优势去指定地址。如下:

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 ...

ipfw1 语法只能为没一个ip独立设置要求,不能像上面那样。

DYNAMIC RULES
为了保护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

前者是允许没一个在那个网络上的主机可以开10个tcp连接。后面的将被放到服务器上,去证实单一的客户端没有同时使用4个以上的tcp连接。

BEWARE:数据规则可能会被 SYN-flood 攻击,还有其他一些的攻击手段可以在设置sysctl的变量的时候限制他们。


这里有一些好办法,去察看那些账户纪录和时间段的信息:

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

TRAFFIC SHAPING
下列规则显示ipfw and dummynet的一些应用。

这个规则5%的几率随机丢掉引入的包:

ipfw add prob 0.05 deny ip from any to any in

作一个dummynet pipes也可以达到同样的效果:

ipfw add pipe 10 ip from any to any
ipfw pipe 10 config plr 0.05

我们可以使用管道,手工限制宽带,例如,在一个当路由器的及其上,如果我们想限制从本地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

注意我们用非修改的,所以,那个规则只能用一次。记住实际上,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

上述的很重要,例如,如果你想看你的网页将怎样寻找你那个连接很慢的用户。你应该不仅仅使用一个 通道为双向连接,除非你想模拟一个半双工的方法(例如:AppleTalk, Ethernet, IRDA),双通道有同样的 设置是不可取的,所以我们也模拟不均衡的连接。

我们应该用RED queue运算法则测试网络:

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


SETS OF RULES
添加一个小规则的设置,例如18:

ipfw disable set 18
ipfw add NN set 18 ... # repeat as needed
ipfw enable set 18

删除的命令为:

ipfw delete set 18

去测试一个规则表,如果哪出现了问题,就关闭它并重新调节:

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

这里,如果一切正常,你可以按control-C在"sleep"停止之前,并且你的规则表将被保存。另外,例如如果你不能存取你的小盒子,那些规则表将在"sleep"停止之后被关闭,因而重新储存以前的配置。
SEE ALSO
cpp(1), m4(1), bridge(4), divert(4), dummynet(4), ip(4), ipfirewall(4),
protocols(5), services(5), init( 8) , kldload( 8) , reboot(8) , sysctl(8) ,
syslogd( 8)  


  • 上一篇文章:

  • 下一篇文章: