列表允许在一个规则里描述多个同类项。例如, 多个协议、端口号、地址等, 这样就不必为每个需要阻止的IP地址单独写一条过滤规则, 你可以为列表中的所有的IP地址写一条规则。列表定义是将所有同类项写入{ }中。
当 pfctl(8) 载入规则集内的列表时, 它会为列表中的同类项产生多条规则, 每条规则对应列表中的一个同类项。例如:
block out on fxp0 from { 192.168.0.1, 10.5.32.6 } to any
会展开为:
block out on fxp0 from 192.168.0.1 to any block out on fxp0 from 10.5.32.6 to any
一条规则里可以指定多种列表:
match in on fxp0 proto tcp to port { 22 80 } rdr-to 192.168.0.6
block out on fxp0 proto { tcp udp } from { 192.168.0.1, \
10.5.32.6 } to any port { ssh telnet }
注意列表中同类项之间的逗号是可选项。(译者注:也可以用空格)
列表也可以嵌套:
trusted = "{ 192.168.1.2 192.168.5.36 }" pass in inet proto tcp from { 10.10.0.0/24 $trusted } to port 22
当心像下面这样常见的语法结构, 我们姑且称之为 "否定列表":
pass in on fxp0 from { 10.0.0.0/8, !10.1.2.3 }
尽管通常使用这个列表的本意可能是指"除了10.1.2.3, 允许从外部到10.0.0.0/8范围内的任何地址的通讯", 但是这条规则会展开为:
pass in on fxp0 from 10.0.0.0/8 pass in on fxp0 from !10.1.2.3
结果就是允许外部到内部任何地址的通讯。这里应该用一个 table 代替它来进行描述。
宏的名称必须以字母开头, 名称里面可以包含字母、数字和下划线。 宏的名称不能使用保留字符, 诸如 pass, out, queue等。
ext_if = "fxp0"
block in on $ext_if from any to any
这里定义了一个名为 ext_if 的宏, 当一个宏被定义后, 引用时要在其名称前面加上$字符。
宏也可以展开为列表, 比如:
friends = "{ 192.168.1.1, 10.0.2.5, 192.168.43.53 }"
宏可以被递归定义。 因此宏不能在引号内展开, 必须使用下面的语法:
host1 = "192.168.1.1" host2 = "192.168.1.2" all_hosts = "{" $host1 $host2 "}"
宏 $all_hosts 现在展开成 192.168.1.1, 192.168.1.2 。