linux netfilter 过滤数据包,Netfilter-iptabes报文过滤框架(一)
什么是Netfilter/iptable
Netfilter/iptables是Linux內核內置的報文過濾框架,程序可以通過該框架完成報文過濾、地址轉換(NAT)以及連接跟蹤等功能。
Netfilter/iptables由兩部分組成,一部分是Netfilter的"鉤子(hook)",這些"鉤子"由Linux內核協議棧提供,內核模塊可以通過注冊"鉤子"來完成各種各樣的功能。 另一部分是iptables的規則,這些規則規定了"鉤子"如何工作。
下圖很直觀的說明了用戶空間的iptables和內核空間的ip_tables模塊、Netfilter之間的關系。
Netfilter
Netfilter是嵌入Linux內核協議棧的,設置在報文處理路徑上的一系列調用入口。 Netfilter一共有5個"鉤子"設置在IP協議棧的報文處理路徑上,這5個"鉤子"就是內嵌在內核協議棧的檢查點。 我們可以把處理函數注冊到各個檢查點,當報文經過各個檢查點時,就可以通過"鉤子"函數對報文進行處理完成相應功能。
下圖說明了5個"鉤子"在內核協議棧的位置。
"鉤子"的存儲及管理機制
在內核中,"鉤子"函數由一個全局二維數組nf_hooks按照協議族歸類存儲,在每個協議族中,根據鉤子點順序排列,在鉤子點內則根據鉤子函數的優先級排列。 例如ipv4和ipv6就是兩個協議族,每個協議族都包含5個"鉤子",每個"鉤子"下面保存了注冊在這個"鉤子"上的函數地址。
這個二維數組的每一項代表了一個鉤子被調用的點,NF_PROTO代表協議棧,NF_HOOK代表協議棧中某個路徑點。
所有模塊都可以通過nf_register_hook()函數將一個鉤子函數掛入想要被調用點的鏈表中(通過Protocol和hook指定一個點)。 這樣,該鉤子函數就能夠處理從指定Protocol和指定hook點流過的數據包。
Netfilter在不同協議棧的不同點上放置鉤子函數,當數據包經過某個協議棧(NF_PROTO)的某個點(NF_HOOK)時,該協議棧會通過NF_HOOK()函數調用對應鉤子鏈表(nf_hooks[NF_PROTO][NF_HOOK])中注冊的每一個鉤子項來處理該數據包。
Netfilter定義了每個鉤子函數的返回值,每個鉤子函數只能返回下面的返回值,而不能自定義返回值。
NF_DROP(0):數據包被丟棄,即不被下一個鉤子函數處理,同時也不再被協議棧處理,并釋放數據包。
NF_ACCEPT(1):數據包被接受,即交給下一個鉤子或協議棧繼續處理。
NF_STOLEN(2):數據包被停止處理,即不被下一個鉤子函數處理,同時也不再被協議棧處理,但不釋放數據包。
NF_QUEUE(3):將數據包交給nf_queue子系統處理,即不被下一個鉤子函數處理,同時也不再被協議棧處理,也不釋放數據包。
NF_REPEAT(4):數據包將被該返回值的鉤子函數再次處理一遍。
NF_STOP(5): 數據包停止被該HOOK點的后續鉤子函數處理,交給協議棧繼續處理。
"鉤子"的使用方法
"鉤子"的使用首先實例化一個nf_hook_ops對象,然后對其進行必要的初始化設置,最后通過nf_register_hook()函數將其注冊到二維數組nf_hooks中。 我們首先初始化nf_hook_ops中的常用字段:
static struct nf_hook_ops nf_hook_test_ops =
{
.hook = test_hook_func;
.hooknum = NF_INET_PRE_ROUTING;
.pf = PF_INET;
.owner = THIS_MODULE;
.priority = NF_IP_PRI_FIRST;
}
其中:
hook是鉤子函數
hooknum是鉤子點
pf是協議棧
priority是鉤子函數的優先級
然后在模塊加載和退出函數中注冊和移除鉤子函數:
int init_module(void)
{
nf_register_hook(&nf_hook_test_ops);
}
void cleanup_module()
{
nf_unregister_hook(&nf_hook_test_ops);
}
下面是回調函數的聲明:
static unsigned int test_hook(unsigned int hooknum, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
int (*okfn)(struct sk_buff*)
從上述過程可以看出,鉤子函數的使用與iptables沒有任何關系,也就是說如果某個模塊需要對協議棧的報文進行處理,但不需要用戶空間的參數,那么完全可以只注冊鉤子函數,而不需要編寫iptables的模塊。
即使需要用戶空間的參數,也可以通過proc或者netlink等其他用戶態和內核態通信方式來傳遞參數,這樣就可以更靈活的使用Netfilter了。
參考資料:
總結
以上是生活随笔為你收集整理的linux netfilter 过滤数据包,Netfilter-iptabes报文过滤框架(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sunup是什么手机(sunup是什么意
- 下一篇: linux微信公众号报警,zabbix报