《The BOOK Of PF》中文版 —— 5. 利用list和macro使规则稍微严格一些
发表于 : 2010-07-13 9:06
尽管我们可使用第一个规则集说明网络及数据包如何工作,但是它实在是太简单了, 也许并不适合实际的应用。 为了体验一下配置文件的完整结构设定, 我们设定一个更真实的例子。但是这个规则集还是针对一个独立主机只连接到一个网络的情况。
在这个配置里, 我们开始先拒绝一些通讯,然后允许我们需要的通讯。详说明3。这也给我们提供了一个机会向读者介绍两个PF中的角色—— list 和macro,也正是这些角色使PF成为一个很棒的工具。
我们要修改一下 /etc/pf.conf, 第一条规则是
代码: 全选
block all
代码: 全选
tcp_services = "{ ssh, smtp, domain, www, pop3, auth, https, pop3s }"
udp_services = "{ domain }"
这使我们可以更简单地编写规则, 例如像这样:
代码: 全选
block all
pass out proto tcp to any port $tcp_services
pass proto udp to any port $udp_services
说明
请注意,如果你使用的PF版本比OpenBSD 4.1的PF版本要旧,请在规则里加上keep state。
说明3
你可能会问为什么我要在规则集里加上默认拒绝规则。简而言之它可以有助于你思考规则时的控制。包过滤的主要目的就是控制, 而不是玩警察抓小偷的游戏。关于这个机理,Marcus Ranum写了一篇内容生动丰富的文章 ——“The Six Dumbest Ideas in Computer Security,” 我们强烈推荐您阅读。它可以在 http://www.ranum.com/security/computer_ ... index.html里找到,是值得一读的好文章。
这里的字符串$tcp_services和$udp_services是macro引用。
当规则集被调用时Macros在这里被展开, 并且在引用Macros的地方将插入全部的列表。Macros很便于阅读。即便在这样的小型规则集里, 如果我们不使用全部的列表和端口号,而是使用宏和列表,你也能轻易地领会和维护这些规则。
你需要在这里培养良好的习惯,也就是尽量地使用宏以提高规则集的可读性。
当你的规则集展开时, 你会为此感到高兴。
你可能会奇怪,UDP是无状态醒和无连接的,但PF怎么能为UDP通讯产生和维护状态信息以便放行返回的UDP通讯的? 一个最常见的应用UDP状态信息的例子是处理域名解析。当你请求一个域名服务器将一个域名解析为一个IP地址时或将一个IP地址反向解析为一个域名时, 我敢打赌你肯定希望收到服务器的回应。保持状态信息或功能等同于你的UDP通讯可能实现这样的功能。
因为我们已经修改了 pf.conf 文件, 我们必须导入新规则:
代码: 全选
$ sudo pfctl -f /etc/pf.conf
这里值得一提的是,尽管在本例的特定条件下可能输出的结果没有什么差异, 但是你可以用 -v 标签来生成更详尽的pfctl输出:
代码: 全选
$ sudo pfctl -vf /etc/pf.conf
如果你扩展了你的规则集, 你可能想在导入前先检查一下这些规则。 检查的命令是:
代码: 全选
pfctl -nf /etc/pf.conf
在任何情况下, 除非你清除了你的规则(using pfctl -F and some specifier),在你企图从配置文件导入新规则前,最后导入的规则集一直有效,如果你要终止它,那么停止PF,要么导入新的规则集 。 规则集导入的工作流程是, pfctl在切换到新的规则集前先进行语法检查,然后在再导入它。 导入一个有效的规则集时,没有无规则集或执行部分规则集的中间状态。(译者,感觉这里强调的是PF的工作不会停止或出错。) 这个结果是清除规则集很难说是一个好主意, 因为它使你的packet filter进入一个pass all模式。
测试规则集
一旦你有一个在pfctl导入时没有错误提示的规则集, 现在就是看看是否该规则集符合你的要求。
用诸如这样的命令测试一下域名解析,结果应该和前一个例子显示的一样。 但是, 可能此时你的系统仍然保留着上次 DNS 查询的缓存, 所以为了获得真实的测试结果, 请选择一个你最近没有访问过的域名(例如你不会考虑为其投票的政党站点)。你也可以浏览互联网以及使用几个email相关的服务。 但是不管怎样, 除了ssh, smtp, domain, www, pop3, auth, https和pop3s,任何企图访问远程主机其它TCP服务的尝试都应该失败。 而且应该和第一个测试规则一样, 你的系统应该拒绝不匹配状态表里任何项目的所有连接。 也就是说,PF只允许那些由你本地发起连接的返回通讯进站。代码: 全选
$ host gobsd.org