如何將所有流量從特定介面路由到特定網關而不是預設路由?
在我的機器上,我有兩個介面:(
wlan0
預設路由)和tun0
. 該tun0
介面只是一個本地網路,它的ip範圍是172.16.150.0/24
,我機器(機器A)的IP地址是172.16.150.1
,另一台機器(機器B)的IP地址是172.16.150.128
。我設置了一個 wifi 熱點,它為我創建了另一個界面ap0
。我想ap0
通過機器 B 路由來自介面的所有流量(因此網關應該是172.16.150.128
)。$ ip route default via 192.168.0.1 dev wlan0 proto dhcp src 192.168.0.179 metric 1024 172.16.150.0/24 dev tun0 proto kernel scope link src 172.16.150.1 metric 1024 192.168.0.0/24 dev wlan0 proto kernel scope link src 192.168.0.179 metric 1024 192.168.0.1 dev wlan0 proto dhcp scope link src 192.168.0.179 metric 1024 192.168.12.0/24 dev ap0 proto kernel scope link src 192.168.12.1
此時,由於預設路由是
192.168.0.1
,它將所有流量路由wlan0
到我家路由器的介面。我不是經驗豐富的 linux 使用者,所以我不確定如何讓 linux 核心路由來自網關的所有流量
ap0
,172.16.150.128
但這是我嘗試過的:$ ip route add default 192.168.12.0/24 via 172.16.150.128 Error: either "to" is duplicate, or "192.168.12.0/24" is a garbage.
在這裡,我試圖讓核心通過網關路由來自
192.168.12.0/24
子網的所有流量。172.16.150.128
$ ip route add 192.168.12.0/24 via 172.16.150.128 RTNETLINK answers: File exists
與上一個命令相同,但沒有
default
單詞。我在某個地方讀到了ip addr flush dev ap0
可能有幫助的地方,但它會重置介面及其 IP 地址,因此我需要通過手動恢復 IP 地址ip addr add
或重新啟動 wifi 熱點。我認為這不是正確的方法,因為我不想刷新介面,而是想將路由更改
default
為特定網關。我怎樣才能做到這一點?
簡單的路由在這裡是不夠的。簡單路由關心目的地。但這裡的目標是也根據來源改變路線。這樣做稱為策略路由。在 Linux 上,這是通過使用額外的選擇器(不僅僅是目標)來實現的,例如源 IP 地址或源數據包的傳入介面來選擇備用路由表。這些備用路由表可以有其他路由,包括其他預設路由,最終為數據包選擇與主路由表中的通常路由不同的路由。
這通常與 some + some結合使用,並根據要解決的問題進行選擇。通常會有基於源的選擇器以區別對待,而將有(並且只能有)用於這種情況的備用目的地。
ip rule
add ... lookup TABLE``ip route add ...
table TABLE
ip rule ...``ip route ...
因此,對於這種情況,可以像下面那樣做。
- 準備一個備用路由表(使用任意表 1000)
此表應包含所需的所有內容,因此將手動複製主路由表的部分內容
ip route add 192.168.12.0/24 dev ap0 table 1000 ip route add 172.16.150.0/24 dev tun0 table 1000
當然,為了實現目標,也有備用的預設路由:
ip route add default via 172.16.150.128 dev tun0 table 1000
- 為兩個涉及的介面選擇備用路由表
ip rule add iif ap0 lookup 1000 ip rule add iif tun0 lookup 1000
路由規則應如下所示:
# ip rule 0: from all lookup local 32764: from all iif tun0 lookup 1000 32765: from all iif ap0 lookup 1000 32766: from all lookup main 32767: from all lookup default
這解決了機器上的路由問題(但請參閱下一部分關於遠端系統的路由或使用 NAT):
- 來自的任何數據包
ap0
都將使用備用路由表並將發送到tun0
這包括發送到 Internet 的流量,該流量將通過 172.16.150.128。有關詳細資訊:專門發送到這台機器的流量實際上將首先使用本地路由表,因此仍將照常工作。
來自的任何數據包
tun0
都將使用備用路由表
- (如果發送到本系統,實際上本地路由表會先路由到本系統)
- 如果發送到 192.168.12.0/24 它將使用
ap0
- 有關詳細資訊:在其他情況下,路由查找會將流量發送回 172.16.150.128
但這種情況在實踐中絕不應該發生。
如果
ap0
或tun0
曾經下降然後上升,則表 1000 中的相關路線將失去並且必須重新添加。還有一個問題:如果 172.16.150.0/24 LAN 上的系統對 192.168.12.0/24 一無所知,它們將永遠不會向該系統 (172.16.150.1) 發送回复流量。他們可能會使用自己的預設網關,可能是 172.16.150.128。同樣,172.16.150.128 可能會將 192.168.12.0/24 的任何流量發送到它自己的上游網關,遠離這台機器,而不是通過這台機器。
要解決這個問題:
- 讓 172.16.150.0/24 中的其他系統知道這個 LAN(首選)
只需在 172.16.150.128 上添加路由就足夠了:172.16.150.0/24 中的其他系統會嘗試通過 172.16.150.128 發送數據包,除了通過 172.16.150.1 路由它之外,還會發送 ICMP 重定向以告訴這些其他系統發送他們直接在那裡。如果那個 172.16.150.128 系統也在執行 Linux,這應該很簡單:
ip route add 192.168.12.0/24 via 172.16.150.1
所有系統也可以直接添加相同的路由。如果通過 DHCP 進行配置,則應使用 DHCP 選項 121(或者對於較舊的 Windows 客戶端可能是選項 249)將此設置添加到 DHCP 配置中,但這超出了此答案的範圍。
- 否則,如果無法完成之前的更改(例如:無法控制 172.16.150.128),請使用 NAT
如果無法在 172.16.150.0/24 中的系統上設置正確的路由,尤其是在 172.16.150.128 上,那麼仍然可以使用 NAT 將所有 192.168.12.0/24 折疊到可訪問的 172.16.150.1 中。在機器上添加:
iptables -t nat -A POSTROUTING -s 192.168.12.0/24 -o tun0 -j MASQUERADE
此方法允許從 192.168.12.0/24 到 172.16.150.0/24 以及通過 172.16.150.128 到 Internet 的流量沿著回複數據包,但它不允許 192.168.12.0/24 上的任何服務從除此之外的任何其他服務訪問機器。需要針對特定埠/服務的其他 NAT 設置來創建例外。