我有一台只有一个物理接口的服务器eth0
。我打算在这台服务器上运行虚拟机。为此,我有一个路由到该服务器的 IPv4 块。我试图实现的是将虚拟机启动到本地子网,然后将10.0.0.0/8
外部 IP 一对一 NAT 为内部 IP,从而有效地为这些虚拟机提供外部 IP 和互联网访问权限。
1 对 1 NAT 没有问题,但我无法让虚拟机管理程序接受和处理所有外部 IP 的流量(即使没有任何形式的 NAT)。我正在使用单个 /30 网络测试所有内容,IP 如下
xxx.xxx.xxx.0/30
xxx.xxx.xxx.1/30
xxx.xxx.xxx.2/30
xxx.xxx.xxx.3/30
假设 eth0 有 ip yyy.yyy.yyy.yyy
。IPv4 数据包转发已启用。
我可以让我的虚拟机管理程序(或虚拟机)响应块中的最低地址,似乎所有其他地址都被忽略了。
我尝试将所有 IP 作为别名添加到 eth0:
ip addr add xxx.xxx.xxx.0/30 dev eth0 label eth0:1
ip addr add xxx.xxx.xxx.1/30 dev eth0 label eth0:1
ip addr add xxx.xxx.xxx.2/30 dev eth0 label eth0:1
ip addr add xxx.xxx.xxx.3/30 dev eth0 label eth0:1
我还尝试使用 /32 而不是 /30,并使用不同的标签,以及上述所有方法的组合。但都没有成功。接下来,我决定创建一个连接整个子网的网桥。
br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
link/ether ea:5a:59:06:8a:7a brd ff:ff:ff:ff:ff:ff
inet xxx.xxx.xxx.0/30 brd 5.39.22.163 scope global br0
valid_lft forever preferred_lft forever
inet xxx.xxx.xxx.1/30 brd 5.39.22.163 scope global secondary br0
valid_lft forever preferred_lft forever
inet xxx.xxx.xxx.2/30 brd 5.39.22.163 scope global secondary br0
valid_lft forever preferred_lft forever
inet xxx.xxx.xxx.3/30 brd 5.39.22.163 scope global secondary br0
valid_lft forever preferred_lft forever
再次,没有成功。然后我创建了一个网桥,但没有为其附加 IP。我只是在该网桥上添加了到子网的路由。我不需要我的虚拟机管理程序真正响应流量,我只需要它接受它,以便 iptables 处理它并应用 NAT。
ip route add xxx.xxx.xxx.0/30 dev br0
这也没有成功。
在我尝试的所有情况下,虚拟机管理程序(或 VM,如果我启用了 1 对 1 NAT)将能够响应 xxx.xxx.xxx.0 的流量,而块中的任何其他 IP 都将被忽略。
答案1
根本问题原来是数据中心的路由问题。并非所有流量都正确路由到我的服务器。
我的最终设置如下:
6: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether <MAC ADDRESS> brd ff:ff:ff:ff:ff:ff
inet <hypervisor IP/netmask> brd <broadcast addr> scope global eth0
valid_lft forever preferred_lft forever
11: local_net: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether fe:00:05:27:16:a0 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.1/8 brd 10.255.255.255 scope global local_net
valid_lft forever preferred_lft forever
因此,我仅将虚拟机管理程序的 IP 分配给物理接口。然后我创建一个本地桥接器。该桥接器上有一个 DHCP 服务器监听,并为虚拟机的预定义 MAC 地址提供静态租约,因此每个虚拟机每次启动时都会收到相同的本地 IP。
然后,为了使 1 对 1 NAT 运行,我只需添加如下规则:
iptables -t nat -A PREROUTING -d <public VM IP>/32 -i eth0 -j DNAT --to-destination <local VM IP>
iptables -t nat -A POSTROUTING -s <local VM IP>/32 -o eth0 -j SNAT --to-source <public VM IP>
这会将到达eth0
虚拟机某个 IP 的所有流量转换为虚拟机,并将来自虚拟机的所有流量转换为公共 IP。
答案2
在每个子网中,第一个地址用于网络,最后一个地址通常用于广播。因此 xxx.xxx.xxx.0 和 xxx.xxx.xxx.3 不适用于 /30 类网络,而 /32 网络上的所有 IP 地址都是网络地址。网络地址用于路由,不能分配给设备
如果要使用 /30 类网络,则可以在一个网段(xxx.xxx.xxx.0 网络)上使用 xxx.xxx.xxx.1 和 xxx.xxx.xxx.2,在另一个网段(xxx.xxx.xxx.4 网络)上使用 xxx.xxx.xxx.5 和 xxx.xxx.xxx.6
也许可以尝试不同的 /24 类网络。
此外,您似乎试图将所有 IP 地址分配给 eth0:1,请尝试使用 eth0:2、eth0:3 和 eth0:4
另一个要尝试的命令是“ifconfig eth0 add xxx1 netmask 255.255.255.0”,或者对于 /32 类网络使用“netmask 255.255.255.252”。此命令将自动为您分配子接口号,从 eth0:0 开始,接下来使用 eth0:1。
另外,我不确定网络是否可以称为“/30 类”或“/24 类”。我不确定正确的术语是什么。
答案3
对于 IPv4,网络上的最低地址(有两个例外)是网络地址,并且不能用于分配给主机。
如果您有/32
,则表示必须路由单个主机地址。此类地址通常用作路由器环回地址。
如果您有/31
,则该网络用于点对点链接,因为它只有两个可用地址。最初,/31
网络不可用,但RFC 3021,在 IPv4 点对点链路上使用 31 位前缀改变了这一点。
要在同一个网络中使用四个地址,则可以使用的最长掩码为/29
,这将为您提供六个可用地址。