「照著網路教學一步一步裝好 pfSense,LAN 這端明明通了,就是連不上網。」還有另一個版本更折磨人:「VPN 儀表板上白紙黑字寫著已連線,我卻 ping 不到公司內網的任何一台機器。」這兩句話,幾乎是每一位剛踏進開源防火牆世界的工程師都講過的開場白。pfSense 與 OPNsense 都長在 FreeBSD 上,底層跑的是同一顆 pf 封包過濾引擎,連選單長相都像到會認錯,但兩套在預設行為、規則的處理順序,以及設定藏在哪一頁這些地方,差異多到足以讓人卡上一整個週末。以下整理開源防火牆最常見的幾類設定地雷,連同兩套之間那些魔鬼藏在細節裡的差別,一次攤開講清楚,順便補上底層機制,讓你知道「為什麼」,而不只是「照抄哪一步」。
裝好卻上不了網,先從 WAN 與 NAT 這兩層拆
WAN 拿不到 IP 或有位址卻不能上網,先核對 WAN lease、gateway、route 與 firewall log,再看上游是否有 MAC 綁定;數據機斷電或 MAC clone 只能依 ISP 流程使用,不能當通則。若 WAN 拿到 RFC1918 私有位址,Block private networks 可能在私有 WAN/雙重 NAT 情境造成阻擋;Block bogon networks 則是另一份保留與未分配位址清單,不應因為雙重 NAT 就一起關掉。只調整日誌證明有影響的選項,Apply 後逐項驗證 WAN、DNS、NAT 與管理存取;公網 WAN 通常仍應保留 ingress filtering。可對照 Netgate 防火牆規則說明。
如果 WAN 正常、換成 LAN 這端出不去,該看的是 Outbound NAT。到 Firewall > NAT > Outbound 確認模式停在 Automatic 或 Hybrid;最怕的是前手把它切成 Manual,之後又陸續加了新的子網或 VLAN,卻忘了替新網段補上翻譯規則。少了這條,內部位址根本沒被換成對外的公有 IP,外面的伺服器收到一個私有來源位址,回應自然送不回來,對使用者而言就是「連不上」。排查時把「翻譯有沒有發生」單獨拉出來確認,通常一抓就中。
還有一種假性斷網特別會騙人:用 IP 直接 ping 得通、換成網址就不通。這幾乎可以當場確診是 DNS 出事。pfSense 與 OPNsense 內建的都是 Unbound,先試著把它在遞迴解析(Resolver)與轉發(Forwarder)兩種模式之間切一下,很多時候一換就活。這裡要補一個容易踩的坑:兩套預設都開著 DNS Rebinding 防護,它會把 DNS 回應裡的私有位址整段濾掉:立意是防止外部 DNS 拿私有 IP 對你發動 rebinding 攻擊,但如果你的上游 DNS 或內部服務本來就需要回傳私有位址,它就會把好人一起錯殺,症狀同樣是「查得到公網、查不到內網」。診斷順序很固定:先用 Diagnostics > Ping 把來源分別指定成 LAN 與 WAN 逐段打,確認斷在哪一跳,再用 Packet Capture 直接趴在 WAN 上抓封包,看它是否離開防火牆。斷點落在哪一層,一目了然。
規則明明加了卻沒生效?關鍵在順序,還有兩套的性格差異
防火牆規則有一條原則先背起來:由上往下讀、第一條命中就定生死,而且只過濾「封包進來的那個介面」。新手最常犯的錯,是想管內網對外的流量,卻把規則寫到了 WAN 分頁上。那些流量是從 LAN 進來的,防火牆只會拿 LAN 分頁的規則去比對,WAN 分頁的規則從頭到尾都輪不到它上場。另一個高頻情境是規則改了卻像沒改:那多半是既有的連線早就在 state table 裡建好了狀態,後續封包直接命中舊 state、繞過重新評估。到 Diagnostics > States 把相關的 state 清掉,連線就會依照新規則重新走一遍。
接著是 pfSense 與 OPNsense 最容易把人繞暈的地方:規則的處理順序與 quick 旗標。兩套的整體順序都是浮動規則(Floating)先跑、再到介面群組(Interface Group)、最後才輪到各介面自己的規則。真正的分歧在 quick:勾了 quick 的規則是「第一條符合就停手」,沒勾 quick 的規則則是「最後符合的那條勝出」(last match wins)。而浮動規則在不勾 quick 時,走的正是這套與其他分頁相反的邏輯。OPNsense 更進一步把系統內建規則也納入同一條處理鏈,它的 default deny(預設拒絕)就是靠一條掛在系統規則尾端、非 quick、最後才符合的規則實作出來的。於是在同一台 OPNsense 上,「介面規則的 quick 等於先到先贏」和「非 quick 浮動規則等於後到者贏」兩種相反的邏輯是並存的,難怪很多人排錯排到懷疑人生。實務上的建議其實很單純:絕大多數規則都把 Quick 勾起來,讓行為回到直覺的「由上而下、先符合先算」,只有極少數刻意要做例外覆蓋的場合才留白。
要確認實際是哪一條規則命中,別用猜的。看防火牆 log 每一列後面的 Tracker ID,能直接對回是哪一條規則;或者乾脆進 shell,用 pfctl -sr 把實際生效的規則集整份倒出來、用 pfctl -ss 看目前的 state,眼見為憑。工程上一個常被忽略的心法是:規則是「宣告意圖」,state 才是「當下事實」,兩者不一致時,永遠以 state 為準去回推。
NAT 與 port forward:先搞懂「NAT 比防火牆早一步」
對外開放服務的 port forward 打不通,先把一個核心觀念記住:封包進來時,NAT 是在防火牆規則之前先套用的。這代表你替 port forward 補的那條 WAN 防火牆規則,目的地要填「翻譯之後的內部 IP」,而不是 WAN 的公有 IP:因為輪到防火牆檢查時,目的地早就被 NAT 改寫成內部位址了,你若還填公網 IP,這條規則永遠不會命中。pfSense 的 port forward 預設會很貼心地連動幫你生一條對應的防火牆規則(Filter rule association),OPNsense 則從 26.1 版起把這個入口正式改名叫 Destination NAT,找的地方不一樣,別在舊選單裡繞圈。
第二個經典的假故障,是有人習慣站在內網去測試對外的 port forward。port forward 預設就只從外網方向生效,你從內網打當然不會通。要嘛拿手機開 4G 從外面測,要嘛就得動用 NAT Reflection,讓內網也能用公網 IP 繞回來。但這裡有個更漂亮的解法,也是官方更推薦的方向:直接改用 Split DNS。做法是在 DNS Resolver 裡加一筆 Host Override,把同一個網域名稱在內部直接解析到那台伺服器的私有 IP。這樣一來內網對內網是直接路由過去的,封包根本不用繞進防火牆做反射(hairpin),不但少一跳、延遲更低,伺服器端看到的還是內網主機真實的來源 IP,日誌乾淨、權限與稽核也好做,能用 Split DNS 就別用反射。唯一要記得的是前面提過的 DNS Rebinding 防護:用 Host Override 是本機自己給答案,不受影響;但若你是靠轉發模式讓上游回私有位址,就得為那個網域開白名單,否則答案會被濾掉。
VPN「連得上卻不通流量」,多數是這三件事
VPN 儀表板顯示已連線、實際上卻半個封包都過不去,這種「看得到、摸不到」的狀況,追根究柢幾乎都落在三件事之一:VPN 介面的分頁上少了放行規則、兩端的子網路由對不上、或是少了 Outbound NAT。分協定來看:
- OpenVPN:伺服器設定裡的 IPv4 Local network 一定要填上你的 LAN 子網。這個欄位是「要推給用戶端的路由」,留白就等於 client 連得上防火牆本身、卻拿不到通往內網的路,正是「連線成功卻進不了內網」最標準的成因。
- WireGuard:這裡藏著一顆獨門大雷:AllowedIPs 同時扮演兩個角色,它既是送出方向的路由表,也是收進方向的加密白名單。WireGuard 用的是所謂的 cryptokey routing:送封包時靠目的地 IP 去挑要加密給哪個對端,收封包時只有當解密後的來源 IP 落在該對端的 AllowedIPs 範圍內才會被接受,否則即使握手成功、封包也照樣直接丟棄。所以兩端的 AllowedIPs 都必須同時涵蓋對端的通道端點加上對端的 LAN 子網,只要漏了對端 LAN,就是「handshake 成功、卻 ping 不到內網」的頭號元兇。這裡要特別破除一個迷思:握手成功只證明了 UDP 封包互相到得了、金鑰也對得上,它完全不代表回程路由、NAT 或封包轉發有設好。排 WireGuard 建議照固定順序走一遍:防火牆放行、UDP 埠、金鑰、AllowedIPs、NAT、兩端時鐘、MTU,一項一項排除。
- IPsec:重點在 Phase 2 的本地與遠端網段必須對稱。最常見的錯誤,是把某一端填成單一主機 IP(例如 /32)而不是整個網段,兩邊的 traffic selector 對不齊,通道建得起來、流量卻協商不過去。
還有一個多 WAN 環境專屬的暗坑值得單獨拉出來講:reply-to。在 WAN 類型的介面規則上,pf 會自動替你加上 reply-to,強制「從哪個 WAN 進來,回程就從同一個 WAN 出去」,這在絕大多數情況下是好事,能避免多線路環境的回程亂跑。但如果你在某個內部介面上手動指定了 gateway,pf 會替它的規則同時打上 route-to 與 reply-to 標記,強迫封包走那個 gateway,而不是它原本該走的自然路徑,拓樸一特殊就會冒出非對稱路由,讓連線莫名其妙斷掉。碰到 VPN 或多 WAN 下「單向通、回程不通」的怪象,reply-to 與 route-to 是第一個要懷疑的對象,可在規則的進階選項裡把它關掉再測。
效能與 offload:那個沒人注意、卻最會咬人的隱形殺手
如果你的環境是 Realtek 網卡、或跑在虛擬化平台上(virtio、KVM 那一類),又出現那種抓不到規律、時好時壞的間歇性丟包,第一個該懷疑的就是 hardware offload(硬體卸載)。網卡的 Checksum、TSO、LRO 這些卸載功能,本意是把一部分工作從 CPU 搬到網卡上,對一台「端點主機」是好事;但對一台「防火牆/路由器」而言,它要做的是轉發別人的封包,這些 offload 反而會去改動封包內容、打亂 pf 的計算,甚至製造額外負載,結果就是那種查半天查不出所以然的丟包。把 Checksum、TSO、LRO 的卸載關掉,pfSense 的開關在 System > Advanced > Networking,OPNsense 則在 Interfaces > Settings,兩套位置不一樣,別找錯頁。
要上 Suricata 或 Snort 做 inline IPS 的話,這件事就不是建議、而是硬性前提了。inline 模式底層靠的是 netmap,而 netmap 與硬體 offload 天生不相容,官方明文要求把相關的卸載選項全部關掉。實際檢查介面時,TXCSUM、RXCSUM、TSO4、TSO6、LRO、TXCSUM6、RXCSUM6 這幾個旗標都不該出現;如果從介面上關了還關不掉,就得改實際層設定強制關。好消息是,這個關閉只需要針對指派給 Suricata 的那幾個介面做,不必全機一刀切。順帶提醒幾個工程判斷:IDS 與 IPS 建議掛在 LAN 介面而不是 WAN,因為在 LAN 看到的是還沒被 NAT 攪動的乾淨內部位址、雜訊也少,規則的動作記得設成 drop 才是真的攔下來,只設 alert 就只是記帳;而 Suricata 吃的是單線程 CPU 效能與記憶體,1GB RAM 是地板、規則開多了 2GB 起跳,別拿一台小盒子硬扛滿載規則集。
幾個把效能榨出來、以及避免翻車的關鍵旋鈕,也一併記著:
- mbuf 緩衝耗盡會直接讓核心 panic 重開,特別是多佇列網卡或高流量環境。64 位元、記憶體充足的機器,把 mbuf cluster 從預設拉到 1000000(一百萬)是個安全的起跳點,用 netstat -m 就能看目前 mbuf 用到哪、有沒有見底。
- 跑 PPPoE 上網的環境(台灣很多中小企業的線路就是這種),會遇到 PPPoE 本質上偏單線程、吃不滿多核的老問題,把封包分派改成 net.isr.dispatch=deferred 常能換來明顯的吞吐提升。
- VPN 流量重的環境,AES-NI 硬體加解密值得認真看待,開了之後加密速度相較純軟體大約有三到五倍的差距,選機器時 CPU 有沒有 AES-NI 幾乎是必選項,別讓加解密變成整條線路的瓶頸。
臨場排效能問題的三把刀:shell 裡的 pftop 看即時連線分布、top -aSH 看是哪一顆核心被單一工作打到滿載、netstat -m 看 mbuf 有沒有告急。哪裡是瓶頸,數字會說話。