0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux內(nèi)核中Netfilter的設(shè)計(jì)與實(shí)現(xiàn)

xCb1_yikoulinux ? 來源:云原生實(shí)驗(yàn)室 ? 作者:Waynerv ? 2022-05-26 15:27 ? 次閱讀

Netfilter (配合 iptables)使得用戶空間應(yīng)用程序可以注冊內(nèi)核網(wǎng)絡(luò)棧在處理數(shù)據(jù)包時(shí)應(yīng)用的處理規(guī)則,實(shí)現(xiàn)高效的網(wǎng)絡(luò)轉(zhuǎn)發(fā)和過濾。很多常見的主機(jī)防火墻程序以及 Kubernetes 的 Service 轉(zhuǎn)發(fā)都是通過 iptables 來實(shí)現(xiàn)的。

關(guān)于 netfilter 的介紹文章大部分只描述了抽象的概念,實(shí)際上其內(nèi)核代碼的基本實(shí)現(xiàn)不算復(fù)雜,本文主要參考 Linux 內(nèi)核 2.6 版本代碼(早期版本較為簡單),與最新的 5.x 版本在實(shí)現(xiàn)上可能有較大差異,但基本設(shè)計(jì)變化不大,不影響理解其原理。

本文假設(shè)讀者已對 TCP/IP 協(xié)議有基本了解。

Netfilter 的設(shè)計(jì)與實(shí)現(xiàn)

netfilter 的定義是一個(gè)工作在 Linux 內(nèi)核的網(wǎng)絡(luò)數(shù)據(jù)包處理框架,為了徹底理解 netfilter 的工作方式,我們首先需要對數(shù)據(jù)包在 Linux 內(nèi)核中的處理路徑建立基本認(rèn)識(shí)。

數(shù)據(jù)包的內(nèi)核之旅

數(shù)據(jù)包在內(nèi)核中的處理路徑,也就是處理網(wǎng)絡(luò)數(shù)據(jù)包的內(nèi)核代碼調(diào)用鏈,大體上也可按 TCP/IP 模型分為多個(gè)層級,以接收一個(gè) IPv4 的 tcp 數(shù)據(jù)包為例:

  1. 在物理-網(wǎng)絡(luò)設(shè)備層,網(wǎng)卡通過 DMA 將接收到的數(shù)據(jù)包寫入內(nèi)存中的ring buffer,經(jīng)過一系列中斷和調(diào)度后,操作系統(tǒng)內(nèi)核調(diào)用 __skb_dequeue 將數(shù)據(jù)包加入對應(yīng)設(shè)備的處理隊(duì)列中,并轉(zhuǎn)換成 sk_buffer 類型(即 socket buffer - 將在整個(gè)內(nèi)核調(diào)用棧中持續(xù)作為參數(shù)傳遞的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),下文指稱的數(shù)據(jù)包都可以認(rèn)為是 sk_buffer),最后調(diào)用 netif_receive_skb 函數(shù)按協(xié)議類型對數(shù)據(jù)包進(jìn)行分類,并跳轉(zhuǎn)到對應(yīng)的處理函數(shù)。如下圖所示:

7add4c74-dca8-11ec-ba43-dac502259ad0.png

