通过端口转发寻求一个好的单个ip路由配置

时间:2015-06-25 12:48:23

标签: networking virtual-machine router gateway xen

我已经在家中运行Xen on Debian 8,在桥接模式下运行了几年,主要是为了尝试PCI passthrough功能进行游戏,并且仍然可以使用本地Linux环境。我已经开始定期建立xen,从4.2不稳定到4.5.1这几天,我很想在今年夏天之后尝试使用4.6版本的qxl加速驱动程序。

但是今天,我的问题远远没有通过。我有几个月租用这个专用服务器,它只有一个IP,我从来没有成功设置vm的内部网络配置。我在网上找到的很多脚本都是针对xen的低级版本,以及网络和版本。 vif脚本改变了很多。

我想要的只是一种干净的方式让我的VM得到广告,无论是基于MAC地址还是静态地进入192.168.88.0/24子网,并且能够 将端口列表(tcp或udp)转发到特定的vm

所以这是我的配置文件:

的/ etc /网络/接口

auto lo
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet dhcp

auto dummy0
iface dummy0 inet manual
        pre-up ifconfig $IFACE up
        post-down ifconfig $IFACE down

auto xenbr0
iface xenbr0 inet static
        bridge_ports dummy0
        address 192.168.88.254
        broadcast 192.168.88.255
        netmask 255.255.255.0
        bridge_maxwait 0
        bridge_stp off
        bridge_fd 0

netstat -rn

Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         62.210.115.1    0.0.0.0         UG        0 0          0 eth0
62.210.115.0    0.0.0.0         255.255.255.0   U         0 0          0 eth0
192.168.88.0    0.0.0.0         255.255.255.0   U         0 0          0 xenbr0

iptables -L&& iptables -t nat -L

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             PHYSDEV match --physdev-out vif1.0 --physdev-is-bridged
ACCEPT     udp  --  anywhere             anywhere             PHYSDEV match --physdev-in vif1.0 --physdev-is-bridged udp spt:bootpc dpt:bootps
ACCEPT     all  --  anywhere             anywhere             PHYSDEV match --physdev-out vif1.0 --physdev-is-bridged
ACCEPT     all  --  192.168.88.2         anywhere             PHYSDEV match --physdev-in vif1.0 --physdev-is-bridged

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

--

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
DNAT       tcp  --  anywhere             anywhere             tcp dpt:2222 to:192.168.88.2:22
DNAT       tcp  --  anywhere             anywhere             tcp dpt:8888 to:192.168.88.2:80

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

/ etc / network / interfaces [domU]

auto lo
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet dhcp
        address 192.168.88.2
        broadcast 192.168.88.255
        netmask 255.255.255.0
        gateway 192.168.88.254

对于xen中的网络脚本,我已经创建了一个vif-bridge脚本的副本,我已经添加了两行来使用一个处理iptables规则的小脚本(在互联网上找到,可能是不完整的iptable规则) )

/etc/xen/script/portmapper.py

#!/usr/bin/env python
netdev='eth0' 
# {'domU'_ip:[(domU_port, dom0port, ['tcp'|'udp']), (domU_port, dom0port), ..}
# 3rd param - protocol is optional - if not specified, tcp is default
portmap={'192.168.88.2': [(22, 2222), (80, 8888)],
        '192.168.88.3': [(8081, 10001), (22, 10002)],
        '192.168.88.4': [(6697, 6697)],
        }

# do not edit below this line
ip_tables_proto='iptables -%s PREROUTING -t nat -p %s -i %s --dport %d -j DNAT --to %s:%d\n'
import sys
is_delete=False
def usage():
    print >>sys.stderr, 'Usage: %s [-d] domU_ip' % sys.argv[0]
    sys.exit(1)
def is_ip(adr):
    ip_list=adr.split('.')
    if len(ip_list)!=4:
        usage()
    for i in ip_list:
        try:
            if int(i)>255 or int(i)<0:
                usage()
        except ValueError:
            usage()

args_no=len(sys.argv)

if args_no==3:
    if sys.argv[1]=='-d':
        is_delete=True
    ip=sys.argv[2]
    is_ip(ip)
elif args_no==2:

    ip=sys.argv[1]
    is_ip(ip)
else:
    usage()

if is_delete:
    action="D"
else:
    action="A"

