第 15.2 节 Packet Filter(PF)
PF(Packet Filter,包过滤器)是一款由 OpenBSD 移植而来的防火墙,提供了大量功能,包括 ALTQ (Alternate Queuing,交错队列) 等。
启用 PF
# kldload pf # ① 加载内核模块
# 复制示例文件作为默认配置规则集文件,否则 pf 无法启动②
# cp /usr/share/examples/pf/pf.conf /etc/
# service pf enable # 设置 pf 开机启动
# service pf start # 启动 pf
① 如不做,则提示
pfctl: /dev/pf: No such file or directory
。或者你重启再service pf start
。② 否则提示:
/etc/rc.d/pf: WARNING: /etc/pf.conf is not readable.
pfctl
pfctl
pf 的管理命令为 pfctl
,常用操作示例如下:
# 启动 pf,相当于 service pf start
# pfctl -e
# 即禁止规则。几乎相当于 service pf stop(停止防火墙)
# pfctl -d
# 加载规则集文件中的规则
# pfctl -f /etc/pf.conf
# 解析规则,但不加载。-f 参数还可以与其他参数配合,如 -N 表示只载入 NAT 规则,-R 表示只载入过滤规则,-A 只载入队列规则,-O 只载入选项规则
# pfctl -nf /etc/pf.conf
# 查看 pf 所有对象信息。如果想查看特定对象信息,可以用 nat、queue、rules、Anchors、states、Sources、info、Running、labels、timeouts、memory、Tables、osfp、Interfaces 替换 all
# pfctl -s all
# 清理 pf 所有规则
# pfctl -F all
如果想查看特定规则,可以用 nat、queue、rules、states、Sources、info、Tables、osfp 替换 all。
不过以上操作并没有对规则的管理,因此还需要修改规则集文件,常用示例如下:
# 整理所有输入的数据
scrub in all
# 拒绝所有访问
block all # 默认明示禁止所有访问。block 是动作,all 是从任何源到任何目标的简写,表示从源地址到目标地址。
# 放开回环接口的访问权限,回环接口不对外部
pass quick on lo0 all # quick 关键字表示若规则匹配,就停止执行,不会再执行后续规则
# 增加 TCP 协议访问 80 端口的规则,允许任何设备以 TCP 协议访问本机 80 端口
pass in quick proto tcp from any to 192.168.1.184 port 80 # proto tcp 是访问协议,port 80 是目标端口
# 允许回显信息给任何访问的设备
pass out quick proto tcp from 192.168.1.184 port 80 to any # 允许本机向外发送 80 端口的响应
# 增加 80 端口到 8080 端口流量转发的规则
rdr pass on em0 inet proto tcp from any to 192.168.1.184 port 80 -> 192.168.1.166 port 8080 # 转发流量到内网地址 192.168.1.166 端口 8080
# 允许本机与外部设备互 ping
pass quick inet proto icmp all icmp-type 8 code 0 # icmp-type 8 是查询请求,code 0 表示返回码为 0
# 允许 traceroute 命令以 ICMP 协议执行
pass out quick inet proto icmp from 192.168.1.184 to any icmp-type 11 code 0 # icmp-type 11 用于时间超时
# 允许 traceroute 使用 UDP 协议执行,端口号从 33434 开始
pass out quick proto udp from 192.168.1.184 to any port 33434 >< 34500 # 默认 UDP 协议,端口号从 33434 开始,每转发一次端口号加 1
可能用到的规则集文件 /etc/pf.conf
如下:
# 流量整形
scrub in all
# 转发规则
rdr pass on em0 inet proto tcp from any to 192.168.1.184 port 8080 -> 192.168.1.184 port 80 # 注意规则次序,根据 pf.conf 规则,转发规则应位于过滤规则之前,相关内容请参考帮助
# 过滤规则
block all pass quick on lo0 all # 阻止所有流量,但允许回环接口(lo0)上的流量
# 设置任何设备可以访问服务器的 22、80、443、4200、10000 端口
pass in quick proto tcp from any to 192.168.1.184 port { 22, 80, 443, 4200, 10000 }
# 设置服务器可以访问外部设备的 22、80、443、4200、10000 端口
pass out quick proto tcp from 192.168.1.184 port { 22, 80, 443, 4200, 10000 } to any
# 设置服务器访问任何网络设备的 80、443 端口,并保持状态
pass out quick proto tcp from 192.168.1.184 to any port { 80, 443 } keep state
# 设置服务器访问 DNS 服务器(UDP 端口 53)
pass out quick proto udp from any to any port 53 keep state
# 设置服务器访问 DHCP 服务器(UDP 端口 67)
pass out quick proto udp from any to any port 67 keep state
# 允许服务器发送 ICMP 请求
pass quick inet proto icmp all icmp-type 8 code 0
# 允许服务器发送 ICMP 超时消息(TTL 超过)
pass out quick inet proto icmp from 192.168.1.184 to any icmp-type 11 code 0
# 允许服务器访问 UDP 范围端口 33434 到 34500
pass out quick proto udp from 192.168.1.184 to any port 33434 >< 34500
保存文件,接下来在终端执行命令:
# 加载规则集文件中的规则 就可以看到效果了。
# pfctl -Fa -f /etc/pf.conf
最后更新于