使用 Libvirt 在客户操作系统上转发端口

使用 Libvirt 在客户操作系统上转发端口

我目前正在 Ubuntu 14.04 下运行 Xen Hypervisor。在主机上,我正在运行客户虚拟机。

据我所知,为了能够在虚拟机上接收传入连接,我必须首先编写一个钩子,iptables在启动客户机时编辑我。

我使用虚拟机管理器作为 GUI 来启动我的虚拟机。我设置的钩子位于/etc/libvirt/hooks/qemu我试图打开的位置TCP/UDP port 6969UDP port 17对于我的虚拟机,它标记为“ Windows

    #!/bin/bash
    # used some from advanced script to have multiple ports: use an equal number of$

    # Update the following variables to fit your setup
    Guest_name=Windows
    Guest_ipaddr=192.168.122.99
    Host_ipaddr=192.168.122.1
    Host_port=(  '6969' '17' )
    Guest_port=( '6969' '17' )

    length=$(( ${#Host_port[@]} - 1 ))
    if [ "${1}" = "${Guest_name}" ]; then
       if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
           for i in `seq 0 $length`; do
                   iptables -t nat -D PREROUTING -d ${Host_ipaddr} -p tcp --dport $$
                   iptables -D FORWARD -d ${Guest_ipaddr}/32 -p tcp -m state --stat$
           done
       fi
       if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
           for i in `seq 0 $length`; do
                   iptables -t nat -A PREROUTING -d ${Host_ipaddr} -p tcp --dport $$
                   iptables -I FORWARD -d ${Guest_ipaddr}/32 -p tcp -m state --stat$
           done
       fi
    fi

我从 ifconfig 获得信息

    $ ifconfig
    eth0      Link encap:Ethernet  HWaddr d0:50:99:67:4a:b7  
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:17367 errors:0 dropped:6 overruns:0 frame:0
              TX packets:13439 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000 
              RX bytes:3494857 (3.4 MB)  TX bytes:2707716 (2.7 MB)

    lo        Link encap:Local Loopback  
              inet addr:127.0.0.1  Mask:255.0.0.0
              inet6 addr: ::1/128 Scope:Host
              UP LOOPBACK RUNNING  MTU:65536  Metric:1
              RX packets:3774 errors:0 dropped:0 overruns:0 frame:0
              TX packets:3774 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0 
              RX bytes:1303572 (1.3 MB)  TX bytes:1303572 (1.3 MB)

    vif1.0    Link encap:Ethernet  HWaddr fe:ff:ff:ff:ff:ff  
              UP BROADCAST MULTICAST  MTU:1500  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0 frame:0
              TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:32 
              RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

    vif1.0-emu Link encap:Ethernet  HWaddr fe:ff:ff:ff:ff:ff  
              inet6 addr: fe80::fcff:ffff:feff:ffff/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:1613 errors:0 dropped:0 overruns:0 frame:0
              TX packets:3307 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:500 
              RX bytes:508517 (508.5 KB)  TX bytes:1054123 (1.0 MB)

    xenbr0    Link encap:Ethernet  HWaddr d0:50:99:67:4a:b7  
              inet addr:192.168.2.100 Bcast:192.168.2.255 Mask:255.255.255.0
              inet6 addr: fe80::d250:99ff:fe67:4ab7/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:14808 errors:0 dropped:0 overruns:0 frame:0
              TX packets:11826 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0 
              RX bytes:2478850 (2.4 MB)  TX bytes:2165931 (2.1 MB)

这些是iptables,似乎被钩子打开了

    $ sudo iptables -L
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination         
    ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain
    ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domain
    ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootps
    ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:bootps

    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination         
    ACCEPT     all  --  anywhere             192.168.122.0/24     ctstate RELATED,ESTABLISHED
    ACCEPT     all  --  192.168.122.0/24     anywhere            
    ACCEPT     all  --  anywhere             anywhere            
    REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable
    REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable
    ACCEPT     all  --  anywhere             anywhere             PHYSDEV match --physdev-out vif2.0 --physdev-is-bridged
    ACCEPT     all  --  anywhere             anywhere             PHYSDEV match --physdev-in vif2.0 --physdev-is-bridged
    ACCEPT     all  --  anywhere             192.168.122.0/24     state NEW,RELATED,ESTABLISHED

    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination         
    ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootpc

这是我找到钩子的地方:http://wiki.libvirt.org/page/Networking#Forwarding_Incoming_Connections

有些人会对网络接口感到好奇,所以这里:

    auto lo
    iface lo inet loopback

    auto eth0
    iface eth0 inet manual

    auto xenbr0
    iface xenbr0 inet static
            bridge_ports eth0
            address 192.168.2.100
            netmask 255.255.255.0
            gateway 192.168.2.1
            dns-nameservers 192.168.2.1

默认网络配置:

    <network>
      <name>default</name>
      <bridge name="virbr0"/>
      <forward/>
      <ip address="192.168.122.1" netmask="255.255.255.0">
        <dhcp>
          <range start="192.168.122.2" end="192.168.122.254"/>
        </dhcp>
      </ip>
    </network>

输出sudo iptables -t nat -v -x -n -L

    Chain PREROUTING (policy ACCEPT 4326 packets, 267215 bytes)
        pkts      bytes target     prot opt in     out     source               destination         
           9      528 DNAT       tcp  --  *      *       0.0.0.0/0            192.168.2.100        tcp dpt:6969 to:192.168.122.99:6969
           0        0 DNAT       tcp  --  *      *       0.0.0.0/0            192.168.2.100        tcp dpt:6969 to:192.168.122.0:6969
           0        0 DNAT       tcp  --  *      *       0.0.0.0/0            192.168.122.1        tcp dpt:6969 to:192.168.122.0:6969
           0        0 DNAT       tcp  --  *      *       0.0.0.0/0            192.168.122.1        tcp dpt:6969 to:192.168.122.99:6969

    Chain INPUT (policy ACCEPT 3457 packets, 177928 bytes)
        pkts      bytes target     prot opt in     out     source               destination         

    Chain OUTPUT (policy ACCEPT 2010 packets, 132685 bytes)
        pkts      bytes target     prot opt in     out     source               destination         

    Chain POSTROUTING (policy ACCEPT 2609 packets, 213516 bytes)
        pkts      bytes target     prot opt in     out     source               destination         
           5      365 RETURN     all  --  *      *       192.168.122.0/24     224.0.0.0/24        
           0        0 RETURN     all  --  *      *       192.168.122.0/24     255.255.255.255     
           0        0 MASQUERADE  tcp  --  *      *       192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
           0        0 MASQUERADE  udp  --  *      *       192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
           0        0 MASQUERADE  all  --  *      *       192.168.122.0/24    !192.168.122.0/24  

答案1

发布网络配置后,我发现您正在为 Libvirt 使用不同的子网。这是错误的,尤其是考虑到您在192.168.2.100用于 Libvirt 的桥接接口上使用,而虚拟机(位于同一桥接上)已分配192.168.122.0/24

无论如何,如果您坚持使用双 NAT,请在您的设置中反映这一点。将模式设置为 NAT 或在桥的两端使用相同的 IP 范围。

你现在做的事情非常令人困惑,而且会在某个时间点给你带来麻烦。你的问题已经在 Server Fault 上得到解答(尽管花了一些时间才弄清楚你的问题到底是什么)。答案如下:Debian 上的 iptables 端口转发

答案2

编辑:原来 OP 使用了具有两个不同子网的网桥。在编辑之前,这个问题并不清楚,并且这个答案是在假设网桥两端具有相同子网的情况下编写的。

您没有在 Libvirt 盒上使用 NAT。我怀疑您正在运行家庭实验室,您的 ISP 调制解调器会为您执行 NAT 操作?您的 Libvirt 盒已配置桥接。

这意味着,很可能您无需执行任何操作,iptables代码中的命令也是不必要的。虚拟机已暴露在您的本地网络中192.168.2.0/24,如果您想让它们可从互联网访问,则必须在路由器中执行此操作(这不是 Libvirt 问题,不值得在此线程中讨论)。


例外的是,虚拟机可能ebtables如果您正在使用或启用此功能,则无法访问net.bridge.bridge-nf-call-iptables。但是,我怀疑这里的情况并非如此。

相关内容