mapping=portmap.get(ip, [])
cmds=''
for port_map in mapping:
    if len(port_map)==3 and port_map[2] in ('tcp', 'udp'):
        from_port, to_port, proto=port_map
    elif len(port_map)==2:
        from_port, to_port=port_map
        proto='tcp'
    cmds+=ip_tables_proto % (action, proto, netdev, to_port, ip, from_port)

import os
os.system(cmds)

的/ etc / xen的/脚本/ VIF桥-NAT

#!/bin/bash
#============================================================================
# ${XEN_SCRIPT_DIR}/vif-bridge-nat
# Script for configuring a vif in bridged mode.
#
# Usage:
# vif-bridge (add|remove|online|offline)
#
# Environment vars:
# vif         vif interface name (required).
# XENBUS_PATH path to this device's details in the XenStore (required).
#
# Read from the store:
# bridge  bridge to add the vif to (optional).  Defaults to searching for the
#         bridge itself.
# ip      list of IP networks for the vif, space-separated (optional).
#
# up:
# Enslaves the vif interface to the bridge and adds iptables rules
# for its ip addresses (if any).
#
# down:
# Removes the vif interface from the bridge and removes the iptables
# rules for its ip addresses (if any).
#============================================================================

dir=$(dirname "$0")
. "$dir/vif-common.sh"

bridge=${bridge:-}
bridge=$(xenstore_read_default "$XENBUS_PATH/bridge" "$bridge")

ip=${ip:-}

if [ -z "$bridge" ]
then
  bridge=$(brctl show | awk 'NR==2{print$1}')

  if [ -z "$bridge" ]
  then
     fatal "Could not find bridge, and none was specified"
  fi
else
  #
  # Old style bridge setup with netloop, used to have a bridge name
  # of xenbrX, enslaving pethX and vif0.X, and then configuring
  # eth0.
  #
  # New style bridge setup does not use netloop, so the bridge name
  # is ethX and the physical device is enslaved pethX
  #
  # So if...
  #
  #   - User asks for xenbrX
  #   - AND xenbrX doesn't exist
  #   - AND there is a ethX device which is a bridge
  #
  # ..then we translate xenbrX to ethX
  #
  # This lets old config files work without modification
  #
  if [ ! -e "/sys/class/net/$bridge" ] && [ -z "${bridge##xenbr*}" ]
  then
     if [ -e "/sys/class/net/eth${bridge#xenbr}/bridge" ]
     then
        bridge="eth${bridge#xenbr}"
     fi
  fi
fi

RET=0
ip link show dev $bridge 1>/dev/null 2>&1 || RET=1
if [ "$RET" -eq 1 ]
then
    fatal "Could not find bridge device $bridge"
fi

case "$command" in
    online)
        setup_virtual_bridge_port "$dev"
        set_mtu $bridge $dev
        add_to_bridge "$bridge" "$dev"
        $dir/portmap.py $ip
        ;;

    offline)
        do_without_error brctl delif "$bridge" "$dev"
        do_without_error ifconfig "$dev" down
        $dir/portmap.py -d $ip
        ;;

    add)
        setup_virtual_bridge_port "$dev"
        set_mtu $bridge $dev
        add_to_bridge "$bridge" "$dev"
        ;;
esac

handle_iptable

call_hooks vif post

log debug "Successful vif-bridge $command for $dev, bridge $bridge."
if [ "$type_if" = vif -a "$command" = "online" ]
then
  success
fi

ATM,我的VM甚至没有对外的访问。我一直在玩tcpdump,ping和wget试图看看发生了什么,并调整配置,有时管理得到请求,回到dom0然后被droped,在错误的界面上路由,没有找到他的方式到VM。我觉得我只是缺少一些小碎片或螺丝...... 我也尝试过使用带有isc-dhcp-server的vif-nat,没有任何成功。能够命名vm然后将'map'映射到dns可能是有用的,所以如果你对这个想法有任何信息。

感谢您的时间。

1 个答案:

答案 0 :(得分:0)

没关系,我只是缺少2个iptables线,这是我缺少的

{
  array = [ { "a" : "b" }, { "c" : "d" } ]
  nb_elements = 2
}

我把它放在我的/etc/rc.local中,这样它就可以在启动后立即执行一次(我先把它放在/ etc / network / interfaces中,但是每个vm的规则都会成倍增加

我的端口转发脚本完成了它的工作,因此端口得到正确映射,规则在创建时添加,并在销毁时删除。

我可能会更深入地研究一下我的网络规则,因为我怀疑它们是否真的很完美,但是它确实起到了作用。