根據進程將 IP 流量路由到不同的預設路由/接口

根據進程將 IP 流量路由到不同的預設路由/接口

我試圖確定是否可以選擇性地透過特定介面路由來自進程或進程組的 IP 封包,同時所有其他封包都透過另一個介面路由。也就是說,我希望所有流量 from 都/usr/bin/testapp被路由通過,eth1而所有其他資料包都通過eth0。這種情況下的封包可以是 TCP、UDP、ICMP 等,並且可由最終使用者配置以使用各種連接埠。

因為我無法輕鬆強制相關進程綁定到特定接口,所以我嘗試透過路由實現相同的結果。這可能嗎?

- - 編輯 - -

這裡以及許多其他地方的一個有用建議是基於 UID 標記資料包;這並不是真正的目標。目標是根據流程進行標記/過濾/路由與用戶無關。也就是說, ifalicebobcharlie運行自己的實例/usr/bin/testapp;來自所有三個實例的所有資料包都應該通過,eth1而來自系統的所有其他資料包都應該通過eth0

請注意,透過來源/目標連接埠、使用者名稱/UID 等進行標記是不夠的,因為不同的使用者可能會運行testapp並且他們可能會在自己的連接埠~/.config/testapp.conf或其他連接埠中設定不同的連接埠。問題是關於按進程過濾。

/bin/(ba|z)?sh一個可用的選項是在本機二進位檔案周圍使用基於 - 的包裝器,儘管我不知道它有多大幫助。

- - 編輯 - -

我指的是運行現代 Linux 核心(例如 4.0 或更高版本)的系統上的路由。如果除了iproute2、和類似工具nftables之外還存在軟體依賴性conntrack,我願意探索開源解決方案,儘管基本工具更可取。

答案1

您透過 eth1 或 eth0 路由資料包。 table mangle 應該可以解決這個問題。為此,我必須標記資料包並設定處理它的規則。首先,新增一條規則,使核心將標記為2的資料包路由通過表

ip rule add fwmark 2 table 3

新增一條路由以透過不同介面重定向流量,假設網關為 10.0.0.1:

ip route add default via 10.0.0.1 table 3

刷新您的路由快取。

ip route flush cache

現在,設定防火牆規則來標記指定的封包:

iptables -t mangle -A OUTPUT -p tcp --dport 465 -j MARK --set-mark 2

最後,放寬反向路徑來源驗證。有些人建議您將其設為 0,但根據 2 似乎是更好的選擇https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt。如果您跳過此步驟,您將收到資料包(可使用 確認tcpdump -i tap0 -n),但資料包不會被接受。更改設定以便接受資料包的命令:

sysctl -w net.ipv4.conf.tap0.rp_filter=2

參考 :http://serverfault.com/questions/345111/iptables-target-to-route-packet-to-specific-interface

答案2

您可以使用特定使用者執行該進程,並將資料包與 iptable 的owner副檔名進行比對。一旦匹配,您可以標記它並將其與另一個路由表、使用POSTROUTING或您可能喜歡的任何解決方案一起使用。

帖子更好地解釋了與 的數據包匹配owner

答案3

這可以使用網路命名空間來隔離進程,使用虛擬乙太網路連接將該網路命名空間連接到主命名空間。然後,您可以使用 iptables 根據該來源進行路由。

這是一個例子。我正在使用網路管理員執行一些命令,但你可以直接執行

# Create a namespace
ip netns add ns1

# create a bridge between them
nmcli connection add type veth ifname virt0 peer virt1
ip link set virt1 netns ns1
ip addr add 192.168.69.1/24 dev virt0
ip netns exec ns1 ip addr add 192.168.69.2/24 dev virt1
ip netns exec ns1 ip link up virt1
echo 1 > sudo tee /proc/sys/net/ipv4/ip_forward

# At this point traffic from ns1 will appear in your main network namespace as coming from ip 192.168.69.2 dev virt0, so you can handle it from there.  You will need NAT to make it go somewhere useful.
# In this case I want the traffic to go out through interface vpn1, which is not a default route on my system.

# Add your process-specific routing rules in a non-default table (12345 in this case)
ip route add default dev vpn1 table 12345 proto static scope link metric 50
# Set up a rule to use that table for the traffic coming from that IP, with lower priority than the default table's rule.
ip rule add priority 30000 from 192.168.69.0/24 lookup 12345
# Add the nat, so that the traffic can actually exist on your outbound interface
iptables -t nat -A POSTROUTING -o vpn1 -j MASQUERADE

# At this point traffic from ns1 will go out through interface vpn1. Now you can run command sin that netns to utilize this.

nsenter  --net=/var/run/netns/ns1 your_program

答案4

好吧,鑑於您告訴我們:

因為我無法輕鬆強制相關進程綁定到特定接口,所以我嘗試透過路由實現相同的結果。這可能嗎?

我們可以從現在開始為您提供協助。曾幾何時,FreeBSD 中jail出現了系統調用,其目的是將一個進程或一組進程限制在系統資源的某個子部分。特別是,可以指定那些「隔離」進程用於其網路活動的 IP 位址。這太方便了,我真的很懷念 Linux 中的這個功能。但 Linux 也有一些方法可以達到類似的結果:

或者,大多數輕量級只是手動修改命名空間:https://unix.stackexchange.com/questions/155446/linux-is-there-handy-way-to-exec-a-program-binding-it-to-ip-address-of-choice

相關內容