Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 防火牆框架深度解析:Netfilter 五大核心組件與 iptables/nftables 實作

編輯:Linux 教學

Linux 核心網路封包處理的靈魂是 Netfilter 框架。它在核心協定棧的五個關鍵點掛載 Hook,讓核心模組(如 iptables、nftables、連線追蹤、NAT)得以攔截、修改、裁決封包。本文從架構層面剖析 Netfilter 五大組件、五大 Hook 點、裁決回傳值、三大表(filter/nat/mangle)運作邏輯,並說明如何編寫核心模組掛載 Hook。

Netfilter 五大核心組件

  1. 協定專屬 Hook 定義:為每種網路協定(IPv4、IPv6、ARP、Bridge)定義一組 Hook 函數。IPv4 定義 5 個 Hook(見下節),IPv6 同樣 5 個,Bridge/ARP 各有專屬 Hook。
  2. 核心模組註冊與回呼機制:任意核心模組可對特定協定的特定 Hook 註冊回呼函數(nf_hookfn)。封包流經 Hook 時,核心依優先順序調用所有已註冊的回呼,模組可檢查、修改、丟棄、佇列、重導封包。
  3. 使用者空間佇列處理:裁決為 NF_QUEUE 的封包被移至使用者空間佇列(nfnetlink_queue),由用戶態程式(如 libnetfilter_queue 應用)非同步處理,處理完可重新注入核心同一 Hook 繼續流程。
  4. 丟棄前檢查機制:IP 層即將丟棄的封包(如路由不可達、校驗和錯誤)在真正丟棄前仍會觸發 Hook,允許模組檢查(如偵測 IP Spoofing 封包)。
  5. IPv4 五大 Hook 點位置與語意(核心原始碼 include/uapi/linux/netfilter_ipv4.h 定義):

IPv4 五大 Hook 點詳表

Hook 常數位置(核心路徑)典型應用
NF_IP_PRE_ROUTING (0)封包剛進入網路層,完成版本/校驗和檢查後DNAT(目的位址轉換)、透明代理、策略路由標記
NF_IP_LOCAL_IN (1)路由查詢後,確定送往本機INPUT 鏈過濾、本機服務存取控制
NF_IP_FORWARD (2)路由查詢後,確定需轉發FORWARD 鏈過濾、轉發封包 NAT
NF_IP_POST_ROUTING (3)封包即將送出網路介面前SNAT(來源位址轉換)、MASQUERADE、封包標記輸出
NF_IP_LOCAL_OUT (4)本機進程產生的封包進入網路層前OUTPUT 鏈過濾、本機輸出 NAT、封包標記

模組回傳裁決值

值語意
NF_ACCEPT繼續正常傳遞
NF_DROP悄悄丟棄,不回應發送端
NF_STOLEN模組接管封包,核心不再處理(如直接在核心回應 ICMP)
NF_QUEUE送入使用者空間佇列待處理
NF_REPEAT重新調用同一 Hook(罕用,需極度小心避免迴圈)

三大表在 Netfilter 框架中的掛載

  • filter 表(封包過濾):掛載於 NF_IP_LOCAL_IN、NF_IP_FORWARD、NF_IP_LOCAL_OUT。每個封包只經過一個過濾點(優於 iptables 早期 ipchains 多次遍歷)。
  • nat 表(位址轉換):掛載於 NF_IP_PRE_ROUTING (DNAT)、NF_IP_POST_ROUTING (SNAT)、NF_IP_LOCAL_OUT (本機輸出 DNAT)。只有連線第一個封包遍歷規則,後續封包依連線追蹤條目直接套用相同轉換。
  • mangle 表(封包修改/標記):掛載於 NF_IP_PRE_ROUTING、NF_IP_LOCAL_OUT。支援修改 TOS/DSCP、設定 skb->mark(供 tc/ip rule 策略路由使用)。

編寫核心模組掛載 Hook 範例

#include 
#include 
#include 
#include 
#include 

static struct nf_hook_ops nfho = {
    .hook     = my_hook_fn,
    .pf       = PF_INET,
    .hooknum  = NF_IP_PRE_ROUTING,
    .priority = NF_IP_PRI_FIRST,  // 最高優先級
};

unsigned int my_hook_fn(void *priv, struct sk_buff *skb,
                        const struct nf_hook_state *state)
{
    struct iphdr *iph = ip_hdr(skb);
    if (!iph || iph->protocol != IPPROTO_TCP) return NF_ACCEPT;

    struct tcphdr *tcph = tcp_hdr(skb);
    if (tcph->dest == htons(80)) {
        printk(KERN_INFO "HTTP request to %pI4:%d\n", &iph->daddr, ntohs(tcph->dest));
        // 可在此修改封包、丟棄、標記
    }
    return NF_ACCEPT;
}

static int __init my_init(void) {
    return nf_register_net_hook(&init_net, &nfho);
}
static void __exit my_exit(void) {
    nf_unregister_net_hook(&init_net, &nfho);
}
module_init(my_init);
module_exit(my_exit);
MODULE_LICENSE("GPL");

關鍵結構體欄位:
- list:初始化為 {NULL, NULL}。
- pf:協定族(PF_INET IPv4)。
- hooknum:Hook 號(0~4)。
- priority:優先級,數值越小越早執行。參考 netfilter_ipv4.h 內建優先級列舉(NF_IP_PRI_FIRST、NF_IP_PRI_CONNTRACK、NF_IP_PRI_MANGLE、NF_IP_PRI_NAT_DST、NF_IP_PRI_FILTER、NF_IP_PRI_NAT_SRC、NF_IP_PRI_LAST)。

從 iptables 到 nftables:統一框架

nftables(Linux 3.13+)取代 iptables/ip6tables/arptables/ebtables,提供單一 CLI(nft)、統一核心 API(nf_tables)、原生支援集合/字典/遞迴集合、原子式規則更新、JSON 輸出。底層仍複用 Netfilter 相同 5 大 Hook,但規則評估引擎改為虛擬機器(nft_expr),效能與擴充性大幅提升。

總結

Netfilter 以「Hook + 註冊回呼 + 裁決值」極簡抽象,支撐起 Linux 整個封包處理生態。理解五大 Hook 語意、三大表掛載點、優先級排序,是進階網路除錯、開發核心模組、設計高效能防火牆規則的基石。

Copyright © Windows教程網 All Rights Reserved