network-path

  1. 假設(shè)該數(shù)據(jù)包為 IP 協(xié)議包,對應(yīng)的接收包處理函數(shù)ip_rcv將被調(diào)用,數(shù)據(jù)包處理進(jìn)入網(wǎng)絡(luò)(IP)層。ip_rcv檢查數(shù)據(jù)包的 IP 首部并丟棄出錯(cuò)的包,必要時(shí)還會(huì)聚合被分片的 IP 包。然后執(zhí)行ip_rcv_finish函數(shù),對數(shù)據(jù)包進(jìn)行路由查詢并決定是將數(shù)據(jù)包交付本機(jī)還是轉(zhuǎn)發(fā)其他主機(jī)。假設(shè)數(shù)據(jù)包的目的地址是本主機(jī),接著執(zhí)行的dst_input函數(shù)將調(diào)用ip_local_deliver函數(shù)。ip_local_deliver函數(shù)中將根據(jù) IP 首部中的協(xié)議號(hào)判斷載荷數(shù)據(jù)的協(xié)議類型,最后調(diào)用對應(yīng)類型的包處理函數(shù)。本例中將調(diào)用 TCP 協(xié)議對應(yīng)的tcp_v4_rcv函數(shù),之后數(shù)據(jù)包處理進(jìn)入傳輸層。

  2. tcp_v4_rcv函數(shù)同樣讀取數(shù)據(jù)包的 TCP 首部并計(jì)算校驗(yàn)和,然后在數(shù)據(jù)包對應(yīng)的 TCP control buffer 中維護(hù)一些必要狀態(tài)包括 TCP 序列號(hào)以及 SACK 號(hào)等。該函數(shù)下一步將調(diào)用__tcp_v4_lookup查詢數(shù)據(jù)包對應(yīng)的 socket,如果沒找到或 socket 的連接狀態(tài)處于TCP_TIME_WAIT,數(shù)據(jù)包將被丟棄。如果 socket 處于未加鎖狀態(tài),數(shù)據(jù)包將通過調(diào)用tcp_prequeue函數(shù)進(jìn)入prequeue隊(duì)列,之后數(shù)據(jù)包將可被用戶態(tài)的用戶程序所處理。傳輸層的處理流程超出本文討論范圍,實(shí)際上還要復(fù)雜很多。

netfilter hooks

接下來我們正式進(jìn)入主題。netfilter 的首要組成部分是 netfilter hooks。

hook 觸發(fā)點(diǎn)

對于不同的協(xié)議(IPv4、IPv6 或 ARP 等),Linux 內(nèi)核網(wǎng)絡(luò)棧會(huì)在該協(xié)議棧數(shù)據(jù)包處理路徑上的預(yù)設(shè)位置觸發(fā)對應(yīng)的 hook。在不同協(xié)議處理流程中的觸發(fā)點(diǎn)位置以及對應(yīng)的 hook 名稱(藍(lán)色矩形外部的黑體字)如下,本文僅重點(diǎn)關(guān)注 IPv4 協(xié)議:

7af814aa-dca8-11ec-ba43-dac502259ad0.png

netfilter-flow

所謂的 hook 實(shí)質(zhì)上是代碼中的枚舉對象(值為從 0 開始遞增的整型):

enum nf_inet_hooks { NF_INET_PRE_ROUTING, NF_INET_LOCAL_IN, NF_INET_FORWARD, NF_INET_LOCAL_OUT, NF_INET_POST_ROUTING, NF_INET_NUMHOOKS };

每個(gè) hook 在內(nèi)核網(wǎng)絡(luò)棧中對應(yīng)特定的觸發(fā)點(diǎn)位置,以 IPv4 協(xié)議棧為例,有以下 netfilter hooks 定義:

7b268d6c-dca8-11ec-ba43-dac502259ad0.png

netfilter-hooks-stack

  • NF_INET_PRE_ROUTING: 這個(gè) hook 在 IPv4 協(xié)議棧的ip_rcv 函數(shù)或 IPv6 協(xié)議棧的 ipv6_rcv 函數(shù)中執(zhí)行。所有接收數(shù)據(jù)包到達(dá)的第一個(gè) hook 觸發(fā)點(diǎn)(實(shí)際上新版本 Linux 增加了 INGRESS hook 作為最早觸發(fā)點(diǎn)),在進(jìn)行路由判斷之前執(zhí)行。

  • NF_INET_LOCAL_IN: 這個(gè) hook 在 IPv4 協(xié)議棧的ip_local_deliver() 函數(shù)或 IPv6 協(xié)議棧的 ip6_input() 函數(shù)中執(zhí)行。經(jīng)過路由判斷后,所有目標(biāo)地址是本機(jī)的接收數(shù)據(jù)包到達(dá)此 hook 觸發(fā)點(diǎn)。

  • NF_INET_FORWARD: 這個(gè) hook 在 IPv4 協(xié)議棧的ip_forward() 函數(shù)或 IPv6 協(xié)議棧的 ip6_forward() 函數(shù)中執(zhí)行。經(jīng)過路由判斷后,所有目標(biāo)地址不是本機(jī)的接收數(shù)據(jù)包到達(dá)此 hook 觸發(fā)點(diǎn)。

  • NF_INET_LOCAL_OUT: 這個(gè) hook 在 IPv4 協(xié)議棧的__ip_local_out() 函數(shù)或 IPv6 協(xié)議棧的 __ip6_local_out() 函數(shù)中執(zhí)行。所有本機(jī)產(chǎn)生的準(zhǔn)備發(fā)出的數(shù)據(jù)包,在進(jìn)入網(wǎng)絡(luò)棧后首先到達(dá)此 hook 觸發(fā)點(diǎn)。

  • NF_INET_POST_ROUTING: 這個(gè) hook 在 IPv4 協(xié)議棧的ip_output() 函數(shù)或 IPv6 協(xié)議棧的 ip6_finish_output2() 函數(shù)中執(zhí)行。本機(jī)產(chǎn)生的準(zhǔn)備發(fā)出的數(shù)據(jù)包或者轉(zhuǎn)發(fā)的數(shù)據(jù)包,在經(jīng)過路由判斷之后, 將到達(dá)此 hook 觸發(fā)點(diǎn)。

