- NFQUEUE 允許 Netfilter 將過濾和標記決策委託給使用者空間進程,從而實現動態 IP 防火牆和路由器。
- Suricata 提供了一個多進程 IDS/IPS 引擎,支援 NFQUEUE、AF_PACKET 以及與 Snort 和新興威脅相容的規則。
- 將 NFQUEUE 與 Suricata、資料庫、Memcached 或 Pfsense 集成,即可使用免費軟體建立高級安全性和路由解決方案。
- 效能很大程度上取決於線程設計和用戶空間邏輯,因此優化和仔細選擇要檢查的流量至關重要。
如果您在 GNU/Linux(安全性和隱私性最佳的 Linux 發行版)上從事網路工作,並且對超越傳統的靜態防火牆感興趣,那麼您可能很想知道如何將 Netfilter、NFQUEUE 和 Suricata 結合起來,構建一個真正靈活的入侵檢測/防禦系統 (IDS/IPS),而無需在專有硬體上花費巨資。這正是我們將在本文中探討的內容,我們將底層元素(核心、佇列、C 語言)與進階工具(Suricata、規則、MySQL、Memcached、pfSense)融合在一起。
其核心思想非常強大:利用核心(請參閱如何優化 Linux 核心)可以將資料包排隊到用戶空間,並由自訂程式決定如何處理這些資料包。這可以用於流量過濾(進階防火牆、入侵防禦系統)、動態路由或整合業務邏輯(資料庫、快取、Web 應用程式攻擊偵測、VoIP 等)。如果我們再增加 Suricata 作為多進程入侵偵測/防禦系統引擎,就能得到一個非常強大的組合,適用於從實驗室到高流量資料中心的各種環境。
NFQUEUE 與 Netfilter:將防火牆提升至使用者空間
在典型的 GNU/Linux 系統中,Netfilter/iptables(或 nftables)規則通常作為靜態策略,完全駐留在核心空間。前端和裝置(包括許多基於 Netfilter 或 BSD Packet Filter 的解決方案)將配置儲存在文字、XML 或 SQLite 檔案中,並在配置變更時重新產生並載入規則。這種方式雖然靈活,但其邏輯仍然只是防火牆的一種快照,僅進行一些細微的動態調整(例如每秒連接數限制、連接追蹤、國家/地區匹配、是否啟用第 7 層等)。
NFQUEUE 的方案可謂顛覆性的:它不再總是由核心做出最終決定,而是將決策權委託給使用者進程。核心將封包放入編號佇列,而使用 libnetfilter_queue 函式庫的應用程式則從佇列中取出資料包,進行分析,並傳回一個判斷結果:接受、丟棄,甚至將其標記為策略路由。這就像在防火牆之上增加了一個用 C、Python 或 Perl 編寫的可編程「法官」。
這樣做的好處在於,我們的程式可以隨心所欲地執行任何操作:在回應核心之前,查詢 /dev/urandom、資料庫、Web 服務、分散式快取或複雜的演算法。從架構角度來看,防火牆不再是一組簡單的靜態規則,而變成了一個管道,其中 Netfilter、佇列和使用者應用程式像拼圖一樣完美契合。
NFQUEUE 由兩部分組成:iptables 中的 NFQUEUE 目標,用於將資料包傳送到特定佇列;以及libnetfilter_queue 使用者庫,用於讀取這些資料包並做出判斷。它並非像 tcpdump 那樣簡單的嗅探器:在這裡,我們可以直接決定封包的傳輸路徑。
使用 NFQUEUE 進行基本的 iptables 配置
從 iptables 的角度來看,使用 NFQUEUE 非常簡單:您只需在感興趣的鏈中新增一條規則,即可將符合特定條件(來源/目標 IP、連接埠、狀態、額外的模組,例如 GeoIP 或 layer7(如果可用)等)的封包傳送至佇列。
例如,如果我們想要將到達主機本身的所有 ping 請求傳送到 NFQUEUE:
iptables -I INPUT -p icmp -j NFQUEUE
這會將傳入的 ICMP 封包傳送到佇列 0(除非另有指定)。我們可以使用類似`--queue-num 3` 的參數來指定另一個佇列。使用計數器列出規則(`iptables -L -n -v -x`)時,我們會看到計數器遞增,表示封包正在排隊。一個重要的細節是:如果佇列中有資料包,但沒有使用者程序檢索和處理它們,則預設行為是拒絕這些資料包,因此,應用程式故障會導致流量被阻止,這是設計使然。
使用 libnetfilter_queue 進行程式設計:C 語言的「Hello World」程序
若要從使用者空間加入佇列,需要使用libnetfilter_queue函式庫(該函式庫又依賴 libnfnetlink)。在 Debian 等發行版上,只需安裝開發軟體包即可:
apt-get install libnfnetlink-dev libnetfilter-queue-dev gcc
一個始終接收資料包的最小程式框架由幾個非常清晰的步驟組成:打開庫,解除所有現有處理程序的綁定,綁定到 AF_INET 協議,創建帶有回調函數的隊列,定義複製模式,然後進入接收循環。回呼函數會針對每個入隊的資料包執行,提取資料包 ID 並傳回處理結果。
實際上,流程大致如下:`nfq_open` 取得句柄,`nfq_unbind_pf` 清理句柄,`nfq_bind_pf` 與 AF_INET 關聯,`nfq_create_queue` 在佇列 0 中註冊回調函數,`nfq_set_mode`` 將指示處理每個資料包。退出時,使用 `nfq_destroy_queue` 銷毀佇列,並使用 `nfq_close` 關閉句柄。
這種「Hello World」範例可以清楚衡量NFQUEUE的影響。如果我們用類似這樣的程式碼編譯範例:
gcc -o nftest code.c -lnfnetlink -lnetfilter_queue
如果我們對來自 iperf 的流量進行排隊(例如,輸入和輸出都使用 TCP 連接埠 5001),我們會發現,僅接收封包的程式碼對千兆網路的效能影響甚微。然而,這裡有一個關鍵細節:在回調函數中列印資訊(例如 printf、fflush 等)會顯著降低吞吐量,這可以透過比較啟用和停用螢幕偵錯的 iperf 測試結果來驗證。
NFQUEUE 進階選項:旁路、平衡和故障開啟
NFQUEUE 包含幾個有趣的 iptables 選項,這些選項會修改佇列的預設行為,在進入生產或高效能環境之前應該了解這些選項,因為它們會影響使用者應用程式故障或佇列填充的處理方式。
`--queue-bypass`指令可以確保在沒有進程監聽佇列時,封包不會被丟棄,而是轉送到 iptables 鏈中的下一跳。如果您希望系統在用戶服務不可用時“故障保持開放”,這將非常有用,但從安全角度來看,這把雙刃劍也會帶來風險。
`--queue-balance`選項可讓您將封包指派到一系列佇列(例如,從 0 到 3),然後讓多個獨立的進程或執行緒分別從每個佇列中消費資料包。 Netfilter 的程式碼確保來自相同資料流的資料包始終進入同一個佇列,這大大簡化了決策邏輯的一致性維護。
此外,還有`--fail-open`模式,它控制著當使用者進程運行過慢導致佇列填滿時會發生什麼。啟用此模式後,核心會直接接收資料包而不是丟棄它們,從而防止大規模流量中斷。同樣,這可能存在安全隱患,因為如果我們想要根據具體情況做出決策,丟失決策資料包就意味著無法實現該目標。
為了監控佇列的運作情況,Netfilter 在偽文件系統/proc/net/netfilter/nfnetlink_queue中公開了相關信息,可以透過腳本或監控工具輕鬆查詢。
整合業務邏輯:使用 Memcached 和 MySQL 進行測試
一旦「Hello World」流程運作正常,下一步自然就是透過呼叫外部系統來豐富回調函數。一個典型的實驗是,根據來源IP位址是否出現在任何後端(例如MySQL資料庫或Memcached快取)中來決定是否接受或拒絕封包。
對於 Memcached,首先需要安裝守護程序(使用命令 `apt-get install memcached`),然後載入一個金鑰(例如`authorized`),其中包含我們感興趣的 IP 位址。我們可以使用簡單的 `echo` 和 `netcat` 命令來完成此操作,然後使用 `get` 命令驗證該值是否已正確儲存。接下來,NFQUEUE 程式除了取得資料包 ID 外,還會使用`NFQNL_COPY_PACKET`接收整個資料包,提取 IP 頭部(`struct iphdr`),並使用 `inet_ntop` 將來源位址轉換為字串。
為了避免每次資料包都建立連線而浪費時間,Memcached 連線僅在主方法(memcached_create、memcached_server_list_append、memcached_server_push)中初始化一次,並將處理程序儲存在全域變數中。在回調函數中,使用所需的鍵呼叫 memcached_get 函數,將來源 IP 位址與檢索到的值進行比較,如果匹配,則傳回 NF_ACCEPT;否則,傳回 NF_DROP。如果鍵不存在或出現錯誤,則出於保守策略,丟棄該資料包。
使用 iperf 測試發現,這種策略在千兆網路上的吞吐量會降低到大約 140 Mbit/s,並且觀察到佇列開始出現丟包(例如,程式碼本身中的符號就表明了這一點)。換句話說,即使每個資料包都呼叫快取服務,也會產生相當大的開銷,儘管如果進行最佳化,它在中等流量的情況下仍然可行。
使用 MySQL 的方法類似,但更複雜:首先安裝伺服器和客戶端庫,然後建立一個資料庫(例如 nfqueue),其中包含一個名為 authorized(ip varchar(50)) 的簡單表,並將允許的 IP 位址插入其中。程式啟動時會執行`mysql_init` 和 `mysql_real_connect`,並在回呼函數中建構一個類似 `select * from authorized where ip like 'xxxx'` 的查詢。如果查詢成功執行並找到符合的行,則接受該套件;否則,丟棄該套件。
啟用 MySQL 查詢快取後,測試結果約為188 Mbit/s ;停用查詢快取後,速度降至103 Mbit/s 。雖然這些數據遠未達到千兆級別,但足以證明,即使採用最不理想的方法(單線程、未優化),基於數據庫或緩存的決策也能處理可觀的流量。
效能、多執行緒和 CPU 使用率
使用 iperf、Memcached 和 MySQL 進行的測試清楚地表明,效能瓶頸並非主要由 NFQUEUE 本身決定,而是由我們在使用者空間添加的邏輯及其實作方式決定。一個只返回 NF_ACCEPT 的可執行檔可以輕鬆達到近千兆的吞吐量;一旦引入 I/O 或網路調用,吞吐量就會下降,NFQUEUE 執行伺服器、Memcached 守護程序或 MySQL 的 CPU 就會達到極限。
從架構角度來看,這具有兩層意義。一方面,它證實了在考慮每次呼叫的實際成本的情況下,將防火牆決策委託給用戶應用程式來處理大量流量是完全可行的。另一方面,它表明,為了充分發揮平台的效能,必須考慮多執行緒或多進程。 NFQUEUE 允許將流量分配到多個佇列;我們可以啟動應用程式的多個副本,每個副本監聽不同的佇列,並利用多核心處理器,而無需使用 pthreads 或進行大規模的進程分叉。
另一個顯而易見的最佳化方法是限制哪些流量會通過 NFQUEUE。在測試中,整個 iperf 流都被排隊,但在實際場景中,我們可以只對狀態為 NEW 的資料包進行排隊,允許狀態為 ESTABLISHED/RELATED 的資料包通過,並將耗時的邏輯留給登入或可疑模式的處理。
歸根結底,CPU 使用率和執行緒設計是關鍵:如果使用者進程不足,佇列就會填滿,我們必須採取諸如故障開啟或接受丟棄之類的措施,從而失去這種方法旨在實現的一些精細控制。
Netfilter品牌動態路由
NFQUEUE 不僅限於簡單地「接受」或「丟棄」。它還可以用於將 Netfilter(fwmark)標誌應用於資料包,並將其與 ip 規則和 iproute2 結合使用,從而創建高度靈活、幾乎輕量級的 VRF 式策略路由方案。
大致來說,該過程如下:在/etc/iproute2/rt_tables中定義幾個路由表,例如 slow 和 fast;為每個表分配不同的預設路由(一個透過光纖,另一個透過更有限的連結表,例如 slow 和 fast;為每個表分配不同的預設路由(一個透過光纖,另一個透過更有限的連結表);使用 ip 規則指定 fwmark 為 1 的資料包進入 QUElow,fwUE 為 2 的資料包依此使用;在傳回結果之前對資料包進行適當的標記。
要從回調函數設定判決結果,可以使用`nfq_set_verdict2` 函數,它與 `nfq_set_verdict` 類似,但允許您設定一個判決值,該值隨後會被 `ip rule` 函數識別。結合所有這些,您可以建立一個 IP 路由器,該路由器可以根據任意標準決定路由方向:從奇偶資料包大小這種看似荒謬的標準,到流量預測演算法、社交媒體事件或監控系統訊號等外部輸入。
結果是,核心繼續以通常的速率轉送封包,但每個資料流的具體路徑都委託給外部軟體,該軟體可以即時改變其想法,而無需觸及靜態規則。
NFQUEUE 和 Suricata:GNU/Linux 中的高級 IPS
以上所有功能都可以用 C 語言手動編寫,但對於入侵檢測和深度包檢測而言,更明智的選擇通常是依賴成熟的 IDS/IPS 引擎。 Suricata 正是為此而生,它最初就是作為 Snort 的多進程替代方案而誕生的,從一開始就具備 IPS 功能,並著重利用當今可用的眾多 CPU 核心。
Suricata 完全從零開始編寫,並以GPLv2 許可證發布;開放資訊安全基金會 (OISF) 負責維護引擎以及相當全面的規則和文件生態系統。與繼承了單線程核心並在此基礎上進行修改的 Snort 2.x 不同,Suricata 的設計理念是將工作負載分配到多個線程上:捕獲、解碼、檢測和輸出,並採用不同的負載平衡策略。
在功能層面上,Suricata 提供對IPv6 的原生支援、第 7 層偵測(透過 HTP 函式庫實現非常高階的 HTTP)、與連接埠無關的協定識別、流重建,以及一個非常強大的會話變數(流位)系統,用於關聯跨多個 TCP 連線的攻擊的不同階段。
另一個優點是它與 Snort 規則的兼容性,以及它能夠同時使用 Sourcefire VRT 和 Emerging Threats 簽名集(免費的 ET Open 版本和商業版 ET Pro 版本)。此外,它還能以非常實用的格式(fast.log、eve.json 格式的 JSON)匯出事件,以便與 SIEM、ELK、Splunk 和其他系統整合。
Suricata 作為 Linux 中的 IPS:捕獲模式和 NFQUEUE
在 GNU/Linux 系統上,Suricata 可以根據流量攔截方式的不同以不同的模式運作:NFQUEUE、AF_PACKET、PF_RING、libpcap、NFLOG、IPFW、DAG、Napatech等。每種模式都有其自身的優點和要求。在純粹的入侵防禦系統 (IPS) 層面,最重要的兩種模式是 NFQUEUE 和 AF_PACKET。
在NFQ(NFQUEUE)模式下,流程與前面描述的類似:一組 iptables 規則將封包傳送到佇列;運行在使用者空間的 Suricata 從該佇列讀取資料包,根據其規則檢查資料包內容,並將結果傳回給核心:NF_ACCEPT、NF_DROP 或 NF_REPEAT。第三種方法(NF_REPEAT)可用於在套用其他標記或修改後,將封包重新註入到同一個 iptables 表中。
這種模式非常靈活,易於在現有基礎設施中實現,因為它只需要修改特定節點(例如,FORWARD、INPUT、OUTPUT)的規則,其他部分保持不變。其代價是需要透過 NFQUEUE 上下傳遞資料包,如果資料包數量非常大或規則資源消耗較大,則會產生上述影響。
在AF_PACKET模式下,Suricata 更靠近網路介面運行,透過 AF_PACKET 套接字複製封包。這是一種速度更快的零拷貝方法,但它要求系統作為具有兩個介面的網關運行,並且流量阻塞必須在網卡之間的轉送層執行:要阻塞的資料包根本不會從輸入介面傳遞到輸出介面。
在兩種模式下,Suricata 都可以與 Netfilter 結合使用,但NFQUEUE 特別適合我們想要重複使用所有 iptables 邏輯(策略、範圍、先前規則)並且只將我們有興趣深入檢查的流量傳送到 Suricata 的場景。
從原始碼安裝 Suricata 的基本步驟
對於那些喜歡編譯 Suricata 而不是使用軟體包的人來說,在 Debian/Ubuntu 類型的發行版上,該過程包括首先安裝編譯依賴項(build-essential、libpcre、libpcap-dev、libnet-dev、libyaml-dev、zlib、libcap-ng-dev、libjansson-dev.make ncmake-make,然後從官方網站下載經典的 installm.m.make-devm.ake .ake makem.ake 的經典網站。
在設定階段,腳本會指示已啟用哪些支援功能:AF_PACKET 是/否、PF_RING、NFQUEUE 是/否、NFLOG、IPFW、對 libnss、libjansson、Prelude、PCRE JIT、Lua、GeoIP 等的支援。如果我們想在該模式下工作,則必須驗證 NFQUEUE 是否已啟用,並且我們感興趣的捕獲庫已找到。
安裝二進位檔案後,您可以執行`make install-conf`將預設設定部署到 `/etc/suricata`,並執行`make install-rules`下載並向 `/etc/suricata/rules` 中放置一組新興威脅規則。之後,可以使用 `suricata-update` 等工具更新這些規則集。
在 Red Hat/CentOS 系統上,邏輯類似,使用 yum 或 dnf 安裝依賴項(libpcap-devel、pcre-devel、libnet-devel、libyaml-devel、jansson-devel 等),然後按照相同的步驟進行編譯。出於效能考慮,建議使用 ethtool在捕獲介面中停用 LRO/GRO,因為這些卸載功能可能會影響 IDS 層對軟體包的可見性。
Suricata 設定:YAML、變數和執行緒
Suricata 的主要設定檔位於/etc/suricata/suricata.yaml。這是一個可讀性較高且註釋詳盡的 YAML 文件,其中定義了從日誌路徑和規則集到目標作業系統策略和執行緒參數等所有內容。
其中一個基本欄位是`default-log-dir`,它指定日誌檔案的儲存位置(預設為 `/var/log/suricata`)。 `vars` 部分包含諸如 `HOME_NET`、`EXTERNAL_NET`、`HTTP_PORTS`、`SHELLCODE_PORTS` 和 `SSH_PORTS` 之類的變量,它們在規則中用作縮寫。 `HOME_NET` 通常配置為我們想要保護的本地網路範圍,而 `EXTERNAL_NET` 通常定義為 `!HOME_NET`。
另一個重要組成部分是主機作業系統策略 (host-os-policy),它告訴 Suricata 哪些作業系統應該運行特定的 IP 位址範圍。這使得 Suricata可以調整其 TCP 重組裝方式或對某些網路協定堆疊行為的解釋,從而更難利用協定堆疊之間的差異(例如 Windows 與 Linux)來規避協定。可以將特定的 IP 位址範圍指派給 Windows、Linux、BSD、Vista、Windows 2003 等類別。
關於線程設置,線程部分可讓您微調 CPU 親和性和檢測線程數。預設情況下,`set-cpu-affinity` 通常處於停用狀態,這使得系統調度器能夠將執行緒分配到各個核心上。 `detect -thread-ratio`參數指示每個可用核心建立的偵測線程數;例如,在 8 核心機器上,如果將 `detect-thread-ratio` 設定為 1.5,Suricata 將產生 12 個偵測線程,外加擷取線程和管理線程。
整個模型會在守護程式啟動時反映在輸出中:除了串流管理器和統計管理器之外,還可以看到擷取執行緒(例如 pcap)和多個偵測器執行緒。這種多進程架構使得 Suricata在面對 10/40 Gbit/s 連結時,比單執行緒引擎具有更好的擴展性。
Suricata 中的規則和簽名更新
Suricata 依靠規則集來偵測攻擊模式、異常行為和協定濫用。除了接受Snort 格式的規則外,最常見的生態系統是 Emerging Threats:ET Open(免費)和 ET Pro(商業),其規則針對當前威脅。
許多現代發行版都包含`suricata-update`工具,它可以簡化規則管理:更新來源、啟用或停用特定提供程序,以及下載最新版本的簽名集。典型的工作流程是:安裝 `suricata-update`(例如,透過 pip),執行第一個 `suricata-update` 以下載 ET Open,使用 `suricata-update list-sources` 列出來源,啟用其他來源,例如 `ptresearch/attackdetection``、``f/trap/sh/wid/list `suricata-update` 以重新產生規則檔案。
suricata.yaml 檔案已進行調整,指向正確的規則路徑。之後,Suricata 將開始觸發警報事件,這些事件將記錄在fast.log(快速、易讀的文字檔案)和 eve.json(包含非常完整資訊的結構化 JSON 檔案)中。後一種格式尤其適用於為儀錶板、關聯繫統或自訂腳本提供資料。
除了簽章之外,Suricata 還整合了多種協定的解碼器和解析器,使其對連接埠的依賴性降低:即使 HTTP 流量通過非標準端口,它也能識別它;它還能檢測不同端口和封裝等級(包括混合 IPv4/IPv6 隧道)上的 SSH、TLS、DNS 等。
實際應用:從偵測網路漏洞到自動攔截
在託管環境或資料中心中,最理想的用例之一是即時檢測利用 Web 應用程式(例如 WordPress 及其外掛程式)漏洞的嘗試,並自動做出反應,通常是透過在防火牆中封鎖或將來源 IP 列入黑名單。
Suricata 憑藉著更新後的規則,能夠識別針對 URL、參數、HTTP 有效負載甚至與已知漏洞相符的請求序列的特定攻擊模式。此入侵偵測系統 (IDS) 可以被動運行,透過交換器連接埠鏡像 (SPAN) 接收流量;但要作為入侵防禦系統 (IPS) 並阻止攻擊,則需要將其整合到轉送平面中。
有兩種常見的方法:一種是將入侵偵測系統 (IDS) 設定為線上橋接,使流量實際經過該裝置(根據平台使用 iptables、AF_PACKET 或 PF),另一種是保持網路拓撲不變,但將鏡像與透過 API、腳本或 NFQUEUE 對中央防火牆執行的操作相結合。第一種方法最大限度地減少了檢測和攔截之間的延遲,但代價是在網路「中間」增加了一個元素;第二種方法提供了更高的靈活性和彈性,但增加了編排的複雜性。
入侵偵測系統 (IDS) 完全可以偵測到試圖利用存在漏洞的 WordPress 外掛程式的行為,然後直接或透過相關元件將攻擊者的 IP 位址加入到 iptables 黑名單中。這可以透過Suricata 的 JSON 輸出和調用 iptables/nftables 的腳本來實現,也可以透過將部分邏輯委託給 NFQUEUE 來實現,NFQUEUE 引擎本身或相關進程可以即時做出決策,而無需等待外部列表更新。
這樣一來,您就可以專注於真正重要的威脅(漏洞利用、權限提升嘗試、非常激進的掃描),而忽略或僅記錄背景噪音,例如基本的連接埠掃描,這些掃描在許多情況下本身並不令人擔憂。
PfSense 上的 Suricata:整合了 IDS/IPS 的開源防火牆
並非每個人都能或願意購買像 Palo Alto 這樣的高階專有防火牆。在許多環境下,使用 pfSense 和 Suricata 建立開源解決方案更具吸引力,它既能滿足進階防火牆需求(多 WAN、VLAN、VPN、NAT 等),又能提供 IDS/IPS 功能。
基於 FreeBSD 和封包過濾器的 Pfsense 在虛擬化環境(Proxmox、KVM 等)中表現特別出色,但有一點例外:如果想要避免在高負載下出現效能問題和崩潰,建議在 KVM 機器中使用 E1000 網路卡而不是 Virtio 網路卡,除非您採納 Netgate的建議(在“系統”>“高級”>“網路”中禁用硬體校驗和卸載並重新啟動,但請注意,在高負載下,這可能還不夠)。
在 Pfsense 上運行 Suricata 的實驗室的最低硬體要求可能比較低(1 個 500 MHz 的 CPU、1 GB 內存、4 GB 磁碟),但對於嚴肅的使用,建議至少使用 2 個 CPU、4 GB 內存和 16 GB 存儲空間,不要忘記配備多個網絡接口(一個用於 WAN,另一個
安裝 pfSense 本身非常快速:從 ISO 映像啟動,接受許可協議,選擇安裝,選擇語言和鍵盤佈局,分割區設定為自動(如果要使用整個磁碟,則選擇自動 UFS),幾分鐘後系統即可啟動。控制台提供了一個選單,用於分配介面、重新啟動、啟動 shell 等。
例如在實驗室的 VirtualBox 中,通常會使用 pfctl -d 從控制台暫時停用 Pfsense 防火牆,以便透過 WAN 存取 Web 介面(使用者名稱 admin,密碼 pfsense),並完成初始精靈:常規資料、NTP 伺服器、WAN 設定(在實驗室中 DHCP 通常就足夠了)、LAN、更改管理員密碼和應用程式設定。
一旦存取穩定,您可以在 WAN 防火牆中建立規則,允許任何來源的 HTTPS 流量存取 pfSense 的 IP 位址,並添加描述性分隔符號以方便地組織規則(例如,「防火牆存取」)。如果您在測試環境中使用 RFC1918 位址,建議停用 WAN 上封鎖專用網路的選項,以避免頻繁使用 `pfctl -d` 指令。
在 pfSense 上安裝 Suricata 及概述
pfSense 基礎系統啟動並運作後,安裝 Suricata 非常簡單:只需依序進入「系統」>「軟體套件管理器」>「可用軟體套件」,搜尋 Suricata 並安裝即可。該過程會下載多個文件,耗時可能因硬體配置而異,但整個過程都會透過 Web 介面提供全程協助。
安裝完成後,Suricata 的條目會出現在「服務」標籤中,您可以在其中按介面(WAN、LAN、VLAN 等)設定實例,選擇要使用的規則集,啟動 IDS 或 IPS 模式,以及調整效能和日誌記錄參數。選項非常豐富(僅配置部分就足以寫成幾篇文章),但其優勢在於,許多在 Linux 中需要手動編輯 YAML 檔案的任務,在這裡都可以透過表單和複選框輕鬆完成。
重要提示:雖然在實驗室環境中直接將 pfSense 管理介面暴露在互聯網上可能很誘人,但在生產環境中,必須限制對靜態 IP 位址的訪問,使用 VPN 進行遠端管理,並務必避免 Web 控制台暴露在外。 pfSense 非常靈活,但同時也必須將其視為至關重要的組件。
在 pfSense 上啟用 Suricata 後,網路流量會先經過 pfSense 進行防火牆和 NAT 處理,然後由Suricata 根據其規則進行檢查,並在 IPS 模式下阻止流量。這種組合透過單一的 Web 介面進行管理,大大簡化了在中小型網路中部署 DPI 防護的過程。
在許多部署中,Pfsense/Suricata 與 SIEM 或集中式日誌平台連接起來,利用結構化的輸出格式來關聯事件並偵測更廣泛的攻擊活動,從而起到補充作用。
Suricata 中的事件監控和範例日誌
Suricata 執行後,事件會被記錄到預設日誌目錄定義的路徑中,通常是/var/log/suricata。 fast.log檔案使用緊湊的文字格式,包含時間戳記、規則 ID、分類和優先級,適合從終端快速查看(tail -f)。
例如,當遇到 TCP 校驗和錯誤的流量時,我們可能會看到類似這樣的資訊行:包含日期和時間的時間戳,後跟規則識別碼(例如 1:2200074:1)、訊息「SURICATA TCPv4 校驗和無效」、分類、優先權以及來源-目標 IP/連接埠對。這類警報有助於快速識別資料包完整性問題或規避嘗試。
eve.json 檔案包含 JSON 格式的相同事件,欄位包括 timestamp、event_type、src_ip、dest_ip、src_port、dest_port 和 proto,以及一個包含 action、gid、signature_id、rev、signature、category 和 severity 等資訊的警告子檔案。這種格式可以輕鬆地被 Logstash、Fluentd、Filebeat 或任何其他日誌代理程式讀取,從而實現比純文字更豐富的分析功能。
在多核心伺服器(例如 8 核心)上部署 Suricata 時,執行緒壓縮在 htop 等工具的執行緒模式下非常明顯,會顯示一個或多個擷取執行緒(pcap、AF_PACKET 或 NFQ)以及大量分佈在各個核心上的偵測執行緒。當流量接近平台極限時,調整偵測執行緒比例和 CPU 親和性可以顯著影響吞吐量和延遲。
在部署到生產環境之前,建議花點時間微調已啟動的規則集,以避免大量誤報,阻止合法流量或使日誌變得混亂。 Suricata-update 可讓您停用整個類別或單一規則,以便在靈敏度和可用性之間找到合理的平衡點。
特殊應用:VoIP、音訊分析與創意 NFQUEUE
除了經典用途(Web 服務保護、惡意軟體偵測、DDoS 分析)之外,Netfilter + NFQUEUE 組合還能在 VoIP 等領域實現極具創意的解決方案。例如,可以設定反 SPIT(IP 電話垃圾郵件)過濾器,或用於審查RTP 流中不雅詞彙的系統。
其思路是:透過連接埠或協定識別來識別 RTP 流量,並將其發送到 NFQUEUE;從用戶應用程序,使用 librtp 等庫重建 RTP 流量,提取 WAV 格式的音頻,並將其傳遞給關鍵字識別引擎(詞點識別),例如第三方提供的合成或識別庫。
根據偵測到的詞語,NFQUEUE 進程可以決定允許、阻止甚至透過在音訊串流中插入嗶聲來改變播放,儘管後者需要對 RTCP、封包序列和時間進行非常精細的控制——幾乎是一種中間人攻擊。這並非易事,但理論上可以透過利用相同的隊列和判定係統來實現。
確實,其中一些操作可以透過簡單的嗅探器將資料傳輸到外部處理器,然後對 SIP 訊號或透過 SBC(例如 Asterisk、Kamailio 等)進行處理來實現。使用 NFQUEUE 的差異在於,它可以立即直接地對 RTP 流進行操作,而無需協調多個元件或等待訊號層完成呼叫。
這些場景清楚地說明了 GNU/Linux + Netfilter + Suricata + 第三方庫組合的潛力:它不僅僅是阻止連接埠和 IP 位址,而是使用 100% 自由軟體生態系統即時協調複雜的流量決策。
從始終接受資料包的小型 C 程式到整合了 NFQUEUE、Pfsense、資料庫和快取的多進程 Suricata 部署,縱觀整個發展歷程,人們可以體會到該技術棧的靈活性,它能夠構建從簡單的動態防火牆到資料中心規模的 IDS/IPS 架構,具備真正的深度檢測能力,並能自動響應日益複雜的攻擊。