歡迎光臨
每天分享高質量文章

如何在 FreeBSD 上設定 PF 防火牆來保護 Web 伺服器 | Linux 中國

在 FreeBSD 上,我該如何設定 PF 防火牆,來保護只有一個公共 IP 地址和埠的 web 伺服器呢?
— Vivek Gite


致謝
編譯自 | 
https://www.cyberciti.biz/faq/how-to-set-up-a-firewall-with-pf-on-freebsd-to-protect-a-web-server/
 
 作者 | Vivek Gite
 譯者 | Lv Feng (ucasFL) ?????共計翻譯:69.0 篇 貢獻時間:731 天

How To Set Up a Firewall with PF on FreeBSD to Protect a Web Server

我是從 Linux 遷移過來的 FreeBSD 新使用者,Linux 中使用的是 netfilter 防火牆框架(LCTT 譯註:netfilter 是由 Rusty Russell 提出的 Linux 2.4 核心防火牆框架)。那麼在 FreeBSD 上,我該如何設定 PF 防火牆,來保護只有一個公共 IP 地址和埠的 web 伺服器呢?

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

在這裡:

1. pf_enable="YES" – 開啟 PF 服務
2. pf_rules="/usr/local/etc/pf.conf" – 從檔案 /usr/local/etc/pf.conf 中讀取 PF 規則
3. pflog_enable="YES" – 為 PF 服務開啟日誌支援
4. pflog_logfile="/var/log/pflog" – 儲存日誌的檔案,即日誌存於檔案 /var/log/pflog 中

第二步:在 /usr/local/etc/pf.conf 檔案中建立防火牆規則

輸入下麵這個命令開啟檔案(超級使用者樣式下):

  1. # vi /usr/local/etc/pf.conf

在檔案中新增下麵這些 PF 規則集:

  1. # vim: set ft=pf

  2. # /usr/local/etc/pf.conf

  3. ## 設定公共埠 ##

  4. ext_if="vtnet0"

  5. ## 設定伺服器公共 IP 地址 ##

  6. ext_if_ip="172.xxx.yyy.zzz"

  7. ## 設定並刪除下麵這些公共埠上的 IP 範圍 ##

  8. martians = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, \

  9.          10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, \

  10.          0.0.0.0/8, 240.0.0.0/4 }"

  11. ## 設定 http(80)/https (443) ##

  12. webports = "{http, https}"

  13. ## 啟用下麵這些服務 ##

  14. int_tcp_services = "{domain, ntp, smtp, www, https, ftp, ssh}"

  15. int_udp_services = "{domain, ntp}"

  16. ## 跳過迴環埠 - 跳過埠上的所有 PF 處理 ##

  17. set skip on lo

  18. ## 設定 PF 應該統計的埠資訊,如傳送/接收位元組數,透過/禁止的包的數目 ##

  19. set loginterface $ext_if

  20. ## 設定預設策略 ##

  21. block return in log all

  22. block out all

  23. # 基於 IP 分片的錯誤處理來防禦攻擊

  24. scrub in all

  25. # 刪除所有不可達路由地址

  26. block drop in quick on $ext_if from $martians to any

  27. block drop out quick on $ext_if from any to $martians

  28. ## 禁止欺騙包

  29. antispoof quick for $ext_if

  30. # 開啟 SSH 埠,SSH 服務僅從 VPN IP 139.xx.yy.zz 監聽 22 號埠

  31. # 出於安全原因,我不允許/接收 SSH 流量

  32. pass in quick on $ext_if inet proto tcp from 139.xxx.yyy.zzz to $ext_if_ip port = ssh flags S/SA keep state label "USER_RULE: Allow SSH from 139.xxx.yyy.zzz"

  33. ## 使用下麵這些規則來為所有來自任何 IP 地址的使用者開啟 SSH 服務 #

  34. ## pass in inet proto tcp to $ext_if port ssh

  35. ### [ OR ] ###

  36. ## pass in inet proto tcp to $ext_if port 22

  37. # Allow Ping-Pong stuff. Be a good sysadmin

  38. pass inet proto icmp icmp-type echoreq

  39. # All access to our Nginx/Apache/Lighttpd Webserver ports

  40. pass proto tcp from any to $ext_if port $webports

  41. # 允許重要的傳送流量

  42. pass out quick on $ext_if proto tcp to any port $int_tcp_services

  43. pass out quick on $ext_if proto udp to any port $int_udp_services

  44. # 在下麵新增自定義規則

