Linux socket設定mark的必要性

2021-08-26 22:55:05 字數 2051 閱讀 2873

linux的netfilter鉤子點的位置會導致一些奇怪的問題,比如本機發出的包無法使用基於mark的策略路由,這是因為mark一般是在netfilter中進行的,而linux的路由處在output鉤子點之前,因此這是乙個順序倒置的問題,如何來解決呢?只能在路由之前打上mark,而我們知道,對於外部進入的包,mark是在prerouting進行的,因此對於外部進入的包,策略路由是好使的,對於本機發出的包,路由之前只能是socket層了,那為何不能在傳輸層做呢?因為一來傳輸層比較雜,二來很多協議直接走到ip層,比如ospf之類的,三來很多傳輸層協議也需要路由查詢,比如tcp在connect的時候就需要查詢路由以確定源ip位址(如果沒有bind的話)。

幸運的是,linux的socket支援so_mark這樣乙個option,可以很方便的使用:

mark = 100;

setsockopt(client_socket, sol_socket, so_mark, &mark, sizeof(mark));

雖然raw表是資料報經過的第乙個表,使用so_mark仍然可以在整個raw表起作用之前做點mark,從而使得乙個特定socket發出的包統統notrack:

iptables -t raw -a output -m mark --mark 100 -j notrack

如果不這樣的話,就需要:

iptables -t raw -a output [-s ***x] [-d yyyy] [-p tcp|udp [--sport x] [--dport y] ... -j mark --set-mark 100

...[一大堆和上面類似的規則]

iptables -t raw -a output -m mark --mark 100 -j notrack

正如在prerouting上的raw表需要做的那樣。我們得意於output上面是socket,是應用程式的世界,而prerouting以下則是核心以及驅動的世界了,後者太雜太亂,不便做更多的事,而前者則是我們可以掌控的範圍。

so_mark最大的受益者就是策略路由了,如果我們這是以下的路由:

ip rule add fwmark 100 table abc

ip route add 1.2.3.4/32 via 192.168.0.254 table abc

ip route del 1.2.3.4/32 table main

不設定so_mark的情況下,所有的訪問1.2.3.4的流量將因為沒有路由而被丟棄,因為在進入prerouting前首先要查詢路由,而此時還沒有打上mark,因而不會匹配到abc策略表中的那條路由,而main表中的對應路由我們已經刪除了...但是如果我們在應用程式中加入:

mark = 100;

setsockopt(client_socket, sol_socket, so_mark, &mark, sizeof(mark));

訪問就可以正常了,因為在查詢路由的時候,已經有這個mark了。

針對本地發出的包需要注意的是,對於基於mark的策略路由,如果在main表中隨意命中了乙個路由,然後就會進入output點,如果在該點中存在mark操作,比如mangle中所做的那樣,hook函式結束前將會進行reroute,如下**所示,在ipt_local_hook中:

if (ret != nf_drop && ret != nf_stolen && ret != nf_queue

&& ((*pskb)->nh.iph->saddr != saddr

|| (*pskb)->nh.iph->daddr != daddr

#ifdef config_ip_route_fwmark

|| (*pskb)->nfmark != nfmark

#endif

|| (*pskb)->nh.iph->tos != tos))

return ip_route_me_harder(pskb) == 0 ? ret : nf_drop;

Linux socket設定mark的必要性

分享一下我老師大神的人工智慧教程。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智慧的隊伍中來!linux的netfilter鉤子點的位置會導致一些奇怪的問題,比如本機發出的包無法使用基於mark的策略路由,這是因為mark一般是在netfilter中進行的,而linux的路由處在o...

Linux socket設定mark的必要性

linux socket設定mark的必要性 linux的netfilter鉤子點的位置會導致一些奇怪的問題,比如本機發出的包無法使用基於mark的策略路由,這是因為mark一般是在netfilter中進行的,而linux的路由處在output鉤子點之前,因此這是乙個順序倒置的問題,如何來解決呢?只...

linux socket 程式設計

兩段程式 可用於開發板和主機之間的資料傳輸,很管用!file client.c檔案傳輸客戶端程式示例 本檔案是客戶機的 include for sockaddr in include for socket include for socket include for printf include f...