PF的关键字顺序有多灵活?PF防火墙最详细教程
PF 语法
PF的语法相当灵活,因此,允许编写非常灵活的规则集。PF能够自动插入某些关键字因此它们不必在规则中明确写出,关键字的顺序也是随意的,因此不需要记忆严格的语法限制。
减少关键字
(相关资料图)
要定义全部拒绝的策略,使用下面2条规则:
block in all block out all
这可以简化为:
block all
如果没有指定方向,PF会认为规则适用于数据包传递的进、出2个方向。
同样的, "from any to any" 和 "all" 子句可以在规则中省略,例如
block in on rl0 all pass in quick log on rl0 proto tcp from any to any port 22 keep state
可以简化为:
block in on rl0 pass in quick log on rl0 proto tcp to port 22 keep state
第一条规则阻塞rl0上从任意到任意的进入数据包,第二条规则允许rl0上端口22的TCP流量通过。
Return 简化
用于阻塞数据包,回应TCP RST或者ICMP不可到达的规则集可以这么写:
block in all block return-rst in proto tcp all block return-icmp in proto udp all block out all block return-rst out proto tcp all block return-icmp out proto udp all
可以简化为::
block return
当PF看到return关键字,PF可以智能回复合适应答,或者完全不回复,取决于要阻塞的数据包使用的协议。W
关键字顺序
在大多数情况下,关键字的顺序是非常灵活的。例如,规则可以这么写:
pass in log quick on rl0 proto tcp to port 22 \ flags S/SA keep state queue ssh label ssh
也可以这么写:
pass in quick log on rl0 proto tcp to port 22 \ queue ssh keep state label ssh flags S/SA
其他类似的顺序也能够正常工作。
编辑本段 回目录
PF防火墙 - 高级配置
运行选项
运行选项是控制pf操作的选择。这些选项在pf.conf中使用set指定。
set block-policy设定过滤规则中指定的block动作的默认行为。 drop - 数据包悄然丢弃. return - TCP RST 数据包返回给遭阻塞的TCP数据包,ICMP不可到达数据包返回给其他。 注意单独的过滤规则可以重写默认的响应。
set debug设定pf的调试级别。 none - 不显示任何调试信息。 urgent - 为严重错误产生调试信息,这是默认选择。 misc - 为多种错误产生调试信息。(例如,收到标准化/整形的数据包的状态,和产生失败的状态)。. loud - 为普通条件产生调试信息(例如,收到被动操作系统检测信息状态)。
set fingerprints file设定应该装入的进行操作系统识别的操作系统特征文件来,默认是 /etc/pf.os.
set limitfrags - 在内存池中进行数据包重组的最大数目。默认是5000。 src-nodes - 在内存池中用于追踪源地址(由stick-address 和 source-track选项产生)的最大数目,默认是10000。 states - 在内存池中用于状态表(过滤规则中的keep state)的最大数目,默认是10000。
set loginterface int设定PF要统计进/出流量和放行/阻塞的数据包的数目的接口卡。统计数目一次只能用于一张卡。注意 match, bad-offset, 等计数器和状态表计数器不管 loginterface是否设置都会被记录。
set optimization为以下的网络环境优化PF: normal - 适用于绝大多数网络,这是默认项。 high-latency - 高延时网络,例如卫星连接。 aggressive - 自状态表中主动终止连接。这可以大大减少繁忙防火墙的内存需求,但要冒空闲连接被过早断开的风险。 conservative - 特别保守的设置。这可以避免在内存需求过大时断开空闲连接,会稍微增加CPU的利用率。
set state-policy设定 PF在状态保持时的行为。这种行为可以被单条规则所改变。见状态保持章节。 if-bound - 状态绑定到产生它们的接口。如果流量匹配状态表种条目但不是由条目中记录的接口通过,这个匹配会失败。数据包要么匹配一条过滤规则,或者被丢弃/拒绝。 group-bound - 行为基本和if-bound相同,除了数据包允许由同一组接口通过,例如所有的ppp接口等。 floating - 状态可以匹配任何接口上的流量。只要数据包匹配状态表条目,不管是否匹配它通过的接口,都会放行。这是默认的规则。
set timeoutinterval - 丢弃过期的状态和数据包碎片的秒数。 frag - 不能重组的碎片过期的秒数。
例如:
set timeout interval 10 set timeout frag 30 set limit { frags 5000, states 2500 } set optimization high-latency set block-policy return set loginterface dc0 set fingerprints /etc/pf.os.test set state-policy if-bound
编辑本段 回目录
PF防火墙 - 流量整形
简介
流量整形是将数据包标准化避免最终的数据包出现非法的目的。流量整形指引同时也会重组数据包碎片,保护某些操作系统免受某些攻击,丢弃某些带有非法联合标记的TCP数据包。流量整形指引的简单形式是:
scrub in all
这会对所有接口上到来的数据包进行流量整形。
一个不在接口上进行流量整形的原因是要透过PF使用NFS。一些非openbsd的平台发送(和等待)奇怪的数据包,对设置不分片位的数据包进行分片。这会被流量整形(正确的)拒绝。这个问题可以通过设置no-df选项解决。另一个原因是某些多用户的游戏在进行流量整形通过PF时存在连接问题。除了这些极其罕见的案例,对所有的数据包进行流量整形时强烈推荐的设置。
流量整形指引语法相对过滤语法是非常简单的,它可以非常容易的选择特定的数据包进行整形而不对没指定的数据包起作用。
选项
流量整形有下面的选项:
no-df在IP数据包头中清除不分片位的设置。某些操作系统已知产生设置不分片位的分片数据包。尤其是对于NFS。流量整形(scrub)会丢弃这类数据包除非设置了no-df选项。某些操作系统产生带有不分片位和用0填写IP包头中分类域,推荐使用no-df和random-id 联合使用解决。 random-id用随机值替换某些操作系统输出数据包中使用的可预测IP分类域的值这个选项仅适用于在选择的数据包重组后不进行分片的输入数据包。 min-ttl num增加IP包头中的最小存活时间(TTL)。 max-mss num增加在TCP数据包头中最大分段值(MSS)。 fragment reassemble在传递数据包到过滤引擎前缓冲收到的数据包碎片,重组它们成完整的数据包。优点是过滤规则仅处理完整的数据包,忽略碎片。缺点是需要内存缓冲数据包碎片。这是没有设置分片选项时的默认行为。这也是能和NAT一起工作的唯一分片选项。 fragment crop导致重复的碎片被丢弃,重叠的被裁剪。与碎片重组不同,碎片不会被缓冲,而是一到达就直接传递。 fragment drop-ovl跟 fragment crop 相似,除了所有重复和重叠的碎片和其他更多的通信碎片一样被丢弃。 reassemble tcpTCP连接状态标准化。当使用了 scrub reassemble tcp时,方向(进/出)不用说明,会执行下面的标准化过程: 连接双方都不允许减少它们的IP TTL值。这样做是为了防止攻击者发送数据包到防火墙,影响防火墙保持的连接状态,使数据包在到达目的主机前就过期。所有数据包的TTL都为了这个连接加到了最大值。 用随机数字调整TCP数据包头中的 RFC1323 时间戳。这可以阻止窃听者推断主机在线的时间和猜测NAT网关后面有多少主机。
实例:
scrub in on fxp0 all fragment reassemble min-ttl 15 max-mss 1400 scrub in on fxp0 all no-df scrub on fxp0 all reassemble tcp
编辑本段 回目录
PF防火墙 - 锚定和命名规则集
简介
除了主要的规则集,PF还可以载入子规则 该网络的队列策略:
* 为Bob保留玩在线游戏的80Kbps下行带宽,以减少另外两人对他的影响,并且总带宽富余的情况下可以超出该限制。 * 交互的SSH和即时信息流量要有高于其他流量的优先级。 * DNS请求和反馈数据流要有第二高的优先级。 * 流出的TCP ACK 数据包的优先级要高于其他流出数据包的优先级。
下面是对应的策略(省略了其他部分策略,如rdr、nat等):
# enable queueing on the external interface to control traffic going to # the Internet. use the priq scheduler to control only priorities. set # the bandwidth to 610Kbps to get the best performance out of the TCP # ACK queue.
altq on fxp0 priq bandwidth 610Kb queue { std_out, ssh_im_out, dns_out, \ tcp_ack_out }
# define the parameters for the child queues. # std_out - the standard queue. any filter rule below that does not # explicitly specify a queue will have its traffic added # to this queue. # ssh_im_out - interactive SSH and various instant message traffic. # dns_out - DNS queries. # tcp_ack_out - TCP ACK packets with no data payload.
queue std_out priq(default) queue ssh_im_out priority 4 priq(red) queue dns_out priority 5 queue tcp_ack_out priority 6
# enable queueing on the internal interface to control traffic coming in # from the Internet. use the cbq scheduler to control bandwidth. max # bandwidth is 2Mbps.
altq on dc0 cbq bandwidth 2Mb queue { std_in, ssh_im_in, dns_in, bob_in }
# define the parameters for the child queues. # std_in - the standard queue. any filter rule below that does not # explicitly specify a queue will have its traffic added # to this queue. # ssh_im_in - interactive SSH and various instant message traffic. # dns_in - DNS replies. # bob_in - bandwidth reserved for Bob‘s workstation. allow him to # borrow.
queue std_in cbq(default) queue ssh_im_in priority 4 queue dns_in priority 5 queue bob_in bandwidth 80Kb cbq(borrow)
# ... in the filtering section of pf.conf ...
alice = "192.168.0.2" bob = "192.168.0.3" charlie = "192.168.0.4" local_net = "192.168.0.0/24" ssh_ports = "{ 22 2022 }" im_ports = "{ 1863 5190 5222 }"
# filter rules for fxp0 inbound block in on fxp0 all
# filter rules for fxp0 outbound block out on fxp0 all pass out on fxp0 inet proto tcp from (fxp0) to any flags S/SA \ keep state queue(std_out, tcp_ack_out) pass out on fxp0 inet proto { udp icmp } from (fxp0) to any keep state pass out on fxp0 inet proto { tcp udp } from (fxp0) to any port domain \ keep state queue dns_out pass out on fxp0 inet proto tcp from (fxp0) to any port $ssh_ports \ flags S/SA keep state queue(std_out, ssh_im_out) pass out on fxp0 inet proto tcp from (fxp0) to any port $im_ports \ flags S/SA keep state queue(ssh_im_out, tcp_ack_out)
# filter rules for dc0 inbound block in on dc0 all pass in on dc0 from $local_net
# filter rules for dc0 outbound block out on dc0 all pass out on dc0 from any to $local_net pass out on dc0 proto { tcp udp } from any port domain to $local_net \ queue dns_in pass out on dc0 proto tcp from any port $ssh_ports to $local_net \ queue(std_in, ssh_im_in) pass out on dc0 proto tcp from any port $im_ports to $local_net \ queue ssh_im_in pass out on dc0 from any to $bob queue bob_in
实例 #2: 公司网络
( IT Dept ) [ Boss‘s PC ] | | T1 -- ---- ----- ---------- dc0 [ OpenBSD ] fxp0 -------- ( Internet ) | fxp1 [ COMP1 ] [ WWW ] / | / -- ----------‘
这个例子中OpenBSD作为公司网络的防火墙,公司内部在DMZ区运行了WWW服务器,用户通过FTP上传他们的网站。IT部门有自己的子网,老板的电脑主要用来收发电子邮件和网页冲浪。防火墙通过1.5Mbps双向带宽的T1电路连接因特网,其他网段均使用快速以太网(100Mbps)。
实现上述要求的策略如下:
* 限制WWW服务器到因特网之间的双向流量――500Kbps。 * WWW服务器和内部网络之间没有流量限制。 * 赋予WWW服务器和因特网间的流量高于其他流量的优先级(例如FTP上传流量)。 * 为IT部门保留500Kbps的带宽使他们可以下载到最新的软件,同时如果总带宽富余,他们可以借用。 * 为老板访问因特网的流量赋予比其他访问因特网流量高的优先级。
下面是对应的策略(省略了其他部分策略,如rdr、nat等):
# enable queueing on the external interface to queue packets going out # to the Internet. use the cbq scheduler so that the bandwidth use of # each queue can be controlled. the max outgoing bandwidth is 1.5Mbps.
altq on fxp0 cbq bandwidth 1.5Mb queue { std_ext, www_ext, boss_ext }
# define the parameters for the child queues. # std_ext - the standard queue. also the default queue for # outgoing traffic on fxp0. # www_ext - container queue for WWW server queues. limit to # 500Kbps. # www_ext_http - http traffic from the WWW server # www_ext_misc - all non-http traffic from the WWW server # boss_ext - traffic coming from the boss‘s computer
queue std_ext cbq(default) queue www_ext bandwidth 500Kb { www_ext_http, www_ext_misc } queue www_ext_http priority 3 cbq(red) queue www_ext_misc priority 1 queue boss_ext priority 3
# enable queueing on the internal interface to control traffic coming # from the Internet or the DMZ. use the cbq scheduler to control the # bandwidth of each queue. bandwidth on this interface is set to the # maximum. traffic coming from the DMZ will be able to use all of this # bandwidth while traffic coming from the Internet will be limited to # 1.0Mbps (because 0.5Mbps (500Kbps) is being allocated to fxp1).
altq on dc0 cbq bandwidth 100% queue { net_int, www_int }
# define the parameters for the child queues. # net_int - container queue for traffic from the Internet. bandwidth # is 1.0Mbps. # std_int - the standard queue. also the default queue for outgoing # traffic on dc0. # it_int - traffic to the IT Dept network. # boss_int - traffic to the boss‘s PC. # www_int - traffic from the WWW server in the DMZ.
queue net_int bandwidth 1.0Mb { std_int, it_int, boss_int } queue std_int cbq(default) queue it_int bandwidth 500Kb cbq(borrow) queue boss_int priority 3 queue www_int cbq(red)
# enable queueing on the DMZ interface to control traffic destined for # the WWW server. cbq will be used on this interface since detailed # control of bandwidth is necessary. bandwidth on this interface is set # to the maximum. traffic from the internal network will be able to use # all of this bandwidth while traffic from the Internet will be limited # to 500Kbps.
altq on fxp1 cbq bandwidth 100% queue { internal_dmz, net_dmz }
# define the parameters for the child queues. # internal_dmz - traffic from the internal network. # net_dmz - container queue for traffic from the Internet. # net_dmz_http - http traffic. # net_dmz_misc - all non-http traffic. this is also the default queue.
queue internal_dmz # no special settings needed queue net_dmz bandwidth 500Kb { net_dmz_http, net_dmz_misc } queue net_dmz_http priority 3 cbq(red) queue net_dmz_misc priority 1 cbq(default)
# ... in the filtering section of pf.conf ...
main_net = "192.168.0.0/24" it_net = "192.168.1.0/24" int_nets = "{ 192.168.0.0/24, 192.168.1.0/24 }" dmz_net = "10.0.0.0/24"
boss = "192.168.0.200" wwwserv = "10.0.0.100"
# default deny block on { fxp0, fxp1, dc0 } all
# filter rules for fxp0 inbound pass in on fxp0 proto tcp from any to $wwwserv port { 21, \ > 49151 } flags S/SA keep state queue www_ext_misc pass in on fxp0 proto tcp from any to $wwwserv port 80 \ flags S/SA keep state queue www_ext_http
# filter rules for fxp0 outbound pass out on fxp0 from $int_nets to any keep state pass out on fxp0 from $boss to any keep state queue boss_ext
# filter rules for dc0 inbound pass in on dc0 from $int_nets to any keep state pass in on dc0 from $it_net to any queue it_int pass in on dc0 from $boss to any queue boss_int pass in on dc0 proto tcp from $int_nets to $wwwserv port { 21, 80, \ > 49151 } flags S/SA keep state queue www_int
# filter rules for dc0 outbound pass out on dc0 from dc0 to $int_nets
# filter rules for fxp1 inbound pass in on fxp1 proto { tcp, udp } from $wwwserv to any port 53 \ keep state
# filter rules for fxp1 outbound pass out on fxp1 proto tcp from any to $wwwserv port { 21, \ > 49151 } flags S/SA keep state queue net_dmz_misc pass out on fxp1 proto tcp from any to $wwwserv port 80 \ flags S/SA keep state queue net_dmz_http pass out on fxp1 proto tcp from $int_nets to $wwwserv port { 80, \ 21, > 49151 } flags S/SA keep state queue internal_dmz
编辑本段 回目录
PF防火墙 - 地址池和负载均衡
简介
地址池是提供2个以上的地址供一组用户共享的。地址池可以是rdr规则中的重定向地址;可以是nat规则中的转换地址;也可以是route-to, reply-to, 和 dup-to filter选项中的目的地址。
有4种使用地址池的方法:
* bitmask- 截取被修改地址(nat规则的源地址;rdr规则的目标地址)的最后部分和地址池地址的网络部分组合。例如:如果地址池是192.0.2.1/24,而被修改地址是10.0.0.50,则结果地址是192.0.2.50。如果地址池是192.0.2.1/25,而被修改地址是10.0.0.130,这结果地址是192.0.2.2。 * random- 从地址池中随机选择地址. * source-hash- 使用源地址 hash 来确定使用地址池中的哪个地址。这个方法保证给定的源地址总是被映射到同一个地址池。Hash算法的种子可以在source-hash关键字后通过16进制字符或者字符串来指定。默认情况下,pfctl(8)在规则集装入时会随机产生种子。 * round-robin- 在地址池中按顺序循环,这是默认方法,也是表中定义的地址池唯一的方法。
除了round-robin方法,地址池的地址必须表达成CIDR(Classless Inter-Domain Routing )的网络地址族。round-robin 方法可以接受多个使用列表和表的单独地址。
sticky-address 选项可以在 random 和round-robin 池类型中使用,保证特定的源地址始终映射到同样的重定向地址。
NAT 地址池
地址池在NAT规则中可以被用做转换地址。连接的源地址会被转换成使用指定的方法从地址池中选择的地址。这对于PF负载一个非常大的网络的NAT会非常有用。由于经过NAT的连接对每个地址是有限的,增加附加的转换地址允许NAT网关增大服务的用户数量。
在这个例子中,2个地址被用来做输出数据包的转换地址。对于每一个输出的连接,PF按照顺序循环使用地址。
nat on $ext_if inet from any to any -> { 192.0.2.5, 192.0.2.10 }
这个方法的一个缺点是成功建立连接的同一个内部地址不会总是转换为同一个外部地址。这会导致冲突,例如:浏览根据用户的ip地址跟踪登录的用户的web站点。一个可选择的替代方法是使用source-hash 方法,以便每一个内部地址总是被转换为同样的外部地址。,要实现这个方法,地址池必须是CIDR网络地址。
nat on $ext_if inet from any to any -> 192.0.2.4/31 source-hash
这条NAT规则使用地址池192.0.2.4/31 (192.0.2.4 - 192.0.2.5)做为输出数据包的转换地址。每一个内部地址会被转换为同样的外部地址,由于source-hash关键字的缘故。
外来连接负载均衡
地址池也可以用来进行外来连接负载均衡。例如,外来的web服务器连接可以分配到服务器群。
web_servers = "{ 10.0.0.10, 10.0.0.11, 10.0.0.13 }"
rdr on $ext_if proto tcp from any to any port 80 -> $web_servers \ round-robin sticky-address
成功的连接将按照顺序重定向到web服务器,从同一个源到来的连接发送到同一个服务器。这个sticky connection会和指向这个连接的状态一起存在。如果状态过期,sticky connection也过期。那个主机的更多连接被重定向到按顺序的下一个web服务器。
输出流量负载均衡
地址池可以和route-to过滤选项联合使用,在多路径路由协议(例如BGP4)不可用是负载均衡2个或者多个因特网连接。通过对round-robin地址池使用route-to,输出连接可以平均分配到多个输出路径。
需要收集的附加的信息是邻近的因特网路由器IP地址。这要加入到route-to选项后来控制输入数据包的目的地址。
下面的例子通过2条到因特网的连接平衡输出流量:
lan_net = "192.168.0.0/24" int_if = "dc0" ext_if1 = "fxp0" ext_if2 = "fxp1" ext_gw1 = "68.146.224.1" ext_gw2 = "142.59.76.1"
pass in on $int_if route-to \ { ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin \ from $lan_net to any keep state
route-to 选项用来在收到流量的内部接口上指定平衡的流量经过各自的网关到输出的网络接口。注意route-to 选项必须在每个需要均衡的过滤规则上出现。返回的数据包会路由到它们出去时的外部接口(这是由ISP做的),然后正常路由回内部网络。
要保证带有属于$ext_if1源地址的数据包总是路由到$ext_gw1($ext_if2 和 $ext_gw2也是同样的),下面2行必须包括在规则集中:
pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 \ to any pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 \ to any
最后,NAT也可以使用在输出接口中:
nat on $ext_if1 from $lan_net to any -> ($ext_if1) nat on $ext_if2 from $lan_net to any -> ($ext_if2)
一个完整的输出负载均衡的例子应该是这个样子:
lan_net = "192.168.0.0/24" int_if = "dc0" ext_if1 = "fxp0" ext_if2 = "fxp1" ext_gw1 = "68.146.224.1" ext_gw2 = "142.59.76.1"
# nat outgoing connections on each internet interface nat on $ext_if1 from $lan_net to any -> ($ext_if1) nat on $ext_if2 from $lan_net to any -> ($ext_if2)
# default deny block in from any to any block out from any to any
# pass all outgoing packets on internal interface pass out on $int_if from any to $lan_net # pass in quick any packets destined for the gateway itself pass in quick on $int_if from $lan_net to $int_if # load balance outgoing tcp traffic from internal network. pass in on $int_if route-to \ { ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin \ proto tcp from $lan_net to any flags S/SA modulate state # load balance outgoing udp and icmp traffic from internal network pass in on $int_if route-to \ { ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin \ proto { udp, icmp } from $lan_net to any keep state
# general "pass out" rules for external interfaces pass out on $ext_if1 proto tcp from any to any flags S/SA modulate state pass out on $ext_if1 proto { udp, icmp } from any to any keep state pass out on $ext_if2 proto tcp from any to any flags S/SA modulate state pass out on $ext_if2 proto { udp, icmp } from any to any keep state
# route packets from any IPs on $ext_if1 to $ext_gw1 and the same for # $ext_if2 and $ext_gw2 pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to any pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to any
编辑本段 回目录
PF防火墙 - 数据包标记
简介
数据包标记是给数据包打内部标记的方法,以后可以在过滤和转换规则中使用。使用标记,有可能做这样的事情,比如在接口间产生信任关系,或者确定数据包是否已经经过了转换规则处理。也可能从基于规则的过滤中移出,开始执行基于策略的过滤。
给数据包打标记
要给数据包打标记,使用tag 关键字:
pass in on $int_if all tag INTERNAL_NET keep state
标记 INTERNAL_NET 会增加到任何匹配上述规则的数据包中。 注意keep state的使用; keep state (或者 modulate state/synproxy state) 在标记数据包通过的规则中使用。
标记也可以通过宏来打,比如:
name = "INTERNAL_NET" pass in on $int_if all tag $name keep state
有一组预先定义的宏也可以被使用。
* $if - 接口 * $srcaddr - 源 IP 地址 * $dstaddr - 目的 IP 地址 * $srcport - 源端口 * $dstport - 目的端口 * $proto - 协议 * $nr - 规则号
这些宏在规则集装入时扩展,而不是运行时。
标记遵循以下规则:
* 标记是粘性的。一旦一个标记被匹配的规则打到一个数据包,就不能被删除。但它可以被不同的标记替换。 * 由于标记的粘性,打了标记的数据包会一直保持,即使所有的规则都没有使用这个标记。 * 一个数据包一次最多只能打一个标记。 * 标记是内部标识符,标记不会被送到网上。
看看下面的例子:
(1) pass in on $int_if tag INT_NET keep state (2) pass in quick on $int_if proto tcp to port 80 tag \ INT_NET_HTTP keep state (3) pass in quick on $int_if from 192.168.1.5 keep state
* 按照规则1,$int_if 接口上收到的数据包会打上INT_NET 标记。 * $int_if 接口上收到的目标端口80的数据包根据规则1首先打上INT_NET 标记,然后根据规则2,被INT_NET_HTTP 标记替代。 * $int_if 接口上收到的来自192.168.1.5的数据包根据规则3会方向,由于这是最终匹配规则,因此如果它们的目标端口是80,则标记是INT_NET_HTTP ,否则标记是INT_NET 。
标记除了适用于过滤规则以外, nat, rdr, binat转换规则也可以用tag关键字使用标记。
检查数据包标记
要检查先前已经打的标记,可以使用tagged关键字:
pass out on $ext_if tagged INT_NET keep state
在$ext_if输出的数据包为了匹配上述规则必须打上INT_NET标记。反转匹配也可以使用!操作:
pass out on $ext_if tagged ! WIFI_NET keep state
策略过滤
过滤策略提供了编写过滤规则集的不同方法。定义的策略设定规则,说明哪种流量放行,哪种流量阻塞。数据包被基于传统的标准如源/目的IP地址,协议等等分配到不同的策略。例如,检查下面的防火墙策略:
* 自内部LAN到DMZ的流量是允许的 (LAN_DMZ)。 * 自因特网到DMZ的服务器流量是允许的。 (INET_DMZ) * 自因特网被重定向到spamd(8)是允许的 (SPAMD) * 其他所有流量阻塞。
注意策略是如何覆盖所有通过防火墙的流量的。括号里面的项目指示这个策略项目将使用的标记。
需要过滤和转换规则来把数据包分配到不同的策略。
rdr on $ext_if proto tcp from to port smtp \ tag SPAMD -> 127.0.0.1 port 8025
block all pass in on $int_if from $int_net tag LAN_INET keep state pass in on $int_if from $int_net to $dmz_net tag LAN_DMZ keep state pass in on $ext_if proto tcp to $www_server port 80 tag INET_DMZ keep state
现在要设置定义策略的规则。
pass in quick on $ext_if tagged SPAMD keep state pass out quick on $ext_if tagged LAN_INET keep state pass out quick on $dmz_if tagged LAN_DMZ keep state pass out quick on $dmz_if tagged INET_DMZ keep state
现在要建立整个规则集,修改分类规则。例如,如果pop3/SMTP服务器增加到了DMZ区,就需要增加针对POP3和SMTP流量的分类,如下:
mail_server = "192.168.0.10" ... pass in on $ext_if proto tcp to $mail_server port { smtp, pop3 } \ tag INET_DMZ keep state
Email 流量会作为INET-DMZ策略的条目被放行。t 完整的规则:
# macros int_if = "dc0" dmz_if = "dc1" ext_if = "ep0" int_net = "10.0.0.0/24" dmz_net = "192.168.0.0/24" www_server = "192.168.0.5" mail_server = "192.168.0.10"
table persist file "/etc/spammers"
# classification -- classify packets based on the defined firewall # policy. rdr on $ext_if proto tcp from to port smtp \ tag SPAMD -> 127.0.0.1 port 8025
block all pass in on $int_if from $int_net tag LAN_INET keep state pass in on $int_if from $int_net to $dmz_net tag LAN_DMZ keep state pass in on $ext_if proto tcp to $www_server port 80 tag INET_DMZ keep state pass in on $ext_if proto tcp to $mail_server port { smtp, pop3 } \ tag INET_DMZ keep state
# policy enforcement -- pass/block based on the defined firewall policy. pass in quick on $ext_if tagged SPAMD keep state pass out quick on $ext_if tagged LAN_INET keep state pass out quick on $dmz_if tagged LAN_DMZ keep state pass out quick on $dmz_if tagged INET_DMZ keep state
标记以太网帧
打标记可以在以太网级别进行,如果执行标记/过滤的机器同时做为网桥。通过创建使用tag关键字的网桥过滤规则,PF可以建立基于源/目的MAC地址的过滤规则。网桥规则可以由brconfig(8)命令产生,例如:
# brconfig bridge0 rule pass in on fxp0 src 0:de:ad:be:ef:0 \ tag USER1
然后在 pf.conf文件中:
pass in on fxp0 tagged USER1
编辑本段 回目录
PF防火墙 - 日志
简介
PF的包日志是由pflogd完成的,它通过监听pflog0接口然后将包以tcpdump二进制格式写入日志文件(一般在/val/log/pflog)。过滤规则定义的日志和log-all关键字所定义的日志都是以这种方式记录的。
读取日志文件
由pflogd生成的二进制格式日志文件不能通过文本编辑器读取,必须使用Tcpdump来查看日志。
使用如下格式查看日志信息:
# tcpdump -n -e -ttt -r /var/log/pflog
使用tcpdump( 查看日志文件并不是实时的,若要实时查询日志信息需加上pflog0参数:
# tcpdump -n -e -ttt -i pflog0
注意:当查看日志时需要特别注意tcpdump的详细协议解码(通过在命令行增加-v参数实现)。 Tcpdump的详细协议解码器并不具备完美的安全历史,至少在理论上是这样。日志记录设备所记载的部分包信息可能会引发延时攻击,因此推荐在查询日志文件信息之前先将该日志文件从防火墙上移走。
另外需要注意的是对日志文件的安全访问。默认情况下,pflogd 将在日志文件中记录96字节的包信息。访问日志文件将提供访问部分敏感包信息的途径(就像telnet(1)或者ftp(1)的用户名和密码)。
导出日志
由于pflogd以tcpdump二进制格式记录日志信息,因此当回顾这些日志时可以使用tcpdump的很多特点。例如,只查看与特定端口匹配的包:
# tcpdump -n -e -ttt -r /var/log/pflog port 80
甚至可以限定具体的主机和端口:
# tcpdump -n -e -ttt -r /var/log/pflog port 80 and host 192.168.1.3
同样的方法可以应用到直接从pflog0接口读取的信息:
# tcpdump -n -e -ttt -i pflog0 host 192.168.4.2
注意这与包被记录到pflogd日志文件不相冲突;上述语句只以包被记录的形式显示。
除了使用标准的tcpdump(8)过滤规则外,OpenBSD的tcpdump过滤语言为读取pflogd而被扩展:
* ip -IPv4版本地址。 * ip6 - IPv6版本地址。 * on int - 包通过int接口。 * ifname int - 与 on int相同. * rulenum num - 包匹配的过滤规则编号为num。 * action act - 对包的操作。可能是pass(通过)或者block(阻断)。 * reason res - 执行对包操作的原因。可能的原因是match(匹配), bad-offset, fragment, short, normalize(规格化), memory(内存)。 * inbound -入栈包。 * outbound - 出栈包。
举例:
# tcpdump -n -e -ttt -i pflog0 inbound and action block and on wi0
这将以实时方式显示被wi0接口阻断的入栈包的日志信息。
通过Syslog记录日志
很多情况下需要将防火墙的日志记录以ASCII代码格式存储,或者(同时)把这些日志存到远程的日志服务器上。这些可以通过两个小的脚本文件实现,是对 openbsd配置文件和syslogd,日志守护进程的少许修改。Syslogd进程以ASCII格式存储日志,同时可以将日志存储到远程日志服务器。
首先必须建立一个用户,pflogger,使用 /sbin/nologin shell.最简单的建立用户的方法是使用adduser(8)。
完成后建立如下两个脚本:
/etc/pflogrotate FILE=/home/pflogger/pflog5min.$(date " %Y%m%d%H%M") kill -ALRM $(cat /var/run/pflogd.pid) if [ $(ls -l /var/log/pflog | cut -d " " -f -gt 24 ]; then mv /var/log/pflog $FILE chown pflogger $FILE kill -HUP $(cat /var/run/pflogd.pid) fi
/home/pflogger/pfl2sysl for logfile in /home/pflogger/pflog5min* ; do tcpdump -n -e -ttt -r $logfile | logger -t pf -p local0.info rm $logfile done
编辑root的cron 任务:
# crontab -u root -e
增加如下两行:
# rotate pf log file every 5 minutes 0-59/5 * * * * /bin/sh /etc/pflogrotate
为用户pflogger建立一个cron任务:
# crontab -u pflogger -e
增加如下两行:
# feed rotated pflog file(s) to syslog 0-59/5 * * * * /bin/sh /home/pflogger/pfl2sysl
将下行增加到 /etc/syslog.conf:
local0.info /var/log/pflog.txt
如果需要日志记录到远程日志服务器,增加:
local0.info @syslogger
确定主机syslogger已在hosts(5)中定义。
建立文件 /var/log/pflog.txt 使 syslog 可以向该文件写入日志:
# touch /var/log/pflog.txt
重启syslogd使变化生效:
# kill -HUP $(cat /var/run/syslog.pid)
所有符合标准的包将被写入/var/log/pflog.txt. 如果增加了第二行,这些信息也将被存入远程日志服务器syslogger。
脚本 /etc/pflogrotate 将执行,然后删除 /var/log/pflog ,因此 rotation of pflog by newsyslog(Cool 不再必需可以被禁用。然而, /var/log/pflog.txt 替代 /var/log/pflog and rotation of it 要被启用。 改变 /etc/newsyslog.conf 如下:
#/var/log/pflog 600 3 250 * ZB /var/run/pflogd.pid /var/log/pflog.txt 600 7 * 24
PF 将日志以ASCII格式记录到/var/log/pflog.txt. 如果这样配置 /etc/syslog.conf, 系统将把日志存到远程服务器。存储过程不会马上发生,但是会在符合条件的包出现在文件中前5-6分钟实现。
编辑本段 回目录
PF防火墙 - 性能
“PF可以处理多少带宽?” “我需要多少台计算机处理因特网连接?”
这个问题没有简单的答案。对于一些应用程序来说,一台486/66主机,带有2个比较好的ISA网卡在做过滤和NAT时接近5Mbps,但是对于其他应用程序,一个更快的计算机加上更有效的PCI网卡也会显得能力不足。真正的问题不是每秒处理的位数而是每秒处理的包数和规则集的复杂程度。
体现PF性能的几个参数:
* 每秒处理包的数量.一个1500字节的包和一个只有1个字节的包所需要的处理过程的数目几乎是一样的。每秒处理包的数量标志着状态表和过滤规则集在每秒内被评估的次数 ,标志着一个系统最有效的需求(在没有匹配的情况下)。
* 系统总线性能. ISA 总线最大带宽 8MB/秒, 当处理器访问它时, 它必须降速到80286的有效速度,不管处理器的真实处理速度如何,PCI总线有更有效的带宽,与处理器的冲突更小。
* 网卡的效率.一些网卡的工作效率要高于其他网卡。 基于Realtek 8139的网卡性能较低,而基于 Intel 21143 的网卡性能较好。为了取得更好的性能,建议使用千兆网卡,尽管所连接的网络不是千兆网,这些千兆网卡拥有高级的缓存,可以大幅提高性能。
* 规则集的设计和复杂性。 规则越复杂越慢。越多的包通过keep和quick方式过滤,性能越好。对每个包的策略越多,性能越差。
* 值得一提:CPU 和内存。由于PF是基于内核的进程,它不需要swap空间。所以,如果你有足够的内存,它将运行很好,如果没有,将受影响。不需要太大量的内存。 32MB内存对小型办公室或者家庭应用足够,300MHz的cpu如果配置好网卡和规则集,足够满足要求。
人们经常询问PF的基准点。唯一的基准是在一个环境下系统的性能。不考虑环境因素将影响所设计的防火墙的系统性能。
PF 曾经在非常大流量的系统中工作,同时PF的开发者也是它的忠实用户。
编辑本段 回目录
PF防火墙 - 研究 FTP
FTP 模式
FTP是一种协议,它可以追溯到因特网发展初期,那时的因特网规模小,联网的计算机彼此友好,过滤和严格安全性在那时不是必须的。FTP设计之初就没有考虑包过滤、穿透防火墙和NAT。
FTP的工作模式分为被动(passive)和主动(active)两种。通常这两种选择被用来确定哪边有防火墙问题。实际上,为了方便用户应该全部支持这两种模式。
在active模式下,当用户访问远程FTP服务器并请求一个文件信息时,那台FTP服务器将与该用户建立一个新的连接用来传输请求的数据,这被称为数据连接。具体过程为:客户端随机选择一个端口号,在该端口监听的同时将端口号传给服务器,由服务器向客户端的该端口发起连接请求,然后传递数据。在 NAT后的用户访问FTP服务器的时候会出现问题,由于NAT的工作机制,服务器将向NAT网关的外部地址的所选端口发起连接,NAT网关收到该信息后将在自己的状态表中查找该端口对应的内部主机,由于状态表中不存在这样的记录,因此该包被丢弃,导致无法建立连接。
在passive模式下(OpenBSD的ftp客户端默认模式),由客户端请求服务器随机选择一个端口并在此端口监听,服务器通知客户端它所选择的端口号,等待客户端连接。不幸的是,ftp服务器前的防火墙可能会阻断客户端发往服务器的请求信息。OpenBSD的ftp(1)默认使用 passive模式;要强制改为active模式,使用-A参数,或者在“ftp>”提示符下使用命令“passive off”关闭 passive模式。
工作在防火墙之后的FTP客户端
如前所述,FTP对NAT和防火墙支持不好。
包过滤机制通过将FTP数据包重定向到一个FTP代理服务器解决这一问题。这一过程将引导FTP数据包通过NAT网关/防火墙。OpenBSD和PF使用的FTP代理是ftp-proxy(8),可以通过在pf.conf中的NAT章节增加下列信息激活该代理:
rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 \ port 8021
这条语句的解释为:在内部接口上的ftp数据包被重定向到本机的8021端口
显然该代理服务器应该已在OpenBSD中启动并运行。配置方法为在/etc/inetd.conf中增加下列信息:
127.0.0.1:8021 stream tcp nowait root /usr/libexec/ftp-proxy \ ftp-proxy
重启系统或者通过下列命令发送一个‘HUP’标记来生效:
kill -HUP `cat /var/run/inetd.pid`
ftp代理在8021端口监听,上面的rdr语句也是将数据包转发到这一端口。这一端口号是可选的,因为8021端口没有被其他应用程序占用,因此不失为一个好的选择。
请注意ftp-proxy(8)是用来帮助位于PF过滤器后的ftp客户端传递信息;并不用于PF过滤器后的ftp服务器。
PF“自保护”FTP服务器
当PF运行在一个FTP服务器上,而不是单独的一台防火墙。这种情况下处理passive模式的FTP连接请求时FTP服务器将随机取一个较大的 TCP端口接收数据。默认情况下OpenBSD的本地FTP服务器ftpd(8)使用49152~65535范围内的端口,显然,必须要有对应的过滤规则放行这些端口的数据:
pass in on $ext_if proto tcp from any to any port 21 keep state pass in on $ext_if proto tcp from any to any port > 49151 \ keep state
如果需要可以调整上述端口范围。在OpenBSD的ftpd(8)环境下,可以通过sysctl(8)进行调整 net.inet.ip.porthifirst 和net.inet.ip.porthilast。
使用NAT外部 PF防火墙保护FTP服务器
这种情况下,防火墙必须将数据重定向到FTP服务器。为了讨论方便,我们假设该FTP服务器使用标准的OpenBSD ftpd(8),并使用默认端口范围。
这里有个例子
ftp_server = "10.0.3.21"
rdr on $ext_if proto tcp from any to any port 21 -> $ftp_server \ port 21 rdr on $ext_if proto tcp from any to any port 49152:65535 -> \ $ftp_server port 49152:65535
# in on $ext_if pass in quick on $ext_if proto tcp from any to $ftp_server \ port 21 keep state pass in quick on $ext_if proto tcp from any to $ftp_server \ port > 49151 keep state
# out on $int_if pass out quick on $int_if proto tcp from any to $ftp_server \ port 21 keep state pass out quick on $int_if proto tcp from any to $ftp_server \ port > 49151 keep state
FTP的更多信息过滤FTP和FTP如何工作的更多信息可以参考下面的白皮书。
编辑本段 回目录
PF防火墙 - 验证: 用Shell 进行网关验证
简介
Authpf(Cool是身份认证网关的用户shell。身份认证网关类似于普通网关,只不过用户必须在网关上通过身份验证后才能使用该网关。当用户 shell被设置为/usr/sbin/authpf时(例如,代替了ksh(1),csh(1)等),并且用户通过SSH登录,authpf将对pf (4)策略集做必要的修改以便该用户的数据包可以通过过滤器或者(和)使用NAT、重定向功能。一旦用户退出登录或者连接被断开,authpf将移除加载到该用户上的所有策略,同时关闭该用户打开的所有会话。因此,只有当用户保持着他的SSH会话进程时他才具备透过防火墙发送数据包的能力。
Authpf通过向附加到锚点的命名策略集增加策略来改变pf(4)的策略集。每次用户进行身份验证,authpf建立一个新的命名策略集,并将已经配置好的filter、nat、binat和rdr规则加载上去。被authpf所加载的策略可以被配置为针对单独的一个用户相关或者针对总体。
Authpf可以应用在:
* 在允许用户访问因特网之前进行身份验证。 * 赋予特殊用户访问受限网络的权利,例如管理员。 * 只允许特定的无线网络用户访问特定的网络。 * 允许公司员工在任何时候访问公司网络,而公司之外的用户不能访问,并可以将这些用户重定向到特定的基于用户名的资源(例如他们自己的桌面)。 * 在类似图书馆这样的地方通过PF限制guest用户对因特网的访问。Authpf可以用来向已注册用户开放完全的因特网连接。
Authpf通过syslogd(8)记录每一个成功通过身份验证用户的用户名、IP地址、开始结束时间。通过这些信息,管理员可以确定谁在何时登陆,也使得用户对其网络流量负责。
配置
配置authpf的基本步骤大致描述如下。详细的信息请查看man手册。
将authpf连入主策略集
通过使用锚点策略将authpf连入主策略集:
nat-anchor authpf rdr-anchor authpf binat-anchor authpf anchor authpf
锚点策略放入策略集的位置就是PF中断执行主策略集转为执行authpf策略的位置。上述4个锚点策略并不需要全部存在,例如,当authpf没有被设置加载任何nat策略时,nat-anchor策略可被省略。
配置加载的策略
Authpf通过下面两个文件之一加载策略:
* /etc/authpf/users/$USER/authpf.rules * /etc/authpf/authpf.rules
第一个文件包含只有当用户$USER(将被替换为具体的用户名)登录时才被加载的策略。当特殊用户(例如管理员)需要一系列不同于其他默认用户的策略集时可以使用每用户策略配置。第二个文件包含没定义自己的authpf.rules文件的用户所默认加载的策略。如果用户定义的文件存在,将覆盖默认文件。这两个文件至少存在其一,否则authpf将不会工作。
过滤器和传输策略与其他的PF策略集语法一样,但有一点不同:authpf允许使用预先定义的宏:
* $user_ip �C 登录用户的IP地址 * $user_id �C 登录用户的用户名
推荐使用宏$user_ip,只赋予通过身份验证的计算机透过防火墙的权限。
访问控制列表
可以通过在/etc/authpf/banned/目录下建立以用户名命名的文件来阻止该用户使用authpf。文件的内容将在authpf断开与该用户的连接之前显示给他,这为通知该用户被禁止访问的原因并告知他解决问题联系人提供了一个便捷的途径。
相反,有可能只允许特定的用户访问,这时可以将这些用户的用户名写入/etc/authpf/authpf.allow文件。如果该文件不存在或者文件中输入了“*”,则authpf将允许任何成功通过SSH登录的用户进行访问(没有被明确禁止的用户)。
如果authpf不能断定一个用户名是被允许还是禁止,它将打印一个摘要信息并断开该用户的连接。明确禁止将会使明确允许失效。
将authpf配置为用户shell
authpf必须作为用户的登录shell才能正常工作。当用户成功通过sshd(8)登录后,authpf将被作为用户的shell执行。它将检查该用户是否有权使用authpf,并从适当的文件中加载策略,等等。
有两种途径将authpf设置为用户shell:
1.为每个用户手动使用chsh(1), vipw(Cool, useradd(Cool, usermod(Cool,等。 2.通过把一些用户分配到一个登录类,在文件/etc/login.conf中改变这个登录类的shell属性
查看登陆者
一旦用户成功登录,并且authpf调整了PF的策略,authpf将改变它的进程名以显示登录者的用户名和IP地址:
# ps -ax | grep authpf 23664 p0 Is 0:00.11 -authpf: charlie@192.168 (authpf)
在这里用户chalie从IP地址为192.168.1.3的主机登录。用户可以通过向authpf进程发送SIGTERM信号退出登录。Authpf也将移除加载到该用户上的策略并关闭任何该用户打开的会话连接。
# kill -TERM 23664
实例
OpenBSD网关通过authpf对一个大型校园无线网的用户进行身份验证。一旦某个用户验证通过,假设他不在禁用列表中,他将被允许SSH并访问网页(包括安全网站https),也可以访问该校园的任一个DNS服务器。
文件 /etc/authpf/authpf.rules包含下列策略:
wifi_if = "wi0" dns_servers = "{ 10.0.1.56, 10.0.2.56 }"
pass in quick on $wifi_if proto udp from $user_ip to $dns_servers \ port domain keep state pass in quick on $wifi_if proto tcp from $user_ip to port { ssh, http, \ https } flags S/SA keep state
管理员charlie除了网页冲浪和使用SSH外还需要访问校园网的SMTP和POP3服务器。下列策略被配置在/etc/authpf/users/charlie/authpf.rules 中:
wifi_if = "wi0" smtp_server = "10.0.1.50" pop3_server = "10.0.1.51" dns_servers = "{ 10.0.1.56, 10.0.2.56 }"
pass in quick on $wifi_if proto udp from $user_ip to $dns_servers \ port domain keep state pass in quick on $wifi_if proto tcp from $user_ip to $smtp_server \ port smtp flags S/SA keep state pass in quick on $wifi_if proto tcp from $user_ip to $pop3_server \ port pop3 flags S/SA keep state pass in quick on $wifi_if proto tcp from $user_ip to port { ssh, http, \ https } flags S/SA keep state
定义在/etc/pf.conf中的主策略集配置如下:
# macros wifi_if = "wi0" ext_if = "fxp0"
scrub in all
# filter block drop all
pass out quick on $ext_if proto tcp from $wifi_if:network flags S/SA \ modulate state pass out quick on $ext_if proto { udp, icmp } from $wifi_if:network \ keep state
pass in quick on $wifi_if proto tcp from $wifi_if:network to $wifi_if \ port ssh flags S/SA keep state
anchor authpf in on $wifi_if
该策略集非常简单,作用如下:
* 阻断所有(默认拒绝)。 * 放行外部网卡接口上的来自无线网络并流向外部的TCP,UDP和ICMP数据包。 * 放行来自无线网络,目的地址为网关本身的SSH数据包。该策略是用户登录所必须的。 * 在无线网络接口上为流入数据建立锚点“authpf”。
设计主策略集的主导思想为:阻断任何包并允许尽可能小的数据流通过。在外部接口上流出数据包是允许的,但是默认否策略阻断了由无线接口进入的数据包。用户一旦通过验证,他们的数据包被允许通过无线接口进入并穿过网关到达其他网络。
编辑本段 回目录
PF防火墙 - 实例:家庭和小型办公室防火墙
概况
在这个例子中,PF作为防火墙和NAT网关运行在OpenBSD机器上,为家庭或办公室的小型网络提供服务。总的目标是向内部网提供因特网接入,允许从因特网到防火墙的限制访问。下面将详细描述:
网络
网络配置如下:
[ COMP1 ] [ COMP3 ] | | ADSL --- ------ ----- ------- fxp0 [ OpenBSD ] ep0 -------- ( 因特网 ) | [ COMP2 ]
内部网有若干机器,图中只划出了3台,这些机器除了COMP3之外主要进行网页冲浪、电子邮件、聊天等;COMP3运行一个小型web服务器。内部网使用192.168.0.0/24网段。
OpenBSD网关运行在 Pentium 100计算机上,装有两块网卡:一个3com 3c509B(ep0),另一个 Intel EtherExpress Pro/100(fxp0)。该网关通过ADSL连接到因特网,同时通过NAT向内网共享因特网连接。外部网卡的 IP地址动态分配。
目标
* 向内部网络的每台计算机提供无限制的因特网接入。 * 启用一条“默认拒绝”策略。 * 允许下列来自因特网的请求访问防火墙: SSH (TCP 端口 22): 用来远程维护防火墙。 Auth/Ident (TCP 端口 113): SMTP和IRC服务用到的端口。 ICMP Echo Requests: ping(8)用到的ICMP包类型。 * 重定向访问80端口(访问web的请求)的请求到计算机COMP3,同时,允许指向COMP3计算机的80端口的数据流过防火墙。 * 记录外部网卡接口上的过滤日志。 * 默认为阻断的包返回一个 TCP RST 或者 ICMP Unreachable 信息。 * 尽量保持策略集简单并易于维护。
准备
这里假设作为网关的OpenBSD主机已经配置完成,包括IP网络配置,因特网连接和设置net.inet.ip.forwarding 的值为1。
规则集
下面将逐步建立策略集以满足上诉要求。
宏
定义下列宏以增强策略集的可维护性和可读性:
int_if = "fxp0" ext_if = "ep0"
tcp_services = "{ 22, 113 }" icmp_types = "echoreq"
priv_nets = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }"
comp3 = "192.168.0.3"
前两行定义了发生过滤的网络接口。第3、4行定义了向因特网开放的服务端口号(SSH和ident/auth)和允许访问防火墙的ICMP包类型。第5行定义了回送地址段和RFC1918定义的私有地址段。最后一行定义了主机COMP3的IP地址。
注意:如果ADSL接入因特网需要PPPoE,则过滤和NAT将发生在tun0接口上而不是ep0接口。
选项
下列两个选项用来设置阻断后的默认操作为反馈,并在外部接口设置开启日志记录:
set block-policy return set loginterface $ext_if
流量整修
没有理由不起用对所有进入防火墙的所有包进行规格化,因此只需要简单的一行:
scrub in all
NAT(网络地址转换)
为所有内部网启用NAT可以通过下列策略:
nat on $ext_if from $int_if:network to any -> ($ext_if)
由于外部网卡的IP地址是动态获得的,因此在外部网卡接口处增加小括号以使当IP地址发生变化时PF可以自适应。
重定向
第一个需要重定向策略的是ftp-proxy(8),只有这样内部网上的FTP客户端才可以访问因特网上的FTP服务器。
rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021
注意这条策略只捕获到21端口的数据包,如果用户通过其他端口访问FTP服务器,则在定义目的端口时需要使用list(列表),例如: from any to any port { 21, 2121 }。
第二个重定向策略捕获因特网上的用户访问防火墙80端口的数据包。用户试图访问网络的web服务器时将产生合法的访问该端口的数据包,这些连接请求需要重定向到主机COMP3:
rdr on $ext_if proto tcp from any to any port 80 -> $comp3
过滤规则
过滤规则第一行是默认否规则:
block all
这时没有任何数据包可以流过防火墙,甚至来自内部网络的数据包。下面的规则将逐个依据上面提到的目标开启防火墙上的虚拟接口。
每个Unix系统都有一个“loopback(回送)”接口,它是用于系统中应用程序间通信的虚拟网络接口。在OpenBSD中,回送接口是lo(4)。
pass quick on lo0 all
下一步,由RFC 1918定义的私有地址将在外部网卡接口的进和出方向被阻断。这些地址不应该出现在公网上,通过阻断这些地址可以保证防火墙不向外部网泄漏内网地址,同时也阻断了来自外部网中源地址为这些私有地址的数据包流入内网。
block drop in quick on $ext_if from $priv_nets to any block drop out quick on $ext_if from any to $priv_nets
这里block drop用来通知PF停止反馈TCP RST或者ICMP Unreachabel 数据包。因为RFC 1918规定的地址不会存在于因特网上,发往那些地址的数据包将没有意义。Quick 选项用来通知PF如果这条规则匹配则不再进行其他规则的匹配操作,来自或流向$ priv_nets的数据包将被立即丢弃。
现在将打开因特网上的一些服务所用到的端口:
pass in on $ext_if inet proto tcp from any to ($ext_if) \ port $tcp_services flags S/SA keep state
通过在宏$tcp_services中定义服务端口可以更方便的进行维护。开放UDP服务也可一模仿上述语句,只不过改为proto udp。
已经有了一条rdr策略将web访问请求转发到主机COMP3上,我们必须建立另一条过滤规则使得这些访问请求可以通过防火墙:
pass in on $ext_if proto tcp from any to $comp3 port 80 \ flags S/SA synproxy state
考虑到安全问题,我们使用TCP SYN Proxy保护web服务器――synproxy state。
现在将允许ICMP包通过防火墙:
pass in inet proto icmp all icmp-type $icmp_types keep state
类似于宏$tcp_services,当需要增加允许进入防火墙的ICMP数据包类型时可以容易地编辑宏$icmp_types。注意这条策略将应用于所有网络接口。
现在数据流必须可以正常出入内部网络。我们假设内网的用户清楚自己的所作所为并且确定不会导致麻烦。这并不是必然有效的假设,在某些环境下更具限制性的策略集会更适合。
pass in on $int_if from $int_if:network to any keep state
上面的策略将允许内网中的任何计算机发送数据包穿过防火墙;然而,这并没有允许防火墙主动与内网的计算机建立连接。这是一种好的方法吗?评价这些需要依靠网络配置的一些细节。如果防火墙同时充当DHCP服务器,它需要在分配一个地址之前ping一下该地址以确认该地址没有被占用。允许防火墙访问内部网络同时也允许了在因特网上通过ssh控制防火墙的用户访问内网。请注意禁止防火墙直接访问内网并不能带来高安全性,因为如果一个用户可以访问防火墙,他也可以改变防火墙的策略。增加下列策略可以使防火墙具备访问内网的能力:
pass out on $int_if from any to $int_if:network keep state
如果这些策略同时存在,则keep state选项将不是必须的;所有的数据包都可以流经内网接口,因为一条策略规定了双向放行数据包。然而,如果没有pass out这条策略时,pass in策略必须要有keep state选项。这也是keep state的有点所在:在执行策略匹配之前将先进行state表检查,如果state表中存在匹配记录,数据包将直接放行而不比再进行策略匹配。这将提高符合比较重的防火墙的效率。
最后,允许流出外部网卡接口的数据包通过防火墙
pass out on $ext_if proto tcp all modulate state flags S/SA pass out on $ext_if proto { udp, icmp } all keep state
TCP, UDP, 和 ICMP数据包将被允许朝因特网的方向出防火墙。State信息将被保存,以保证反馈回来的数据包通过防火墙。
完整规则集
# macros int_if = "fxp0" ext_if = "ep0"
tcp_services = "{ 22, 113 }" icmp_types = "echoreq"
priv_nets = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }"
comp3 = "192.168.0.3"
# options set block-policy return set loginterface $ext_if
# scrub scrub in all
# nat/rdr nat on $ext_if from $int_if:network to any -> ($ext_if) rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 \ port 8021 rdr on $ext_if proto tcp from any to any port 80 -> $comp3
# filter rules block all
pass quick on lo0 all
block drop in quick on $ext_if from $priv_nets to any block drop out quick on $ext_if from any to $priv_nets
pass in on $ext_if inet proto tcp from any to ($ext_if) \ port $tcp_services flags S/SA keep state
pass in on $ext_if proto tcp from any to $comp3 port 80 \ flags S/SA synproxy state
pass in inet proto icmp all icmp-type $icmp_types keep state
pass in on $int_if from $int_if:network to any keep state pass out on $int_if from any to $int_if:network keep state
pass out on $ext_if proto tcp all modulate state flags S/SA pass out on $ext_if proto { udp, icmp } all keep state
标签:
相关推荐:
精彩放送:
- []每日播报!无线信号放大模式(Client+AP)怎么设置?设置步骤
- []第一中标获选人!北京地铁12号线电梯供货及安装中标结果公示
- []【全球速看料】酷我音乐盒V5.2.1版本更新 全新乐库火热上线
- []天天热点评!前端页面的截取:MARK下一、引入头部二
- []三国穿越小说排行榜 最好看小说排行
- []每日精选:Godaddy是世界第一大域名注册商 进军主机领域发展迅速
- []世界消息!六种超级boss杀法 问道六道轮回
- []张杰演唱《看月亮爬上来》 好听极了
- []mysql软件包存放目录:Mysql-5.6.40
- []错误619已拒绝远程连接 你还不知道吗?
- []天天新消息丨水平仪是什么?什么牌子水平仪质量好?
- []看点:油价走势分析 江海博3/17油价分析
- []全球百事通!怎么看手机是否支持java?javax.lcdui.Display开发程序
- []每日关注!百度云Linux版本来了!deepin上安装百度网盘版本
- []每日热文:一本书用起来你的恨意就少了 不经历不知道有多难?
- []友信达手机多少钱?友信达手机报价大全
- []速讯:诺基亚7500硬格如何操作?诺基亚7500硬格操作的介绍
- []全球滚动:怎么登陆163邮箱?登陆163邮箱教程
- []当前热议!不同型号的亿和源手机 报价多少钱?
- []快看:HTC G14怎么刷MIUI?HTCG14刷MIUI教程
- []天天微动态丨4g手机可以用3g卡吗?4g手机和3g手机区别
- []全球速看:无敌加速器怎么用?使用方法大全
- []每日快讯!大连短租公寓价格表 大连短租公寓详情介绍
- []天天热议:金鹏手机报价及推荐:金鹏a0001、668、5808
- []控制柜空调怎么安装?控制柜空调定安装方法
- []环球热资讯!什么是邮箱地址?邮箱系列软件最新版本下载
- []世界热门:联通无限流量卡套餐资费多少?联通无限流量卡套餐资费
- []北京爱情故事简介电视剧 北京爱情故事是谁主演?
- []关于单排脚手架搭设要求 你知道多少?
- []天天热资讯!美的空气能热泵热水机怎么样?美的“空气能”热泵热水机组最新价格
- []世界热消息:【我叫MT2】女神血精灵降临 1月签到活动开启
- []世界最新:《爱情公寓》中的陆展博扮演者 你知道吗?
- []全球聚焦:何为盘石桑苞?盘苞什么意思?
- []天天短讯!赣州卫计委地址 赣州市卫生局地址及联系电话一览
- []DNF谁爱拍命运的羽毛?谁虚伪而温柔?
- []全球新消息丨青橙m3如何刷机?青橙m3刷机教程
- []手机套子品牌哪款好?手机套子品牌推荐
- []每日动态!2021年怎么买车险最划算?2022车险怎么买最划算?
- []软件开发中的“OO”到底是什么?真实案例解析OO理论与实践
- []甄嬛传主题曲有哪些歌词?求歌词:甄嬛传主题曲
- []当前热议!【记录分享】Android常用应用市场和应用包名工作
- []原道n90双擎2怎么刷机?原道n90双擎2刷机教程详解
- []全球新消息丨为什么新拟态UI和可访问性是无法共存的?原因分析
- []【环球时快讯】小米cc9配置有多高?小米CC系列智能手机
- []【独家焦点】索尼xperia z刷flyme4.0步骤是什么?索尼l36h刷flyme4教程
- []全球热推荐:不干胶印刷机价格怎么样?不干胶印刷机报价详情
- []数学思想方法猜想与反驳 反例反驳在学习中的用处
- []【环球新要闻】生殖器疱疹的症状有哪些?女性性病有很多种
- []青海省理科400到450分之间的大学名单 有没有公办大学?
- []焦点!配置完Kafka集群后 通过JavaAPI方式来操作
- []东东助手显示无法连接服务器怎么办?模拟器常见问题及解决办法
- []压铸模的使用特点是什么?压铸模的使用特点及使用原则
- []【体验】Xoom评测:比iPad重50克 屏幕倒更大?
- []魅族mx手机壳的价格和使用方法介绍 魅族mx手机壳的使用方法
- []南天pr2e怎么设置?南天pr2e设置与参数修改
- []gps电子狗怎样升级?gps电子狗方法详解
- []环球即时看!QQ邮箱发邮件受限制怎么办?SMTP发送邮件限制的解决方案
- []热门看点:推荐21个高质量图片网站 免费免版权值得收藏
- []【当前独家】什么是执行力?执行力详情介绍
- []环球快看点丨java编程题:如何判断四个棋子连在一起?
- []何删除定时器?MyLibco协程网络库定时器的设计
- []资讯:北京:2023年计划,启动危旧楼房改建和简易楼腾退20万平方米
- []环球快播:免费下载国外视频的网站 你值得拥有
- []【聚看点】华容道有哪些通关技巧?15数字华容道解法
- []泥巴潭:《新龙族》免费卷土重来 拒绝“菜鸟玩家”
- []POI 4.1.2 操作Excel的技巧 POI4.1.2操作Excel的快速应用
- []圆形体癣是什么样子?圆圈状的癣不痛不痒的起因
- []世界观速讯丨速读2023年北京市政府工作报告 | 2023年北京将筹建保障性租赁住房8万套,竣工各类保障性住房9万套
- []世界微资讯!职务与职级并行套改表 新旧“职务与职级并行”套改与晋升实例
- []艾尔文与花栗鼠2/花鼠明星俱乐部 详情介绍
- []每日热讯!泸州老窖:公司销售工作按计划顺利推进
- []北京:过去5年,建设筹集各类政策性住房54万套
- []环球看点!贵州石阡 中国最古老温泉的旅游热度如何继续升温?|新春里的中国经济
- []今亮点!* 中创新航遭摩根大通减持超5%,持股比例降至1.78%
- []【焦点热闻】海南瑞泽:截至2023年1月20日,公司股东人数为66,155
- []【BT金融分析师】比亚迪电动车市场份额持续扩大,分析师称其增长超过特斯拉
- []全球视讯!白求恩大夫是哪国人?诺尔曼·白求恩资料介绍
- []全球热消息:货郎是什么意思?现在的货郎指的是什么?
- []孤城闭帝后结局怎么样?孤城闭剧情介绍
- []【世界聚看点】苹果手机怎么打开微信深色模式?苹果手机打开微信深色模式的步骤
- []陕西的简称是什么?陕西省资料介绍
- []屈原历史资料介绍?对屈原的人物评价怎么写?
- []【独家】猎狐电视剧胡军演谁?猎狐剧情介绍
- []【独家】愚人节怎么发朋友圈?愚人节适合发朋友圈的搞笑说说有哪些?
- []全球观点:华为手机nfc是什么意思?近场通信的技术原理是什么?
- []每日热点:去哪儿2023春节报告:平均每个旅客多走400公里,出境机票同比增长6.7倍
- []天天日报丨这个春节,旅游人信心又来了
- []世界最资讯丨春运返程迎来客流高峰,有人坐绿皮火车返岗开工
- []“零下53度”的东北游,能火多久?
- []简讯:租赁模式的住宿业:合作、匹配、把控
- []全球今头条!我,过年不回家,“和9个陌生人去旅游”
- []【速看料】地产律师的一年| 飞了10多个城市,为购房者追回千万损失
- []天天热推荐:地产营销人的一年| 要时刻保证自己不被淘汰,“还没想过离开房地产行业”
- []今日热门!致远新能:截止2023年1月20日股东人数为11966人
- []热资讯!物业人的一年| 经历了疫情和高温考验,“我们圆满完成年度KPI考核”
- []产业策划人的一年| 产业板块被集团地产业务拖累,“相信今年会比去年好”
- []豪宅中介的一年| 在单价屡破30万元/平的区域卖房是一种什么体验?
- []蓝盾光电:公司将严格按照信息披露的相关规定,及时履行信息披露义务
- []环球快讯:132亿!宁德时代工厂投产!
- []【环球新视野】防城港各大景区人气爆棚
- PF的关键字顺序有多灵活?PF防火墙最详细教程
- 环球热点评!国内常用的ntp服务器 国内常用NTP服务器地址及IP
- 天天快资讯:【商户管理】数字签名安全检测系统-Md5
- 字幕助手电脑版:专业实用的视频字幕制作软件
- 环球讯息:反向解析:Linux搭建DNS服务器的步骤
- LeetCode算法 IntegertoEnglishWords的解题方法
- linux内核编译ccflag,linux-内核编译 centisecs文件控制内核参数
- 新一代office不支持xpsp3的操作系统 XPsp2安装office2010全过程
- 焦点信息:历史上的船到底有多厉害?蒸汽船的发展
- 今日要闻!lbe安全大师纯净版 安卓手机必备的安全软件
- 全球今日报丨国泰君安证券:美国经济外强中干 核心GDP继续回落
- 【环球新视野】马亮:扎堆式旅游何时休?游客要理性,景区更应强化能力建设
- 总投资53亿元!20万吨负极材料项目落地
- 世界实时:【首席展望】海通证券余文心:医药板块有望反转 看好三条主线
- 244亿!特斯拉又投两工厂
- 焦点快看:白酒“霸屏”春节假期 开门红迎新增长周期 今年收益或超额
- 环球观焦点:宁德时代牵头!斥资67亿元 开发玻利维亚锂资源
- 全球热文:中海董事长颜建国拜会香港特首李家超 积极参与北部都会区和明日大屿建设
- 渣打预测布油有望反弹至90美元以上,但对突破100美元并不乐观!
- 每日视讯:现货黄金交易策略:金价见顶风险增加,关注美国PCE数据
- 文化和旅游部:春节假期国内旅游出游3.08亿人次 同比增长23.1%
- 快讯:香港财政司司长:未有定案是否再派消费券 楼市现时有秩序调整
- 美国12月新屋销售量连续第三个月上升 同比仍降26.6%
- 天天观焦点:CFTC商品持仓解读:投机者提高美国原油净多头头寸
- 新春走基层丨保障多地轨道交通正常运行,众合科技员工誓要站好春节最后一班岗
- 广西出台16条措施 加快文化旅游业全面恢复振兴
- 环球即时:1月28日财经早餐:黄金连续第六周周线上涨,焦点转向美联储
- 速读:美原油交易策略:美国GDP数据缓解需求担忧,油价将重拾涨势?
- 热门:美股异动 | 移动金融智选平台简普科技(JT.US)涨超9% 年初至今累涨超31%
- 环球快播:美股异动 | 途牛(TOUR.US)涨超9.5% 年初至今累涨近67%
- 最新资讯:威海广泰:公司以技术创新为龙头,始终重视消防救援装备的技术研发工作,每年都有10余型新产品完成开发
- 环球即时:奥维通信:具体内容请详见公司于2023年1月20日披露的《关于终止筹划重大资产重组的公告》
- 新春行业动态合集 | 日媒:春节中国旅客访日需求依旧低迷;国航回应“一航班颠簸下坠”
- 当前快报:查询车辆保险怎么查询
- 全球快消息!手工钥匙扣制作图片_手工钥匙扣制作过程
- 【世界报资讯】文化和旅游部:今年春节国内出游人次恢复至疫前同期88.6%
- 旅游强劲复苏:多地游客数追平2019年,部分已反超
- 近3.08亿人次出游,收入3758.43亿元, 春节假期各OTA数据战报PK
- 世界快看点丨上万只基金产品 2000余位基金经理 兔年养基如何选?
- 携程2023春节旅游报告:旅游订单同比增长超4倍,其中出境游增长640%
- 状态火热!欧文三分球4中3半场独砍18分
- 钠电池元年将至 产业化到哪一步了?
- 快播:特斯拉杀疯了 价格还能降?美国重磅数据公布 传递什么信号?
- 当前动态:报价上涨12%,西藏山南光伏增配储能EPC中标公示发布
- 峰谷电价差扩大,低价谷电储热采暖优势明显
- 快讯:宝马计划量产全固态电池,最快2025年实现装车
- 今日视点:重磅发声!兔年怎么投?多家公募巨头最新研判
- 环球百事通!机构展望2023:中国市场更具吸引力 多元化投资组合提供机会
- 天天热点评!盘点︱2023年即将上市IPO光伏公司统计表
- 立冬的优美诗词句子_立冬的优美诗词
- 【世界聚看点】平安福7000交了5年能退多少,保单现金价值
- 世界速递!被银行忽悠买了保险可以退吗,可以退
- 热点聚焦:公积金能不能每月还商贷,当然可以
- 全球微动态丨最低-1℃郴州未来几天将迎霜冻天气
- 【环球速看料】兔年港股开门红!恒生指数涨逾2% 科技指数大涨超4%!多板块集体爆发
- 扩张性财政政策包括哪些(扩张性货币政策包括哪些)
- 天天简讯:为什么美金汇率一直在跌(最近美元汇率为什么一直在跌 最近美元汇率为啥一直在)
- 解析基金“专业买手”!FOF基金经理为何喜欢低换手?还有哪些特征?
- 农村信用社贷款无力偿还怎么办理(农村信用社贷款10万还不上怎么办)
- 基金gp和lp的区别优先和劣后(基金gp和lp的区别优先和劣后)
- 发力定制化场景金融布局 钱小乐探索精准营销新模式
- 最低或8万/吨!硅料价格拐点何时来临?
- 当前信息:微信转账退回对方会收到提示吗?(别人微信转账给我我退回有记录吗)
- 宏观经济分析包括哪些内容(宏观经济分析包括哪些内容)
- 今日聚焦!工商宝贝成长卡好不好(工行宝贝成长卡有什么弊端)
- 农业银行怎么查询冻结原因(怎样判断是永久冻结还是临时冻结)
- 全球今亮点!公积金4万可贷款多少(公积金账户4w可以贷款多少)
- 全球今亮点!地方债谁在买(地方专项债谁来买单)
- 天天热讯:京郊民宿老板:过完最冷清的春节,盼春暖花开不愁客人
- 焦点快报!携程:兔年春节过半,香港、澳门领跑春节出境热门目的地
- 天天最资讯丨春节楼市不打烊,部分楼盘推“0月供”计划,有客户打飞的到佛山买房
- 日元计价的黄金周三创新高,美元计价的或将紧随其后!
- 【全球新视野】中信证券交易手续费是多少(中信交易手续费)
- 环球观热点:明星税收怎么收费比例(明星的收入税率是多少)
- 杜邦奖学金_关于杜邦奖学金简述
- 热讯:港元1个月拆息四连跌 报2.94345
- 世界今热点:宣发“重大失误”!邓超新片紧急撤档,上映首日票房、上座率倒数第一;春节档票房已超50亿
- 环球微资讯!多家光伏逆变器上市公司2022年业绩预喜 储能正成为重要增长点
- 年终:2022跨界储能企业一览表
- 头条焦点:投资600亿!比亚迪合作伙伴造电池!
- 山东和山西为何成为储能引领者
- 消息!碳酸锂涨价?再度直逼50万大关!
- 资讯:港交所兔年首个交易日 财政司司长陈茂波冀股市吐气扬眉
- 专题回顾 | 房地产企业并购融资现状解析
- 报告:今年房企主要“保交付”,销售和投资规模呈前低后高走势
- 天天热资讯!红星美凯龙:行使换股权后 阿里巴巴持有公司权益已达到9.99%
- 盘后机构策略:市场维持强势格局 关注春节后内资流入情况
- 以岭药业:奋力推进新时代中医药传承创新发展
- 当前要闻:五矿地产(00230)首季度合约销售额30.7亿元 同比下跌30.7%
- 热讯:已签收的电子汇票在哪里查询 在哪里查询已签收的电子(已签收的电子汇票在哪里查询 在哪里查询已签收的电子)
- 当前报道:股票分红在什么时间(股票分红多长时间到账)
- 覆铜板是什么东西及用途(覆铜板是什么东西及用途)
- 环球视讯!全部资本化比率公式(全部资本化比率公式)
- 小规模纳税人收到专票的风险(小规模收到13%的专票有风险没)
- 【天天速看料】按单利计算是什么意思 什么是按单利计算(按单利计算是什么意思 什么是按单利计算)
- 热点聚焦:利润率的公式怎么算的(利润和利润率的计算公式)
- 世界今头条!春节假期海南离岛免税购物“南北两旺”
- 当前要闻:什么叫收现比(收现比是什么意思)
- 热资讯!税金贷款有什么银行做(什么银行有税金贷)
- 速看:集中趋势指标包括哪些方面(集中趋势指标包括哪些方面)
- 天天播报:大学生可以开佳物分期吗(佳物分期大学生能用吗 大学生可不可以用佳物分期)
- 央行100亿逆回购是什么意思(央行100亿逆回购意味着什么)
- 环球速读:大年初四,怎么做能接好运?
- 新资讯:货币资金包括哪三项(货币资金包括哪三个部分)
- 当前播报:强赎触发价什么意思?(强赎触发价什么意思科普)
- 当前资讯!银行卡信息不完善是怎么回事(银行提示此卡状态异常)
- 无卡是否可以存款(不带卡可以存款吗)
- 全球播报:转账二十四小时没到账怎么办(跨行转账4天了还没到账)
- 【环球时快讯】红字冲销什么意思(红字冲销什么意思)
- 2022年房贷利率是降还是升(银行利率表2022最新住房贷款利率,房贷利率每年都会变吗)