如何在不同的过程中使用不同的网络接口?


59

我在Linux PC上有两个网络接口,我需要手动设置给定进程将使用的接口。

该程序(Twinkle软电话)没有类似的选项,因此我认为必须在外部进行设置。

我该怎么做?

编辑:我不是要使服务器进程绑定到特定的接口,而是要使客户端程序使用特定的接口与服务器联系。


客户端也使用bind / connect,请查看bind.c.txt文档,了解如何将ircII(irc客户端程序)强制为给定的ip:'bash中的示例将您的虚拟IP用作ircII的传出源地址: BIND_ADDR =“ your-virt-ip” LD_PRELOAD =。/ bind.so ircII'–
akira

我在这里找到了一种不同的方法,希望对您有所帮助(我希望希望现在已默认启用所描述的内核策略路由):kindlund.wordpress.com/2007/11/19/…– Savvas
Radevic

Answers:


48

您可以在运行时使用LD_PRELOAD替换代码(@windows您可以使用一种类似的技术,称为detours,相当不错)。这样做是为了通知动态链接器首先将所有库加载到要运行的进程中,然后在其上面添加更多内容。您通常这样使用它:

% LD_PRELOAD=./mylib.so ls

这样,您就可以更改ls功能。

对于您的问题,我会尝试http://www.ryde.net/code/bind.c.txt,您可以像这样使用:

% BIND_ADDR="ip_of_ethX" LD_PRELOAD=./bind.so twinkle

这是您的构建方式:

% wget http://www.ryde.net/code/bind.c.txt -O bind.c
% gcc -nostartfiles -fpic -shared bind.c -o bind.so -ldl -D_GNU_SOURCE

更长的方法是http://daniel-lange.com/archives/53-Binding-applications-to-a-specific-IP.html

类似的技巧和工具:


7
哇,真该死。+1
sinni800

1
嗨,这似乎是一个很好的技巧,但对我来说不起作用。我有两个3G调制解调器,连接后打开两个接口(ppp0和ppp1)。如果我尝试强制使用这两个IP之一,那么我总是最终会使用相同的接口(我看到它是因为我有两个Wireshark实例,每个接口一个)。我还从bind.c中删除了调试打印,实际上我看到“重载”库已加载,所以我不知道为什么它不起作用。
Andrea Spadaccini 2011年

3
如果您的有效UID与实际UID不同,则LD_PRELOAD将被忽略。
matthias krull 2011年

force_bindCatalin M. Boie 的项目支持ipv6
BurnsBA '16

效果很好,但必须添加#include <arpa / inet.h>才能成功进行编译。
安诺

31

ip netns可以做到这一点。

TL; DR: 创建网络名称空间,将接口与它们关联,然后运行“ ip netns exec NAME cmd ...”

只需检查您的发行版是否支持ip netns ...(回溯5r3不支持,而Kali则支持;))

更多详细信息:

#create netns
ip netns add myNamespace
#link iface to netns
ip link set eth0 netns myNamespace
#set ip address in namespace
ip netns exec myNamespace ifconfig eth0 192.168.0.10/24 up
#set loopback (may be needed by process run in this namespace)
ip netns exec myNamespace ifconfig lo 127.0.0.1/8 up
#set route in namespace
ip netns exec myNamespace route add default gw 192.168.0.1
#force firefox to run inside namespace (using eth0 as outgoing interface and the route)
ip netns exec myNamespace firefox

为什么这比通过LD_PRELOAD绑定ip更好?因为LD_PRELOAD不控制进程使用的路由。它将使用第一条路线。

并且由于它始终使用相同的路由,因此它将默认为注册到该路由的接口。(这不是我们想要的)


2
请尝试在您的答案中添加更多详细信息。
Renju Chandran chingath 2014年

4
如果eth0的是公共网络接口不这样做在远程服务器上..
ygrek

1
最后一行应该是ip netns exec myNamespace firefox
meuh 2015年

1
在需要时使用“ sudo ip netns del <名称空间名称>”删除名称空间!
爱德华多·卢西奥

1
@EduardoLucio应该可以像这样执行它: sudo ip netns exec myNamespace su -u someUser -c firefox
olivervbk

2

我认为不可能强迫一个进程使用某个接口。

但是,我认为您可能可以使用ipchain / iptables并强制您的进程正在侦听的某个端口只会使数据包通过特定的接口进入。

有用的HOWTO:http : //tldp.org/HOWTO/IPCHAINS-HOWTO.html


2
这两个投票较高的职位证明不是这样。
Paul Gear

2

基于@olivervbk,下面的答案是我的!

以“ root”身份运行所有命令。

使用命令...

ip a

...以找出您要使用的网络接口的名称。

运行以下命令作为模板...