NF_HOOK 宏和 netfilter 向量

所有的觸發(fā)點(diǎn)位置統(tǒng)一調(diào)用NF_HOOK這個(gè)宏來觸發(fā) hook:

static inline int NF_HOOK(uint8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { return NF_HOOK_THRESH(pf, hook, skb, in, out, okfn, INT_MIN); }

NF-HOOK接收的參數(shù)如下:

  • pf: 數(shù)據(jù)包的協(xié)議族,對 IPv4 來說是NFPROTO_IPV4。

  • hook: 上圖中所示的 netfilter hook 枚舉對象,如 NF_INET_PRE_ROUTING 或 NF_INET_LOCAL_OUT。

  • skb: SKB 對象,表示正在被處理的數(shù)據(jù)包。

  • in: 數(shù)據(jù)包的輸入網(wǎng)絡(luò)設(shè)備。

  • out: 數(shù)據(jù)包的輸出網(wǎng)絡(luò)設(shè)備。

  • okfn: 一個(gè)指向函數(shù)的指針,該函數(shù)將在該 hook 即將終止時(shí)調(diào)用,通常傳入數(shù)據(jù)包處理路徑上的下一個(gè)處理函數(shù)。

NF-HOOK的返回值是以下具有特定含義的 netfilter 向量之一:

  1. NF_ACCEPT: 在處理路徑上正常繼續(xù)(實(shí)際上是在NF-HOOK中最后執(zhí)行傳入的okfn)。

  2. NF_DROP: 丟棄數(shù)據(jù)包,終止處理。

  3. NF_STOLEN: 數(shù)據(jù)包已轉(zhuǎn)交,終止處理。

  4. NF_QUEUE: 將數(shù)據(jù)包入隊(duì)后供其他處理。

  5. NF_REPEAT: 重新調(diào)用當(dāng)前 hook。

回歸到源碼,IPv4 內(nèi)核網(wǎng)絡(luò)棧會(huì)在以下代碼模塊中調(diào)用NF_HOOK()

7b52edf8-dca8-11ec-ba43-dac502259ad0.png

NF_HOOK

實(shí)際調(diào)用方式以`net/ipv4/ip_forward.c`[1] 對數(shù)據(jù)包進(jìn)行轉(zhuǎn)發(fā)的源碼為例,在 ip_forward 函數(shù)結(jié)尾部分的第 115 行以 NF_INET_FORWARDhook 作為入?yún)⒄{(diào)用了 NF_HOOK 宏,并將網(wǎng)絡(luò)棧接下來的處理函數(shù) ip_forward_finish 作為 okfn 參數(shù)傳入:

int ip_forward(struct sk_buff *skb) { .....(省略部分代碼) if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr && !skb_sec_path(skb))  ip_rt_send_redirect(skb);  skb->priority = rt_tos2priority(iph->tos);  return NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD, skb, skb->dev,         rt->dst.dev, ip_forward_finish); .....(省略部分代碼) }

回調(diào)函數(shù)與優(yōu)先級

netfilter 的另一組成部分是 hook 的回調(diào)函數(shù)。內(nèi)核網(wǎng)絡(luò)棧既使用 hook 來代表特定觸發(fā)位置,也使用 hook (的整數(shù)值)作為數(shù)據(jù)索引來訪問觸發(fā)點(diǎn)對應(yīng)的回調(diào)函數(shù)。

