阻止应用程序使用端口上的所有 IP (0.0.0.0:34964)

阻止应用程序使用端口上的所有 IP (0.0.0.0:34964)

我有两个应用程序使用相同的端口进行网络通信 (34964)。我可以控制(源代码)第一个应用程序,它使用 192.168.0.4:34964。尽管另一个应用程序尝试使用/“声明”所有 IP 地址 (0.0.0.0:34964),但我无法控制这个地址。每个应用程序都单独运行,但是当我尝试使它们同时运行时,我收到错误:无法绑定地址。

问题

有什么办法可以防止第二个应用程序使用/声明所有 IP 地址 (0.0.0.0) 并改为使用 192.168.0.5。要么在启动之前,要么将其封装在网络命名空间中?

我什么也没尝试,我已经没有想法了......

更详细的版本: 两个应用程序在两个独立的 Profinet 网络上进行通信。第一个应用程序充当 Profinet 设备并与西门子 Profinet 控制器通信,我可以访问该应用程序的源代码。第二个应用程序应充当与 Profinet 西门子设备通信的 Profinet 控制器,我目前正在使用 Codesys 来实现此目的,并且无权更改源代码。

答案1

你有几个选择。

LD_预加载

您可以使用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 下运行它,并使用 Docker 的端口映射功能在您选择的主机 IP 上公开服务。

这里有龙

我强烈推荐上述解决方案之一。我只包含以下内容,因为您询问了网络名称空间。

带 macvlan 的网络命名空间

如果您想在不使用 Docker 的情况下完成此操作,也是可以的,但需要做更多的工作。首先,创建一个新的网络命名空间:

# 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)。

带 veth 接口的网络命名空间

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

您需要确保您的主机上启用了 ip 转发 ( sysctl -w net.ipv4.ip_forward=1) 并且您的 iptablesFORWARD链允许转发连接 ( iptables -A FORWARD -d 192.168.99.2 -j ACCEPT,请记住,规则是按顺序处理的,因此拒绝规则这一项将优先)。

相关内容