我有两个应用程序使用相同的端口进行网络通信(34964)。我控制(源代码)第一个应用程序,它使用192.168.0.4:34964。而另一个应用程序试图使用/“声明”所有IP地址(0.0.0.0:34964),但我无法控制这个IP地址。每个应用程序都单独运行,但是,当我试图使它们同时运行时,我会得到一个错误:绑定地址失败。
是否有任何方法阻止第二个应用程序使用/声明所有IP地址(0.0.0.0),而改用192.168.0.5。在启动它之前,还是将其封装在网络命名空间中?
我什么都没试过,我没有任何想法.
更详细的版本:两个应用程序在两个不同的Profinet网络上通信。第一个应用程序充当Profinet设备,并与西门子Profinet控制器通信,我可以访问这个应用程序的源代码。第二个应用程序应该充当Profinet控制器,与Profinet西门子设备对话,我目前正在使用Codesys进行此操作,并且没有权限更改源代码。
发布于 2017-04-06 12:50:37
你有几个选择。
您可以使用LD_PRELOAD
库来拦截bind()
系统调用,强制绑定到特定地址。其中一个例子是这,您可以这样编译它:
gcc -nostartfiles -fpic -shared bind.c -o bind.so -ldl -D_GNU_SOURCE
然后像这样使用:
BIND_ADDR=127.0.0.1 LD_PRELOAD=./bind.so /path/to/myprogram
您还可以选择在自己的网络命名空间中运行程序。最简单的方法是为您的应用程序构建一个Docker映像,然后在Docker下运行它,并使用Docker的端口映射功能在您选择的主机ip上公开服务。
我强烈建议上述解决方案之一。我只包含以下内容,因为您询问了网络名称空间。
如果你想在没有码头的情况下做这件事,那是可能的,但要多做一点工作。首先,创建一个新的网络命名空间:
# ip netns add myns
然后创建一个与主机接口相关联的macvlan
接口,并将其放入命名空间中:
# ip link add myiface link eth0 type macvlan mode bridge
# ip link set myiface netns myns
并在本地网络上为其分配一个地址:
# ip netns exec myns \
ip addr add 192.168.0.4/24 dev myiface
# ip netns exec myns \
ip link set myiface up
并在命名空间中创建适当的路由规则(将实际网关地址替换为192.168.0.1
):
# ip netns exec myns \
ip route add default via 192.168.0.1
现在,在网络命名空间中运行您的程序:
# ip netns exec myns \
/path/to/myprogram
现在,您的程序正在运行,并且将只绑定到192.168.0.4
,因为这是命名空间中唯一可见的地址。但!注意mavclan
接口的局限性:虽然您网络上的其他主机将能够连接到服务,但您将无法从正在运行的主机连接到该地址(除非您在主机上创建另一个macvlan
接口并通过该接口将连接路由到192.168.0.4
)。
与使用macvlan
接口不同,您可以创建一个veth
接口对,其一端位于网络命名空间内,另一端位于主机上。您将使用ip伪装将数据包从命名空间传递到本地网络。
创建网络命名空间:
# ip netns add myns
创建一个接口对:
# ip link add myiface-in type veth peer name myiface-out
将一对的一端分配给您的网络命名空间:
# ip link setns myiface-in myns
在对的两端配置一个地址,并打开链接:
# ip addr add 192.168.99.1/24 dev myiface-out
# ip link set myiface-out up
# ip netns exec myns ip addr add 192.168.99.2/24 dev myiface-in
# ip netns exec myns ip link set myiface-in up
在您的主机上配置ip伪装。这将将192.168.0.4
上的传入数据包重定向到您的命名空间:
# iptables -t nat -A PREROUTING -d 192.168.0.4 -p tcp --dport 34964 -j DNAT --to-destination 192.168.99.2
# iptables -t nat -A OUTPUT -d 192.168.0.4 -p tcp --dport 34964 -j DNAT --to-destination 192.168.99.2
这将伪装出站数据包:
# iptables -t nat -A POSTROUTING -s 192.168.99.2 -j MASQUERADE
您将需要确保在您的主机(sysctl -w net.ipv4.ip_forward=1
)上启用了ip转发,并且您的iptables FORWARD
链允许转发连接(iptables -A FORWARD -d 192.168.99.2 -j ACCEPT
,请记住规则是按顺序处理的,因此在此之前将优先处理拒绝规则)。
https://unix.stackexchange.com/questions/356337
复制相似问题