ip netns add [INTERFACE_NAME]_ns
ip link set dev [INTERFACE_NAME] netns [INTERFACE_NAME]_ns
ip netns exec [INTERFACE_NAME]_ns ifconfig [INTERFACE_NAME] 10.1.1.10/24 up
ip netns exec [INTERFACE_NAME]_ns ifconfig lo 127.0.0.1/8 up
ip netns exec [INTERFACE_NAME]_ns route add default gw 10.1.1.1
ip netns exec [INTERFACE_NAME]_ns dhcpcd [INTERFACE_NAME]
ip netns exec [INTERFACE_NAME]_ns sudo -b -u [YOUR_USER] [APP_NAME] 2> /dev/null 1> /dev/null &
  • [INTERFACE_NAME]-替换为所选网络接口的名称。
  • [YOUR_USER]-替换为您的用户名。
  • [APP_NAME]-将在名称空间“ [INTERFACE_NAME] _ns”中执行的应用程序的名称。例如:“ firefox”。

注意I: “ sudo”命令中的“ -b -u”标志允许应用程序使用您的用户(而不是“ root”)运行,并在后台释放终端。该2> /dev/null 1> /dev/null &代码段用于防止在终端上打印“ [APP_NAME]”的输出。
注II: ip“ 10.1.1.10”和“ 10.1.1.1”的值是任意的。
注意三:要为我工作,我必须运行dhcpcd [INTERFACE_NAME]命令。

要删除名称空间,请使用...

ip netns del [INTERFACE_NAME]_ns

... 要么...

ip -all netns delete

...删除存在的任何内容。


1

通常,如果程序没有用于设置侦听接口的选项,则它将在所有接口上侦听。(您可以使用进行验证lsof -i)。

创建iptables防火墙规则是最简单的事情,该规则将传入的通信丢弃到您不希望在其上可见的接口上指向其端口的位置。


1

备选方案I:

使用ld_preload强制接口网关https://github.com/Intika-Linux-Network/App-Route-Jail

强制应用程序使用特定的网络接口

我们需要找到网络接口正在使用的网关,然后将该网关强制到我们监禁的应用程序,从而强制该应用程序绑定到特定的网络接口

  • 如何找到接口网关(找到网关的解决方案很多,这里有一些命令可以找到使用的网关)
$ route
$ route -n
$ ip rule list
$ ip route show
$ netstat -rn
$ cat /etc/network/interfaces
$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
$ traceroute www.google.com
$ ip route show 0.0.0.0/0 dev eth0

每个应用程序网关

  • 建立应用程序路线监狱
git clone https://github.com/Intika-Linux-Network/App-Route-Jail.git
cd Approute-Utils
chown 755 make.sh
./make.sh
  • 在此示例中,为将来标记的数据包添加了一条路由(用于入狱的应用程序),192.168.1.1用作强制网关,此路由规则不会影响其他应用程序,例如,如果您想在系统启动时仅执行一次此操作每天使用此解决方案
ip rule add fwmark 10 table 100
ip route add default via 192.168.1.1 table 100
  • 启动您要入狱的应用程序
MARK=10 LD_PRELOAD=./mark.so firefox
  • 测试WAN IP地址
MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me

备选方案二:

Firejail https://firejail.wordpress.com/可以强制应用程序使用特定的网络,但兼容性有限。

firejail --dns=8.8.8.8 --net=eth0 --ip=192.168.1.1

请注意,普通用户无法使用该标记,您必须以root用户身份运行。
jornane

-2

为什么要让程序使用与服务器连接的接口以外的接口来与该服务器通信?而且,如果系统未使用连接到服务器的接口与该服务器进行通讯,则是系统级(路由表)问题,并且与要与该服务器进行通讯的进程无关。

IP网络上的不同服务器具有不同的IP地址。内核应根据路由表知道要使用哪个接口来到达特定的IP地址。如果您试图与具有相同IP地址的两个不同的服务器进行通信,则系统会感到困惑(因为,除其他外,它仅按目标地址在内部为连接编制索引)。您可以使它工作,但这是系统级的修复,涉及将一台服务器置于单独的逻辑网络中,该逻辑网络仅通过软件NAT连接到计算机。

因此,如果它们具有不同的IP地址,请使用路由选择正确的接口。如果它们具有相同的IP地址,则需要使用NAT,以便它们对于系统而言似乎具有不同的IP地址。


3
首先,客户端和服务器之间可能存在多条有效路由,但是具有不同的特性以适合不同的流量类型;例如UMTS(蜂窝数据)可能要花钱,但范围要比WiFi大,但两者都比光纤连接要慢。如果上游提供商进行源过滤(或NAT),则您别无选择,只能发出“正确”的接口。其次,影响路由并不是选择源地址的唯一原因。即使两个地址都在同一个接口上,作为服务器,控制启动连接时绑定到哪个地址也很有用

一种情况是,如果您具有不同的公共IP,并且您想在每个IP中为出站连接启动一个新进程。
Rfraile
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.