FreeBSD 上设置 PF 防火墙

PF 是包过滤器packet filter的简称。它是为 OpenBSD 开发的,但是已经被移植到了 FreeBSD 以及其它操作系统上。PF 是一个包状态过滤引擎。在这篇教程中,我将向你展示如何在 FreeBSD 10.x 以及 11.x 中设置 PF 防火墙,从而来保护 web 服务器。

第一步:开启 PF 防火墙
你需要把下面这几行内容添加到文件 /etc/rc.conf 文件中:

  1. #echo’pf_enable=“YES”’>>/etc/rc.conf
  2. #echo’pf_rules="/usr/local/etc/pf.conf"’>>/etc/rc.conf
  3. #echo’pflog_enable=“YES”’>>/etc/rc.conf
  4. #echo’pflog_logfile="/var/log/pflog"’>>/etc/rc.conf
    在这里:
  5. pf_enable=“YES” - 开启 PF 服务
  6. pf_rules="/usr/local/etc/pf.conf" - 从文件 /usr/local/etc/pf.conf 中读取 PF 规则
  7. pflog_enable=“YES” - 为 PF 服务打开日志支持
  8. pflog_logfile="/var/log/pflog" - 存储日志的文件,即日志存于文件 /var/log/pflog 中

第二步:在 /usr/local/etc/pf.conf 文件中创建防火墙规则
输入下面这个命令打开文件(超级用户模式下):

  1. #vi/usr/local/etc/pf.conf
    在文件中添加下面这些 PF 规则集:
  2. #vim:set ft=pf
  3. /usr/local/etc/pf.conf

  4. ##设置公共端口##
  5. ext_if=“vtnet0”
  6. ##设置服务器公共 IP 地址##
  7. ext_if_ip=“172.xxx.yyy.zzz”
  8. ##设置并删除下面这些公共端口上的 IP 范围##
  9. martians ="{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, \
  10. 10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, \
  11. 0.0.0.0/8, 240.0.0.0/4 }"
  12. ##设置 http(80)/https (443)端口##
  13. webports ="{http, https}"
  14. ##启用下面这些服务##
  15. int_tcp_services ="{domain, ntp, smtp, www, https, ftp, ssh}"
  16. int_udp_services ="{domain, ntp}"
  17. ##跳过回环端口-跳过端口上的所有 PF 处理##
  18. set skip on lo
  19. ##设置 PF 应该统计的端口信息,如发送/接收字节数,通过/禁止的包的数目##
  20. set loginterface $ext_if
  21. ##设置默认策略##
  22. block returnin log all
  23. block out all
  24. #基于 IP 分片的错误处理来防御攻击
  25. scrub in all
  26. #删除所有不可达路由地址
  27. block drop in quick on $ext_if from $martians to any
  28. block drop out quick on $ext_if from any to $martians
  29. ##禁止欺骗包
  30. antispoof quick for $ext_if
  31. #打开 SSH 端口,SSH 服务仅从 VPN IP 139.xx.yy.zz 监听22号端口
  32. #出于安全原因,我不允许/接收 SSH 流量
  33. passin quick on $ext_if inet proto tcp from139.xxx.yyy.zzz to $ext_if_ip port =ssh flags S/SA keep state label “USER_RULE: Allow SSH from 139.xxx.yyy.zzz”
  34. ##使用下面这些规则来为所有来自任何 IP 地址的用户开启 SSH 服务#
  35. ##passin inet proto tcp to $ext_if port ssh
  36. [ OR ]

  37. ##passin inet proto tcp to $ext_if port 22
  38. #AllowPing-Pong stuff.Be a good sysadmin
  39. pass inet proto icmp icmp-type echoreq
  40. #All access to ourNginx/Apache/LighttpdWebserver ports
  41. pass proto tcp from any to $ext_if port $webports
  42. #允许重要的发送流量
  43. pass out quick on $ext_if proto tcp to any port $int_tcp_services
  44. pass out quick on $ext_if proto udp to any port $int_udp_services
  45. #在下面添加自定义规则
    保存并关闭文件。欢迎来参考我的规则集。如果要检查语法错误,可以运行:
  46. service pf check

  1. /etc/rc.d/pf check
  2. pfctl -n -f /usr/local/etc/pf.conf