儲存並關閉檔案。歡迎來參考我的規則集[1]。如果要檢查語法錯誤,可以執行:

  1. # service pf check

  1. /etc/rc.d/pf check

  1. # 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: Enabled for 0 days 00:02:18           Debug: Urgent

  2. Interface Stats for vtnet0            IPv4             IPv6

  3.  Bytes In                           19463                0

  4.  Bytes Out                          18541                0

  5.  Packets In

  6.    Passed                             244                0

  7.    Blocked                              3                0

  8.  Packets Out

  9.    Passed                             136                0

  10.    Blocked                             12                0

  11. State Table                          Total             Rate

  12.  current entries                        1              

  13.  searches                             395            2.9/s

  14.  inserts                                4            0.0/s

  15.  removals                               3            0.0/s

  16. Counters

  17.  match                                 19            0.1/s

  18.  bad-offset                             0            0.0/s

  19.  fragment                               0            0.0/s

  20.  short                                  0            0.0/s

  21.  normalize                              0            0.0/s

  22.  memory                                 0            0.0/s

  23.  bad-timestamp                          0            0.0/s

  24.  congestion                             0            0.0/s

  25.  ip-option                              0            0.0/s

  26.  proto-cksum                            0            0.0/s

  27.  state-mismatch                         0            0.0/s

  28.  state-insert                           0            0.0/s

  29.  state-limit                            0            0.0/s

  30.  src-limit                              0            0.0/s

  31.  synproxy                               0            0.0/s

  32.  map-failed                             0            0.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 return in log all

  2. block drop out all

  3. block drop in quick on ! vtnet0 inet from 172.xxx.yyy.zzz/24 to any

  4. block drop in quick inet from 172.xxx.yyy.zzz/24 to any

  5. pass in quick on vtnet0 inet proto tcp from 139.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

示例輸出:

  1. Aug 29 15: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]

  2. Aug 29 15: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]

  3. Aug 29 15: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

  4. Aug 29 15: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 1044055305 0,nop,wscale 8> (DF)

  5. Aug 29 15: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

  6. Aug 29 15: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

  7. Aug 29 15: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>

  8. Aug 29 15: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

  9. Aug 29 15: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

  10. Aug 29 15: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

  11. Aug 29 15: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

  12. Aug 29 15: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]

  13. Aug 29 15: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]

  14. Aug 29 15: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]

  15. Aug 29 15: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]

  16. Aug 29 15: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)]

  17. Aug 29 15: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)]

  18. Aug 29 15:51:33.880334 rule 0/(match) block in on vio0: 45.55.22.21.53510 > 45.FOO.BAR.IP.2362: udp 14

  19. Aug 29 15: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]

  20. Aug 29 15: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]

  21. Aug 29 15: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)

  22. Aug 29 15: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

  23. Aug 29 15: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 13511417 0,nop,wscale 2> (DF)

  24. Aug 29 15: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]

  25. Aug 29 15: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

  26. Aug 29 15: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

  27. Aug 29 15: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

  28. Aug 29 15: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

  29. Aug 29 15: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]

  30. Aug 29 15: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]

  31. Aug 29 15: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

  32. Aug 29 15: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>

  33. Aug 29 15: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

  34. Aug 29 15: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]

  35. Aug 29 15: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

  36. Aug 29 15: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]

  37. Aug 29 16: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

如果要檢視實時日誌,可以執行:

  1. # tcpdump -n -e -ttt -i pflog0

如果你想瞭解更多資訊,可以訪問 PF FAQ[2] 和 FreeBSD HANDBOOK[3] 以及下麵這些 man 頁面:

  1. # man tcpdump

  2. # man pfctl

  3. # man pf

關於作者

我是 nixCraft 的創立者,一個經驗豐富的系統管理員,同時也是一位 Linux 作業系統/Unix shell 指令碼培訓師。我在不同的行業與全球客戶工作過,包括 IT、教育、國防和空間研究、以及非營利組織。你可以在 Twitter[4]Facebook[5] 或 Google+[6] 上面關註我。


via: https://www.cyberciti.biz/faq/how-to-set-up-a-firewall-with-pf-on-freebsd-to-protect-a-web-server/

作者:Vivek Gite[8] 譯者:ucasFL 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

贊(0)

分享創造快樂