Netfilter 不是防火牆本身,而是 Linux 核心內建的封包處理框架。它在網路協議棧的關鍵路徑上預留了 5 個鉤子函數,允許核心模組註冊回調函數攔截、檢查、修改、丟棄或重新導向封包。iptables、nftables、ebtables 等用戶空間工具皆通過此框架實現規則下發。
封包流經協議棧時,依序觸發 (對應 include/uapi/linux/netfilter_ipv4.h):
| 返回值 | 含義 | 後續動作 |
|---|---|---|
NF_ACCEPT | 接受 | 繼續正常傳遞至下一鉤子或協議棧 |
NF_DROP | 丟棄 | 封包消失,不再傳遞,不發送錯誤回應 |
NF_STOLEN | 模組接管 | 模組自行處理 (如發送 ICMP 回應、重新注入),核心不再處理 |
NF_QUEUE | 排隊至用戶空間 | 交給用戶態程式 (如 nfqueue、Suricata IPS) 處理,再決定放行/丟棄 |
NF_REPEAT | 重新調用 | 再次調用同一鉤子 (慎用,易死循環) |
iptables 將規則組織為 4 張表 (Table),每表包含多條 鏈,鏈對應鉤子點。封包按優先級遍歷表與鏈。
NOTRACK 關閉連接追蹤,TRACE 除錯。鏈:PREROUTING, OUTPUT。PREROUTING --> NF_INET_PRE_ROUTING (DNAT, mangle, raw)
INPUT --> NF_INET_LOCAL_IN (filter, mangle)
FORWARD --> NF_INET_FORWARD (filter, mangle)
OUTPUT --> NF_INET_LOCAL_OUT (filter, nat, mangle, raw)
POSTROUTING --> NF_INET_POST_ROUTING (SNAT, mangle)
Linux 3.13+ 引入 nftables,統一替代 iptables/ip6tables/arptables/ebtables:
nft 管理 IPv4/IPv6/ARP/Ethernet 規則。nft add rule ip filter input tcp dport 22 accept。CentOS 8+/RHEL 8+/Debian 10+/Ubuntu 20.04+ 已預設切換 nftables (iptables 為兼容層 iptables-nft)。
使用 nf_register_net_hook() (現代 API,支援網路命名空間) 註冊 struct nf_hook_ops:
static unsigned int my_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) {
// 檢查/修改 skb
return NF_ACCEPT; // 或 NF_DROP 等
}
static struct nf_hook_ops nfho = {
.hook = my_hook,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_FIRST, // 優先級
};
int init_module() { return nf_register_net_hook(&init_net, &nfho); }
void cleanup_module() { nf_unregister_net_hook(&init_net, &nfho); }
理解 Netfilter 五大鉤子點與 iptables 四表五鏈的對應關係,是掌握 Linux 網路封包處理、編寫高效防火牆規則、開發核心網路模組、排查疑難網路問題的理論基石。現代運維應向 nftables 遷移,但底層 Netfilter 架構不變。