如何为 2 个 KVM-Guest 分配多个公共 IP 地址

Ron*_*Ron 4 linux ssl routing apache-2.2 kvm-virtualization

我是整个主题的新手,我尝试了好几天来弄清楚如何通过 KVM 主机将多个公共 IP 地址分配给 KVM 来宾。我找到了大量示例,如何在运行 1 个公共 IP 的情况下进行这样的设置。

这是我的设置:服务器只有一个 NIC/MAC,并运行 2 个 KVM-Guest 和 apache(和其他东西)。两个来宾环境都是 ubuntu 服务器 11.10,必须在单独的 VM 中运行。5 个公共 ip 地址用于处理 SSL 证书和其他内容。第一个 VM 应使用 5 个地址/证书中的 3 个。第二个虚拟机得到其余的。apache-stuff 配置正确。

我已经通过 iptables 尝试了多种不同的方式来将流量从主机 NIC 路由到来宾 NIC。尽管一种方法是正确的,但只有错误的实施,我还是不说细节,让您不为所动。问题是:它应该做的理想方式是什么?

应满足以下条件:

  • Apache 必须获取访问者的原始 IP 地址
  • Apache 必须知道,使用什么公共 IP 地址来使用正确的 ssl-vhost
  • 流量不能通过主机上的(反向)代理路由,因为在其他 VM 来宾上还有 2 个其他非 http 服务,应该可以从公共访问。并且:只有 sshd 应该直接在主机上监听 - 没有别的
  • 每个 VM 都应该能够直接访问 Internet。
  • 数据中心的网络是基于 MAC 的交换网络。正如我发现的,与互联网通信的唯一方法是通过 eth0 及其 MAC 地址。

如果我丢弃所有虚拟化的东西,这将非常容易,因为 apache 直接从特定的 ip 地址获取请求。

我愿意接受任何可行的解决方案。

图表

jol*_*ger 5

在 dom0(例如 KVM 主机)WAN 接口上使用网桥。这需要安装bridge-utils包。由于这是基于 Debian 的发行版,您可以在/etc/network/interfaces以下位置配置它:

iface eth0 inet manual

auto br_wan
iface br_wan inet dhcp
    # Assuming DHCP to get address, otherwise migrate all WAN connection options here
    #address 192.168.122.0
    bridge_ports eth0 tap_guest1
    bridge_stp      off
    bridge_maxwait  0
    bridge_fd       0
    pre-up ip tuntap add dev tap_guest1 user guest1 mode tap
    # This command is required if your ISP allocates static IPs depending on MAC address
    # You shouldn't use this but might be handy some time
    #pre-up sysctl -q -w net/ipv4/conf/tap_guest1/proxy_arp=1
    post-down ip tuntap del tap_guest1 mode tap
Run Code Online (Sandbox Code Playgroud)

Pre-up 命令设置 TAP 接口以将您的 KVM 来宾连接到网桥。请注意,此设置允许从非特权用户 guest1 运行 kvm。请注意,net.ipv4.ip_forward = 1使用 sysctl 进行设置也可能很有用。

我使用ip tuntapiproute2包中的命令。它尚未记录在 Debian 软件包中,但很快就会在上游的手册页中提供。由于此软件包安装在每个基于 Debian 的服务器上,因此您无需安装uml-utilitiesopenvpn打包即可创建这些接口。

这种方法确实缺乏管理大量点击界面的优雅,因为您需要创建与界面类似的 pre-up 和 post-down 行tap_guest1。这可以通过在/etc/network/pre-up.d和 中编写额外的脚本来解决/etc/network/post-down.d。如果您想br_wan在 KVM 来宾仍在运行时使用 ifdown/ifup 脚本重新配置接口,这也是一个问题- 您需要删除除eth0网桥配置之外的所有接口并手动将它们从网桥分离(不要忘记附加它们然后在桥重新配置后返回)或关闭在桥上运行的所有 KVM 实例。

另一种可能更简洁的方法是为 KVM 本身编写自定义 ifup 脚本,并在script您的 NIC 选项中使用它。您可以在/etc/qemu-ifup. 有关详细信息,请参阅kvm 手册页

然后你可以像这样运行你的 KVM 机器:

kvm -net nic,model=virtio,macaddr=12:34:56:78:9a:bc \
    -net tap,ifname=tap_guest1,script=no,downscript=no \
    -boot c -nographic -display none -daemonize \
    guest1-drive.qcow2
Run Code Online (Sandbox Code Playgroud)

可以使用命令手动在一个接口上为 KVM 来宾设置多个 IP 地址

ip address add aaa.bbb.ccc.101/24 dev eth0
Run Code Online (Sandbox Code Playgroud)

或者/etc/network/interfaces像这样永久地:

auto eth0 eth0:1
iface eth0 inet static
    address aaa.bbb.ccc.100
    network aaa.bbb.ccc.0
    netmask 255.255.255.0
    broadcast aaa.bbb.ccc.255
    gateway aaa.bbb.ccc.1

iface eth0:1 inet static
    address aaa.bbb.ccc.101
    network aaa.bbb.ccc.0
    netmask 255.255.255.0
    broadcast aaa.bbb.ccc.255
    gateway aaa.bbb.ccc.1
Run Code Online (Sandbox Code Playgroud)

请注意,如果您的数据中心/提供商不希望您在同一网络上显示其他框,他可能不会配置它们并且它们将不可用。在这种情况下,您可能希望创建内部网桥并使用 iptables 使用 DNAT 和 SNAT 在您的 WAN 接口和此网桥之间转发数据包。假设您的本地虚拟桥接网络是 10.0.0.0/8,您的 guest1 是 10.0.0.2,您将需要这个:

iptables -t nat -A PREROUTING --dst aaa.bbb.ccc.100 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2
iptables -t nat -A PREROUTING --dst aaa.bbb.ccc.101 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2
...
iptables -t nat -A POSTROUTING -p tcp --dst 10.0.0.2 -j SNAT --to-source aaa.bbb.ccc.100
Run Code Online (Sandbox Code Playgroud)

请注意,您需要的 DNAT 命令与您拥有的每个 KVM 来宾的外部 IP 一样多,但只需要一个 SNAT 规则即可访问互联网。此外,您还可以通过仅允许所需端口来仅允许 HTTP/HTTPS/SSH 流量。如果省略该--dport语句,则将转发所有端口。除非您愿意托管 DHCP 服务器,否则您的 KVM 来宾应该具有静态网络设置,并将 KVM 主机作为默认网关。