第三步:开始运行 PF 防火墙
命令如下。请小心,如果是基于 SSH 的会话,你可能会和服务器断开连接。

开启 PF 防火墙:

  1. service pf start

停用 PF 防火墙:

  1. service pf stop

检查语法错误:

  1. service pf check

重启服务:

  1. service pf restart

查看 PF 状态:

  1. service pf status

示例输出:

  1. Status:Enabledfor0 days 00:02:18Debug:Urgent
  2. InterfaceStatsfor vtnet0 IPv4IPv6
  3. BytesIn194630
  4. BytesOut185410
  5. PacketsIn
  6. Passed2440
  7. Blocked30
  8. PacketsOut
  9. Passed1360
  10. Blocked120
  11. StateTableTotalRate
  12. current entries 1
  13. searches 3952.9/s
  14. inserts 40.0/s
  15. removals 30.0/s
  16. Counters
  17. match 190.1/s
  18. bad-offset 00.0/s
  19. fragment 00.0/s
  20. short00.0/s
  21. normalize 00.0/s
  22. memory 00.0/s
  23. bad-timestamp 00.0/s
  24. congestion 00.0/s
  25. ip-option 00.0/s
  26. proto-cksum 00.0/s
  27. state-mismatch 00.0/s
  28. state-insert 00.0/s
  29. state-limit 00.0/s
  30. src-limit 00.0/s
  31. synproxy 00.0/s
  32. map-failed 00.0/s

开启/关闭/重启 pflog 服务的命令
输入下面这些命令:

  1. service pflog start

  2. service pflog stop

  3. service pflog restart

第四步:pfctl 命令的简单介绍
你需要使用 pfctl 命令来查看 PF 规则集和参数配置,包括来自包过滤器packet filter的状态信息。让我们来看一下所有常见命令:

显示 PF 规则信息

  1. pfctl -s rules

示例输出:

  1. block returnin log all
  2. block drop out all
  3. block drop in quick on ! vtnet0 inet from172.xxx.yyy.zzz/24 to any
  4. block drop in quick inet from172.xxx.yyy.zzz/24 to any
  5. passin quick on vtnet0 inet proto tcp from139.aaa.ccc.ddd to 172.xxx.yyy.zzz/24 port =ssh flags S/SA keep state label “USER_RULE: Allow SSH from 139.aaa.ccc.ddd”
  6. pass inet proto icmp all icmp-type echoreq keep state
  7. pass out quick on vtnet0 proto tcp from any to any port = domain flags S/SA keep state
  8. pass out quick on vtnet0 proto tcp from any to any port = ntp flags S/SA keep state
  9. pass out quick on vtnet0 proto tcp from any to any port = smtp flags S/SA keep state
  10. pass out quick on vtnet0 proto tcp from any to any port = http flags S/SA keep state
  11. pass out quick on vtnet0 proto tcp from any to any port = https flags S/SA keep state
  12. pass out quick on vtnet0 proto tcp from any to any port = ftp flags S/SA keep state
  13. pass out quick on vtnet0 proto tcp from any to any port =ssh flags S/SA keep state
  14. pass out quick on vtnet0 proto udp from any to any port = domain keep state
  15. pass out quick on vtnet0 proto udp from any to any port = ntp keep state

显示每条规则的详细内容

  1. pfctl -v -s rules

在每条规则的详细输出中添加规则编号:

  1. pfctl -vvsr show

显示状态信息

  1. pfctl -s state

  2. pfctl -s state |more

  3. pfctl -s state |grep’something’

如何在命令行中禁止 PF 服务

  1. pfctl -d

如何在命令行中启用 PF 服务

  1. pfctl -e

如何在命令行中刷新 PF 规则/NAT/路由表

  1. pfctl -F all

示例输出:

  1. rules cleared
  2. nat cleared
  3. 0 tables deleted.
  4. 2 states cleared
  5. source tracking entries cleared
  6. pf: statistics cleared
  7. pf:interface flags reset

如何在命令行中仅刷新 PF 规则

  1. pfctl -F rules

如何在命令行中仅刷新队列

  1. pfctl -F queue

如何在命令行中刷新统计信息(它不是任何规则的一部分)

  1. pfctl -F info