內(nèi)核的其他模塊可以通過 netfilter 提供的 api 向指定的 hook 注冊回調(diào)函數(shù),同一 hook 可以注冊多個(gè)回調(diào)函數(shù),通過注冊時(shí)指定的priority 參數(shù)可指定回調(diào)函數(shù)在執(zhí)行時(shí)的優(yōu)先級。

注冊 hook 的回調(diào)函數(shù)時(shí),首先需要定義一個(gè) nf_hook_ops結(jié)構(gòu)(或由多個(gè)該結(jié)構(gòu)組成的數(shù)組),其定義如下:

struct nf_hook_ops { struct list_head list;  /* User fills in from here down. */ nf_hookfn *hook; struct module *owner; u_int8_t pf; unsigned int hooknum; /* Hooks are ordered in ascending priority. */  int priority; };

在定義中有 3 個(gè)重要成員:

  • hook: 將要注冊的回調(diào)函數(shù),函數(shù)參數(shù)定義與NF_HOOK 類似,可通過 okfn參數(shù)嵌套其他函數(shù)。

  • hooknum: 注冊的目標(biāo) hook 枚舉值。

  • priority: 回調(diào)函數(shù)的優(yōu)先級,較小的值優(yōu)先執(zhí)行。

定義結(jié)構(gòu)體后可通過int nf_register_hook(struct nf_hook_ops *reg) 或 int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n); 分別注冊一個(gè)或多個(gè)回調(diào)函數(shù)。同一 netfilter hook 下所有的nf_hook_ops 注冊后以 priority 為順序組成一個(gè)鏈表結(jié)構(gòu),注冊過程會(huì)根據(jù) priority 從鏈表中找到合適的位置,然后執(zhí)行鏈表插入操作。

在執(zhí)行 NF-HOOK 宏觸發(fā)指定的 hook 時(shí),將調(diào)用 nf_iterate 函數(shù)迭代這個(gè) hook 對應(yīng)的 nf_hook_ops 鏈表,并依次調(diào)用每一個(gè) nf_hook_ops 的注冊函數(shù)成員 hookfn。示意圖如下:

7b752e54-dca8-11ec-ba43-dac502259ad0.png

netfilter-hookfn1

