Iptables

使用配置為請求選擇硬體介面?

  • March 3, 2021

我有一台 linux 機器(基於 Debian 10 的作業系統),有 3 個硬體介面連接到網際網路,2 個是 USB 調製解調器:ifconfig 給出 ->

eth0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
       ether b8:27:eb:95:a0:2c  txqueuelen 1000  (Ethernet)
       RX packets 0  bytes 0 (0.0 B)
       RX errors 0  dropped 0  overruns 0  frame 0
       TX packets 0  bytes 0 (0.0 B)
       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
       inet 127.0.0.1  netmask 255.0.0.0
       inet6 ::1  prefixlen 128  scopeid 0x10<host>
       loop  txqueuelen 1000  (Local Loopback)
       RX packets 14258  bytes 1613046 (1.5 MiB)
       RX errors 0  dropped 0  overruns 0  frame 0
       TX packets 14258  bytes 1613046 (1.5 MiB)
       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ppp0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
       inet 10.199.25.78  netmask 255.255.255.255  destination 10.64.64.64
       ppp  txqueuelen 3  (Point-to-Point Protocol)
       RX packets 7  bytes 130 (130.0 B)
       RX errors 0  dropped 0  overruns 0  frame 0
       TX packets 8  bytes 181 (181.0 B)
       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ppp1: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
       inet 10.227.136.222  netmask 255.255.255.255  destination 10.64.64.65
       ppp  txqueuelen 3  (Point-to-Point Protocol)
       RX packets 7  bytes 130 (130.0 B)
       RX errors 0  dropped 0  overruns 0  frame 0
       TX packets 8  bytes 181 (181.0 B)
       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
       inet 192.168.2.105  netmask 255.255.255.0  broadcast 192.168.2.255
       inet6 fe80::e1b9:e62c:3140:bfc5  prefixlen 64  scopeid 0x20<link>
       ether b8:27:eb:c0:f5:79  txqueuelen 1000  (Ethernet)
       RX packets 26548  bytes 5187998 (4.9 MiB)
       RX errors 0  dropped 0  overruns 0  frame 0
       TX packets 20025  bytes 5171235 (4.9 MiB)
       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan0 是這裡的預設介面,當我嘗試時:curl --interface ppp1 ifconfig.me或者curl --interface ppp0 ifconfig.me請求超時,使用 sudo sudo curl --interface ppp1 ifconfig.me給出響應,但等效於 ppp0 超時,要添加哪些正確的路由規則才能選擇要路由的硬體介面?

實際路由規則:

default via 192.168.2.1 dev wlan0 proto dhcp src 192.168.2.105 metric 303 
10.64.64.64 dev ppp0 proto kernel scope link src 10.233.6.240 
10.64.64.65 dev ppp1 proto kernel scope link src 10.149.182.92 
192.168.2.0/24 dev wlan0 proto dhcp scope link src 192.168.2.105 metric 303 

ip rule給出:

0:  from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default 

ip -4 route show table all:

default via 192.168.2.1 dev wlan0 
10.64.64.64 dev ppp0 proto kernel scope link src 10.235.137.107 
10.64.64.65 dev ppp1 proto kernel scope link src 10.121.55.130 
192.168.2.0/24 dev wlan0 proto kernel scope link src 192.168.2.101 
local 10.121.55.130 dev ppp1 table local proto kernel scope host src 10.121.55.130 
local 10.235.137.107 dev ppp0 table local proto kernel scope host src 10.235.137.107 
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1 
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1 
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1 
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1 
broadcast 192.168.2.0 dev wlan0 table local proto kernel scope link src 192.168.2.101 
local 192.168.2.101 dev wlan0 table local proto kernel scope host src 192.168.2.101 
broadcast 192.168.2.255 dev wlan0 table local proto kernel scope link src 192.168.2.101 

PS。重新啟動後,我嘗試的所有路由都消失了(如預期的那樣)

什麼curl --interface <iface> http://example.com是連接到example.com,使用介面的<iface>IP地址作為源。否則路由照常進行。

如果您希望基於數據包源地址進行路由,則需要添加兩個路由表(一個用於具有源的數據包10.199.25.78,一個用於具有源的數據包10.227.136.222)。讓我們通過添加以下內容來給路由表名稱:

200 ppp0
201 ppp1

/etc/iproute2/rt_tables用來自這些介面的數據包的預設路由填充它們:

ip route add default dev ppp0 via 10.64.64.64 table ppp0
ip route add default dev ppp1 via 10.64.64.65 table ppp1

現在,您需要做的就是添加兩條規則,它們將選擇表ppp0ppp1根據源地址:

ip rule add from 10.199.25.78 table ppp0
ip rule add from 10.227.136.222 table ppp1

編輯:我深入研究了curl--interface ppp0選項。它可以以兩種方式工作(參見connect.c):

  • 如果程序有CAP_NET_RAW能力(比如當你是root時),它會綁定到給定的介面(通過SO_BINDTODEVICE),並且所有不使用ppp0介面的路由都會被忽略。
  • 如果程序沒有特權,curl將綁定到ppp0介面的 IP 地址 ( 10.199.25.78) 並且路由照常進行。

引用自:https://serverfault.com/questions/1003006