歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Netfilter策略路由和uRPF

Netfilter策略路由和uRPF

日期:2017/2/28 15:48:35   编辑:Linux教程

在Linux中,往往會出現一些奇怪的現象,如果你僅僅知道一些皮毛,那麼這些現象將會讓你抓耳撓腮,因為Linux往往遵循RFC建議而有時卻不會保持持久的大眾化實現,畢竟,Linux並不是一個人搞定的,特別是網絡協議棧這一方面。uRPF這個概念很多人都知道,Linux的實現卻很不一致,在Linux實現中,它和策略路由的點點滴滴值得說一番,我們分為以下4個關鍵點來說明,當然這4點並不是全部關於uRPF的:

1.策略路由和OUTPUT鏈

Linux的Netfilter實現5個HOOK點,其中OUTPUT點在路由之後,那麼如果我們將如下的路由:
route add -net 192.168.188.0/24 gw 192.168.40.254
移植到策略路由:
ip rule add $標簽1 tab new
ip route add 192.168.188.0/24 via 192.168.40.254 table new
route del -net 192.168.188.0/24
iptables -t mangle -A OUTPUT -XXX -j MARK --set-mark $標簽1
那麼當我們從本機發包到192.168.188.0/24的時候,得到的結果將是“路由不可達”。這是因為Linux的基於標簽的策略路由是為“過路包”設計的,在本機發包進入任何Netfilter鉤子點之前首先要經過IP路由,也就是說OUTPUT鏈在IP路由之後,此時任何的打標簽策略都還沒有被應用,因此就會出現上述的奇怪現象。

2.CONNMARK target和MARK target

在Linux Netfilter中,有CONNMARK和MARK兩個target,其作用都是set-mark,那麼這兩個target有何不同呢?很簡單,CONNMARK是為一個“連接”即conntrack打上一個mark,而MARK僅僅是為一個packet打上一個mark,對於CONNMARK,如果想讓後續的包或者返回包也被打上mark,www.linuxidc.com 不必再進行一次新的iptables規則匹配,只需要restore-mark即可,而對於MARK,則不能這麼做,因此它是不依賴ip_conntrack的。
因此,考慮以下現象:
路由:
ip rule add $標簽1 tab new
ip route add 192.168.188.0/24 via 192.168.40.254 table new
route del -net 192.168.188.0/24
iptables規則:
iptables -t mangle -A PREROUTING -i $內網口 -XXX -j MARK --set-mark $標簽1
rp_filter配置:
sysctl -w net.ipv4.conf.$所有網卡.rp_filter=1
訪問192.168.188.0/24,將發現返回包無法經過網關,為何呢?很簡單,rp_filter為1,顯然為嚴格uRPF,此時返回包的反向路由必須被查找到且和策略路由的結果一致,然而策略路由是無法被命中的,因此返回包沒有命中任何iptables打標簽的規則而沒有被打標簽,進而不命中策略路由...,如果將iptables中的MARK改為CONNMARK呢?也不行,還缺少一條:
iptables -t mangle -A PREROUTING -j CONNMARK restore-mark
才行,因此請注意,始終將上述規則放在所有規則的靠前的位置且在其後加上RETURN target的規則,可以:第一,免除很多基於mark的iptables規則查找;第二,可以避免由於uRPF而導致的奇怪問題。

3.標簽策略路由和NOTRACK target

如果還是出現了奇怪的問題,那麼看一下是不是NOTRACK target導致的呢?我們知道raw表是所有規則的最前面的,因此如果在raw表中被NOTRACK了,那麼就別指望後面的任何mark規則起作用了,所有的基於mark的策略路由也將無效,更隱蔽的是uRPF驗證失敗導致的包不可達將很難被發現。

4.路由cache與rp_filter

在IP路由查找的時候,首先要查找路由cache,在Linux的實現中,查找路由cache的過程不涉及任何的uRPF(在ip_route_input_XXX中沒有任何fib_validate_source的調用),因此如果系統中有反向包的路由cache,即使你設置了rp_filter為嚴格uRPF,並且還故意配置NOTRACK以及基於mark的正向包策略路由,那還是可以正常通訊的。

Copyright © Linux教程網 All Rights Reserved