![使用 netns 将程序绑定到特定的 IP 地址](https://linux22.com/image/784560/%E4%BD%BF%E7%94%A8%20netns%20%E5%B0%86%E7%A8%8B%E5%BA%8F%E7%BB%91%E5%AE%9A%E5%88%B0%E7%89%B9%E5%AE%9A%E7%9A%84%20IP%20%E5%9C%B0%E5%9D%80.png)
我的服务器上有一个 IP 地址,比如 192.168.0.3,我想在网络命名空间中共享,以便在那里运行应用程序,这些应用程序只能使用 192.168.0.3 与互联网通信。
我可以“某种程度上”让它与macvlan
设备类型一起工作...除了拥有两个 mac 地址之外,网关通常会青睐我的根或我的命名空间绑定接口。
有没有什么办法可以让我在 netns 内部镜像该 IP,而不影响外部 IP?
以下是我一直在尝试的:
ip netns add myns
ip link add link eth0 name en0 netns myns type macvlan
ip netns exec myns ip link set en0 up
ip netns exec myns ip addr add 192.168.0.3/24 dev en0
ip netns exec myns ip route add default via 192.168.0.1
然后我用各种变化进行测试netcat
;要么在远程主机中监听并从命名空间内部和外部进行连接,要么在命名空间内部和外部进行监听并从远程主机进行连接。
由于直接路由器会将数据包发送到某个 mac 地址或其他地址,因此macvlan
它不可靠,我需要重置路由器中缓存的 mac(通过发送数据包)才能在物理或macvlan
接口之间切换。虽然这是可以理解的,但我缺少一种让 IP 共享而不是“争夺”的方法。
我这样做的动机是,我的服务器中只有几个 IP,并且每个 IP 都已监听服务(这允许您正确绑定到特定 IP/端口)。然后我尝试创建一个 chroot jail,它只会将这几个 IP 中的一个暴露给其中运行的应用程序。因此,这些被监禁的应用程序可以绑定到这些 IP 的任何(空闲)端口,但不会有机会接管同一服务器中的任何其他 IP 地址。
(我可以想到其他选项,例如使用 LD_PRELOAD 或 iptables NAT,但我真的认为我缺少了一点让它与网络命名空间一起工作的功能)
答案1
您有两个选择:
- 将 IP 地址分配
192.168.0.3
给该命名空间中的接口,并且不要在该命名空间之外使用它。这将允许该命名空间使用所有端口而不必担心发生冲突。为此,macvlan 是一个不错的选择。 - 在主机和命名空间之间共享 IP 地址
192.168.0.3
。在这种情况下,它必须是相同的接口,您不能在同一网络上使用相同的 IP 地址拥有不同的接口。解决方案是使用 veth 对并在主机上设置转发(确保使用正确的接口/源地址)。这类似于容器所做的。但这不允许您在主机和容器上的端口 80 上运行 Web 服务器。
你可以像这样设置 veth 对:
# Create namespace
ip netns add myns
ip -n myns link set lo up
# Create devices
ip link add myveth0 type veth peer name myveth1
ip link set myveth0 netns myns
# Set addresses
ip -n myns addr add 10.64.0.1/24 dev myveth0
ip -n myns link set myveth0 up
ip addr add 10.64.0.2/24 dev myveth1
ip link set myveth1 up
# Enable forwarding between netns and outside network (customize the rules as needed)
sysctl -w net.ipv4.ip_forward=1
iptables -t filter -A FORWARD -i myveth1 -j ACCEPT
iptables -t filter -A FORWARD -o myveth1 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.64.0.0/24 -j MASQUERADE