這種鏈?zhǔn)秸{(diào)用回調(diào)函數(shù)的工作方式,也讓 netfilter hook 被稱為 Chain,下文的 iptables 介紹中尤其體現(xiàn)了這一關(guān)聯(lián)。

每個(gè)回調(diào)函數(shù)也必須返回一個(gè) netfilter 向量;如果該向量為NF_ACCEPT,nf_iterate 將會(huì)繼續(xù)調(diào)用下一個(gè) nf_hook_ops 的回調(diào)函數(shù),直到所有回調(diào)函數(shù)調(diào)用完畢后返回 NF_ACCEPT;如果該向量為 NF_DROP,將中斷遍歷并直接返回 NF_DROP;**如果該向量為 **NF_REPEAT**,將重新執(zhí)行該回調(diào)函數(shù)**。nf_iterate 的返回值也將作為 NF-HOOK 的返回值,網(wǎng)絡(luò)棧將根據(jù)該向量值判斷是否繼續(xù)執(zhí)行處理函數(shù)。示意圖如下:

7b9e5f40-dca8-11ec-ba43-dac502259ad0.png

netfilter-hookfn2

netfilter hook 的回調(diào)函數(shù)機(jī)制具有以下特性:

  • 回調(diào)函數(shù)按優(yōu)先級依次執(zhí)行,只有上一回調(diào)函數(shù)返回NF_ACCEPT 才會(huì)繼續(xù)執(zhí)行下一回調(diào)函數(shù)。

  • 任一回調(diào)函數(shù)都可以中斷該 hook 的回調(diào)函數(shù)執(zhí)行鏈,同時(shí)要求整個(gè)網(wǎng)絡(luò)棧中止對數(shù)據(jù)包的處理。

iptables

基于內(nèi)核 netfilter 提供的 hook 回調(diào)函數(shù)機(jī)制,netfilter 作者 Rusty Russell 還開發(fā)了 iptables,實(shí)現(xiàn)在用戶空間管理應(yīng)用于數(shù)據(jù)包的自定義規(guī)則。

iptbles 分為兩部分:

  • 用戶空間的 iptables 命令向用戶提供訪問內(nèi)核 iptables 模塊的管理界面。

  • 內(nèi)核空間的 iptables 模塊在內(nèi)存中維護(hù)規(guī)則表,實(shí)現(xiàn)表的創(chuàng)建及注冊。

內(nèi)核空間模塊

xt_table 的初始化

在內(nèi)核網(wǎng)絡(luò)棧中,iptables 通過xt_table 結(jié)構(gòu)對眾多的數(shù)據(jù)包處理規(guī)則進(jìn)行有序管理,一個(gè) xt_table 對應(yīng)一個(gè)規(guī)則表,對應(yīng)的用戶空間概念為 table。不同的規(guī)則表有以下特征:

  • 對不同的 netfilter hooks 生效。

  • 在同一 hook 中檢查不同規(guī)則表的優(yōu)先級不同。

基于規(guī)則的最終目的,iptables 默認(rèn)初始化了 4 個(gè)不同的規(guī)則表,分別是 raw、 filter、nat 和 mangle。下文以 filter 為例介紹xt_table的初始化和調(diào)用過程。

filter table 的定義如下:

#define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) |                (1 << NF_INET_FORWARD) |                (1 << NF_INET_LOCAL_OUT)) static const struct xt_table packet_filter = {   .name = "filter",   .valid_hooks = FILTER_VALID_HOOKS,   .me = THIS_MODULE,   .af = NFPROTO_IPV4,   .priority = NF_IP_PRI_FILTER,  }; (net/ipv4/netfilter/iptable_filter.c)

iptable_filter.c[2] 模塊的初始化函數(shù) [iptable_filter_init](https://elixir.bootlin.com/linux/v2.6.39.4/C/ident/iptable_filter_init "iptable_filter_init") ****中,調(diào)用xt_hook_link 對 xt_table 結(jié)構(gòu) packet_filter 執(zhí)行如下初始化過程:

  1. 通過 .valid_hooks 屬性迭代 xt_table 將生效的每一個(gè) hook,對于 filter 來說是 NF_INET_LOCAL_IN,NF_INET_FORWARD 和 NF_INET_LOCAL_OUT這 3 個(gè) hook。

  2. 對每一個(gè) hook,使用 xt_table 的 priority 屬性向 hook 注冊一個(gè)回調(diào)函數(shù)。

不同 table 的 priority 值如下:

enum nf_ip_hook_priorities { NF_IP_PRI_RAW = -300, NF_IP_PRI_MANGLE = -150, NF_IP_PRI_NAT_DST = -100, NF_IP_PRI_FILTER = 0, NF_IP_PRI_SECURITY = 50, NF_IP_PRI_NAT_SRC = 100, };

當(dāng)數(shù)據(jù)包到達(dá)某一 hook 觸發(fā)點(diǎn)時(shí),會(huì)依次執(zhí)行不同 table 在該 hook 上注冊的所有回調(diào)函數(shù),這些回調(diào)函數(shù)總是根據(jù)上文的 priority 值以固定的相對順序執(zhí)行:

7be92070-dca8-11ec-ba43-dac502259ad0.png

tables-priority

ipt_do_table()

filter 注冊的 hook 回調(diào)函數(shù) iptable_filter_hook[3] 將對 xt_table 結(jié)構(gòu)執(zhí)行公共的規(guī)則檢查函數(shù) ipt_do_table[4]。ipt_do_table 接收 skb、hook 和 xt_table作為參數(shù),對 skb 執(zhí)行后兩個(gè)參數(shù)所確定的規(guī)則集,返回 netfilter 向量作為回調(diào)函數(shù)的返回值

在深入規(guī)則執(zhí)行過程前,需要先了解規(guī)則集如何在內(nèi)存中表示。每一條規(guī)則由 3 部分組成:

  1. 一個(gè) ipt_entry 結(jié)構(gòu)體。通過 .next_offset 指向下一個(gè) ipt_entry 的內(nèi)存偏移地址。

  2. 0 個(gè)或多個(gè) ipt_entry_match 結(jié)構(gòu)體,每個(gè)結(jié)構(gòu)體可以動(dòng)態(tài)的添加額外數(shù)據(jù)。

  3. 1 個(gè) ipt_entry_target 結(jié)構(gòu)體, 結(jié)構(gòu)體可以動(dòng)態(tài)的添加額外數(shù)據(jù)。

ipt_entry 結(jié)構(gòu)體定義如下:

struct ipt_entry { struct ipt_ip ip; unsigned int nfcache;  /* ipt_entry + matches 在內(nèi)存中的大小*/ u_int16_t target_offset; /* ipt_entry + matches + target 在內(nèi)存中的大小 */ u_int16_t next_offset;  /* 跳轉(zhuǎn)后指向前一規(guī)則 */ unsigned int comefrom; /* 數(shù)據(jù)包計(jì)數(shù)器 */ struct xt_counters counters; /* 長度為0數(shù)組的特殊用法,作為 match 的內(nèi)存地址 */ unsigned char elems[0]; };

ipt_do_table 首先根據(jù) hook 類型以及 xt_table.private.entries屬性跳轉(zhuǎn)到對應(yīng)的規(guī)則集內(nèi)存區(qū)域,執(zhí)行如下過程:

7c068d9a-dca8-11ec-ba43-dac502259ad0.png

ipt_do_table

  1. 首先檢查數(shù)據(jù)包的 IP 首部與第一條規(guī)則 ipt_entry 的 .ipt_ip 屬性是否一致,如不匹配根據(jù) next_offset 屬性跳轉(zhuǎn)到下一條規(guī)則。

  2. 若 IP 首部匹配 ,則開始依次檢查該規(guī)則所定義的所有 ipt_entry_match 對象,與對象關(guān)聯(lián)的匹配函數(shù)將被調(diào)用,根據(jù)調(diào)用返回值有返回到回調(diào)函數(shù)(以及是否丟棄數(shù)據(jù)包)、跳轉(zhuǎn)到下一規(guī)則或繼續(xù)檢查等結(jié)果。

  3. 所有檢查通過后讀取 ipt_entry_target,根據(jù)其屬性返回 netfilter 向量到回調(diào)函數(shù)、繼續(xù)下一規(guī)則或跳轉(zhuǎn)到指定內(nèi)存地址的其他規(guī)則,非標(biāo)準(zhǔn) ipt_entry_target 還會(huì)調(diào)用被綁定的函數(shù),但只能返回向量值不能跳轉(zhuǎn)其他規(guī)則。

靈活性和更新時(shí)延

以上數(shù)據(jù)結(jié)構(gòu)與執(zhí)行方式為 iptables 提供了強(qiáng)大的擴(kuò)展能力,我們可以靈活地自定義每條規(guī)則的匹配條件并根據(jù)結(jié)果執(zhí)行不同行為,甚至還能在額外的規(guī)則集之間棧式跳轉(zhuǎn)。

由于每條規(guī)則長度不等、內(nèi)部結(jié)構(gòu)復(fù)雜,且同一規(guī)則集位于連續(xù)的內(nèi)存空間,iptables 使用全量替換的方式來更新規(guī)則,這使得我們能夠從用戶空間以原子操作來添加/刪除規(guī)則,但非增量式的規(guī)則更新會(huì)在規(guī)則數(shù)量級較大時(shí)帶來嚴(yán)重的性能問題:假如在一個(gè)大規(guī)模 Kubernetes 集群中使用 iptables 方式實(shí)現(xiàn) Service,當(dāng) service 數(shù)量較多時(shí),哪怕更新一個(gè) service 也會(huì)整體修改 iptables 規(guī)則表。全量提交的過程會(huì) kernel lock 進(jìn)行保護(hù),因此會(huì)有很大的更新時(shí)延。

用戶空間的 tables、chains 和 rules

用戶空間的 iptables 命令行可以讀取指定表的數(shù)據(jù)并渲染到終端,添加新的規(guī)則(實(shí)際上是替換整個(gè) table 的規(guī)則表)等。

iptables 主要操作以下幾種對象:

  • table:對應(yīng)內(nèi)核空間的 xt_table 結(jié)構(gòu),iptable 的所有操作都對指定的 table 執(zhí)行,默認(rèn)為 filter。

  • chain:對應(yīng)指定 table 通過特定 netfilter hook 調(diào)用的規(guī)則集,此外還可以自定義規(guī)則集,然后從 hook 規(guī)則集中跳轉(zhuǎn)過去。

  • rule:對應(yīng)上文中 ipt_entry、ipt_entry_match 和ipt_entry_target,定義了對數(shù)據(jù)包的匹配規(guī)則以及匹配后執(zhí)行的行為。

  • match:具有很強(qiáng)擴(kuò)展性的自定義匹配規(guī)則。

  • target:具有很強(qiáng)擴(kuò)展性的自定義匹配后行為。

基于上文介紹的代碼調(diào)用過程流程,chain 和 rule 按如下示意圖執(zhí)行:

7c5ef35e-dca8-11ec-ba43-dac502259ad0.png

iptables-chains

對于 iptables 具體的用法和指令本文不做詳細(xì)介紹。

conntrack

僅僅通過 3、4 層的首部信息對數(shù)據(jù)包進(jìn)行過濾是不夠的,有時(shí)候還需要進(jìn)一步考慮連接的狀態(tài)。netfilter 通過另一內(nèi)置模塊conntrack進(jìn)行連接跟蹤(connection tracking),以提供根據(jù)連接過濾、地址轉(zhuǎn)換(NAT)等更進(jìn)階的網(wǎng)絡(luò)過濾功能。由于需要對連接狀態(tài)進(jìn)行判斷,conntrack在整體機(jī)制相同的基礎(chǔ)上,又針對協(xié)議特點(diǎn)有單獨(dú)的實(shí)現(xiàn)。

原文標(biāo)題:深入理解 netfilter 和 iptables

文章出處:【微信公眾號(hào):一口Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11329

    瀏覽量

    209969
  • 數(shù)據(jù)包
    +關(guān)注

    關(guān)注

    0

    文章

    265

    瀏覽量

    24426
  • netfilter
    +關(guān)注

    關(guān)注

    0

    文章

    6

    瀏覽量

    7192

原文標(biāo)題:深入理解 netfilter 和 iptables

文章出處:【微信號(hào):yikoulinux,微信公眾號(hào):一口Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Linux內(nèi)核防火墻netfilter的原理和應(yīng)用

    ;netfilter的工作原理2.1 netfilter的框架結(jié)構(gòu)  netfilterLinux2.4內(nèi)核
    發(fā)表于 09-19 09:22

    如何去實(shí)現(xiàn)netfilter

    Linux下支持netfilter機(jī)制的配置工具就是iptables,它也就相當(dāng)與一個(gè)應(yīng)用程序,可以對netfilter進(jìn)行配置(包過濾規(guī)則,NAT等等)。所以要實(shí)現(xiàn)
    發(fā)表于 11-05 06:12

    如何解決編譯內(nèi)核報(bào)錯(cuò)的問題?

    內(nèi)核源碼版本D:\work\文檔\對接文件\OKMX6Q-C、OKMX6DL-C (Linux)用戶資料-2019.12.30\linux-3.0.35編譯時(shí)提示以下錯(cuò)誤,經(jīng)查看,這個(gè)源碼
    發(fā)表于 01-07 06:04

    netfilter技術(shù)分析及在入侵響應(yīng)的應(yīng)用

    netfilter總體結(jié)構(gòu)入手,分析了netfilter的連線跟蹤、包過濾、地址轉(zhuǎn)換、包處理等關(guān)鍵技術(shù)。在此基礎(chǔ)上,研究了入侵響應(yīng)策略,提出了基于netfilter的主動(dòng)響應(yīng)模型。經(jīng)測試證明
    發(fā)表于 11-18 09:47 ?23次下載

    Linux內(nèi)核教程

    本章學(xué)習(xí)目標(biāo)掌握LINUX內(nèi)核版本的含義理解并掌握進(jìn)程的概念掌握管道的概念及實(shí)現(xiàn)了解內(nèi)核的數(shù)據(jù)結(jié)構(gòu)了解LINUX
    發(fā)表于 04-10 16:59 ?0次下載

    Linux防火墻模塊加載技術(shù)的研究與實(shí)現(xiàn)

    本文對Linux 防火墻內(nèi)核Netfilter 系統(tǒng)的結(jié)構(gòu)框架、工作原理及其在內(nèi)核
    發(fā)表于 06-19 09:59 ?11次下載

    Linux新型內(nèi)核防火墻研究和應(yīng)用

    Linux新型防火墻netfilter框架原理及工作機(jī)制基礎(chǔ)上,研究了該防火墻的應(yīng)用設(shè)計(jì), 提出了用netfilter/iptables構(gòu)建門戶服務(wù)器防火墻的實(shí)現(xiàn)方法,實(shí)驗(yàn)測試證明,
    發(fā)表于 08-25 11:35 ?14次下載

    基于Netfilter的NAT技術(shù)及其應(yīng)用

    NAT技術(shù)是為了解決IPv4網(wǎng)絡(luò)地址空間的不夠而提出的一種過渡技術(shù),并由于其簡單、高效的特性而得到了廣泛的應(yīng)用。該文介紹了NAT技術(shù)及在Linux 2.4內(nèi)核基于Netfilter
    發(fā)表于 12-29 23:53 ?20次下載

    基于Netfilter內(nèi)核態(tài)網(wǎng)絡(luò)流量分析研究

    網(wǎng)絡(luò)流量采集與分析是網(wǎng)絡(luò)流量測量的核心技術(shù)。本文基于Linux 平臺(tái)內(nèi)核空間下的Netfilter 框架,提出并實(shí)現(xiàn)內(nèi)核級的流量采集和分析
    發(fā)表于 01-09 15:13 ?22次下載

    netfilter技術(shù)分析

    netfilter技術(shù)分析 netfilter是由Rusty Russell提出的Linux 2.4內(nèi)核防火墻框架,該框架既簡潔又靈活,可實(shí)現(xiàn)
    發(fā)表于 11-18 09:50 ?854次閱讀
    <b class='flag-5'>netfilter</b>技術(shù)分析

    什么是netfilter?netfilter是什么意思?

    netfilter的定義: netfilter是由Rusty Russell提出的Linux 2.4內(nèi)核防火墻框架,該框架既簡潔又靈活,
    發(fā)表于 11-18 09:54 ?2331次閱讀
    什么是<b class='flag-5'>netfilter</b>?<b class='flag-5'>netfilter</b>是什么意思?

    Iptables移植到嵌入式Linux系統(tǒng)

    Linux下支持netfilter機(jī)制的配置工具就是iptables,它也就相當(dāng)與一個(gè)應(yīng)用程序,可以對netfilter進(jìn)行配置(包過濾規(guī)則,NAT等等)。所以要實(shí)現(xiàn)
    發(fā)表于 11-02 14:51 ?1次下載
    Iptables移植到嵌入式<b class='flag-5'>Linux</b>系統(tǒng)

    Linux 6.2內(nèi)核合并了新的Zstd實(shí)現(xiàn)

    ? 基于 Zstd v1.5 上游的新 Zstd 內(nèi)核實(shí)現(xiàn)已合并到正在開發(fā)的 Linux 6.2 ,以便為從壓縮固件到透明文件系統(tǒng)壓縮的 Zstd 壓縮 / 解壓縮用例提供更好的性能和可靠性
    的頭像 發(fā)表于 12-21 10:16 ?677次閱讀

    Netfilter/iptables

    Netfilter是運(yùn)行在Linux的一個(gè)功能,因?yàn)?b class='flag-5'>Linux是一個(gè)模塊化的內(nèi)核,所以Netfilte
    的頭像 發(fā)表于 04-06 15:13 ?538次閱讀
    <b class='flag-5'>Netfilter</b>/iptables

    Netfilter 的設(shè)計(jì)與實(shí)現(xiàn)

    的 Service 轉(zhuǎn)發(fā)都是通過 iptables 來實(shí)現(xiàn)的。 關(guān)于 netfilter 的介紹文章大部分只描述了抽象的概念,實(shí)際上其內(nèi)核代碼的基本實(shí)現(xiàn)不算復(fù)雜,本文主要參考
    的頭像 發(fā)表于 11-13 10:34 ?445次閱讀
    <b class='flag-5'>Netfilter</b> 的設(shè)計(jì)與<b class='flag-5'>實(shí)現(xiàn)</b>