如何在命令行中清除所有计数器

  1. pfctl -z clear

第五步:查看 PF 日志
PF 日志是二进制格式的。使用下面这一命令来查看:

  1. #tcpdump-n -e -ttt -r /var/log/pflog
    示例输出:
  2. Aug2915:41:11.757829 rule 0/(match) block in on vio0:86.47.225.151.55806>45.FOO.BAR.IP.23: S 757158343:757158343(0) win 52206[tos 0x28]
  3. Aug2915:41:44.193309 rule 0/(match) block in on vio0:5.196.83.88.25461>45.FOO.BAR.IP.26941: S 2224505792:2224505792(0) ack 4252565505 win 17520(DF)[tos 0x24]
  4. Aug2915:41:54.628027 rule 0/(match) block in on vio0:45.55.13.94.50217>45.FOO.BAR.IP.465: S 3941123632:3941123632(0) win 65535
  5. Aug2915:42:11.126427 rule 0/(match) block in on vio0:87.250.224.127.59862>45.FOO.BAR.IP.80: S 248176545:248176545(0) win 28200<mss 1410,sackOK,timestamp 10440553050,nop,wscale 8>(DF)
  6. Aug2915:43:04.953537 rule 0/(match) block in on vio0:77.72.82.22.47218>45.FOO.BAR.IP.7475: S 1164335542:1164335542(0) win 1024
  7. Aug2915:43:05.122156 rule 0/(match) block in on vio0:77.72.82.22.47218>45.FOO.BAR.IP.7475: R 1164335543:1164335543(0) win 1200
  8. Aug2915:43:37.302410 rule 0/(match) block in on vio0:94.130.12.27.18080>45.FOO.BAR.IP.64857: S 683904905:683904905(0) ack 4000841729 win 16384<mss 1460>
  9. Aug2915:44:46.574863 rule 0/(match) block in on vio0:77.72.82.22.47218>45.FOO.BAR.IP.7677: S 3451987887:3451987887(0) win 1024
  10. Aug2915:44:46.819754 rule 0/(match) block in on vio0:77.72.82.22.47218>45.FOO.BAR.IP.7677: R 3451987888:3451987888(0) win 1200
  11. Aug2915:45:21.194752 rule 0/(match) block in on vio0:185.40.4.130.55910>45.FOO.BAR.IP.80: S 3106068642:3106068642(0) win 1024
  12. Aug2915:45:32.999219 rule 0/(match) block in on vio0:185.40.4.130.55910>45.FOO.BAR.IP.808: S 322591763:322591763(0) win 1024
  13. Aug2915:46:30.157884 rule 0/(match) block in on vio0:77.72.82.22.47218>45.FOO.BAR.IP.6511: S 2412580953:2412580953(0) win 1024[tos 0x28]
  14. Aug2915:46:30.252023 rule 0/(match) block in on vio0:77.72.82.22.47218>45.FOO.BAR.IP.6511: R 2412580954:2412580954(0) win 1200[tos 0x28]
  15. Aug2915:49:44.337015 rule 0/(match) block in on vio0:189.219.226.213.22640>45.FOO.BAR.IP.23: S 14807:14807(0) win 14600[tos 0x28]
  16. Aug2915:49:55.161572 rule 0/(match) block in on vio0:5.196.83.88.25461>45.FOO.BAR.IP.40321: S 1297217585:1297217585(0) ack 1051525121 win 17520(DF)[tos 0x24]
  17. Aug2915:49:59.735391 rule 0/(match) block in on vio0:36.7.147.209.2545>45.FOO.BAR.IP.3389: SWE 3577047469:3577047469(0) win 8192<mss 1460,nop,wscale 8,nop,nop,sackOK>(DF)[tos 0x2(E)]
  18. Aug2915:50:00.703229 rule 0/(match) block in on vio0:36.7.147.209.2546>45.FOO.BAR.IP.3389: SWE 1539382950:1539382950(0) win 8192<mss 1460,nop,wscale 8,nop,nop,sackOK>(DF)[tos 0x2(E)]
  19. Aug2915:51:33.880334 rule 0/(match) block in on vio0:45.55.22.21.53510>45.FOO.BAR.IP.2362: udp 14
  20. Aug2915:51:34.006656 rule 0/(match) block in on vio0:77.72.82.22.47218>45.FOO.BAR.IP.6491: S 151489102:151489102(0) win 1024[tos 0x28]
  21. Aug2915:51:34.274654 rule 0/(match) block in on vio0:77.72.82.22.47218>45.FOO.BAR.IP.6491: R 151489103:151489103(0) win 1200[tos 0x28]
  22. Aug2915:51:36.393019 rule 0/(match) block in on vio0:60.191.38.78.4249>45.FOO.BAR.IP.8000: S 3746478095:3746478095(0) win 29200(DF)
  23. Aug2915:51:57.213051 rule 0/(match) block in on vio0:24.137.245.138.7343>45.FOO.BAR.IP.5358: S 14134:14134(0) win 14600
  24. Aug2915:52:37.852219 rule 0/(match) block in on vio0:122.226.185.125.51128>45.FOO.BAR.IP.23: S 1715745381:1715745381(0) win 5840<mss 1420,sackOK,timestamp 135114170,nop,wscale 2>(DF)
  25. Aug2915:53:31.309325 rule 0/(match) block in on vio0:189.218.148.69.377>45.FOO.BAR.IP5358: S 65340:65340(0) win 14600[tos 0x28]
  26. Aug2915:53:31.809570 rule 0/(match) block in on vio0:13.93.104.140.53184>45.FOO.BAR.IP.1433: S 39854048:39854048(0) win 1024
  27. Aug2915:53:32.138231 rule 0/(match) block in on vio0:13.93.104.140.53184>45.FOO.BAR.IP.1433: R 39854049:39854049(0) win 1200
  28. Aug2915:53:41.459088 rule 0/(match) block in on vio0:77.72.82.22.47218>45.FOO.BAR.IP.6028: S 168338703:168338703(0) win 1024
  29. Aug2915:53:41.789732 rule 0/(match) block in on vio0:77.72.82.22.47218>45.FOO.BAR.IP.6028: R 168338704:168338704(0) win 1200
  30. Aug2915:54:34.993594 rule 0/(match) block in on vio0:212.47.234.50.5102>45.FOO.BAR.IP.5060: udp 408(DF)[tos 0x28]
  31. Aug2915:54:57.987449 rule 0/(match) block in on vio0:51.15.69.145.5100>45.FOO.BAR.IP.5060: udp 406(DF)[tos 0x28]
  32. Aug2915:55:07.001743 rule 0/(match) block in on vio0:190.83.174.214.58863>45.FOO.BAR.IP.23: S 757158343:757158343(0) win 27420
  33. Aug2915:55:51.269549 rule 0/(match) block in on vio0:142.217.201.69.26112>45.FOO.BAR.IP.22: S 757158343:757158343(0) win 22840<mss 1460>
  34. Aug2915:58:41.346028 rule 0/(match) block in on vio0:169.1.29.111.29765>45.FOO.BAR.IP.23: S 757158343:757158343(0) win 28509
  35. Aug2915:59:11.575927 rule 0/(match) block in on vio0:187.160.235.162.32427>45.FOO.BAR.IP.5358: S 22445:22445(0) win 14600[tos 0x28]
  36. Aug2915:59:37.826598 rule 0/(match) block in on vio0:94.74.81.97.54656>45.FOO.BAR.IP.3128: S 2720157526:2720157526(0) win 1024[tos 0x28]stateful
  37. Aug2915:59:37.991171 rule 0/(match) block in on vio0:94.74.81.97.54656>45.FOO.BAR.IP.3128: R 2720157527:2720157527(0) win 1200[tos 0x28]
  38. Aug2916:01:36.990050 rule 0/(match) block in on vio0:182.18.8.28.23299>45.FOO.BAR.IP.445: S 1510146048:1510146048(0) win 16384
    如果要查看实时日志,可以运行:
  39. #tcpdump-n -e -ttt -i pflog0
    如果你想了解更多信息,可以访问 PF FAQ 和 FreeBSD HANDBOOK 以及下面这些 man 页面:
  40. #mantcpdump
  41. #man pfctl
  42. #man pf

猜你喜欢

转载自blog.csdn.net/seaship/article/details/86233961