配置xen上VM混杂模式,使其能捕获物理网络流量

本文目的:

配置VM和xen相应的物理网卡(pif)和虚拟网卡(vif)的混杂模式,使得所有物理网路上的流量能被该VM捕获


首先需要配置交换机镜像口,这部分不在本文讨论范围内,百度一下你就知道。
本文镜像口插在eth0(pif),接虚拟网桥xenbr0,虚拟网卡vif3.0也接在该网桥上。

本文重点在将流经xenserver物理端口的数据,映射到某台VM上。
这里会有用到虚拟网桥。通过一个例子讲清大概拓扑,具体原理实现,自行百度。
eg:物理端口eth0,会接到这个xenbr0上,其中eth0与xenbr0的MAC相同。
        创建或启动VM时,会将VM上的虚拟网卡也生成虚拟端口连接到xenbr0上。这也就是传说中的桥接。
上一张图便于理解,要完成的拓扑:
配置xen上VM混杂模式,使其能捕获物理网络流量_第1张图片

主要步骤:

1.配置pif为混杂模式

1.1.在XenServer/XCP host上运行下面操作,得到PIF UUID:
# xe pif-list network-name-label=
是Xen中网络的名字(比如:Network 0)
然而实际不那么好用,直接 xe pif-list 查看全部再找就好。
记下目标PIF的UUID,用在下一条命令中。

1.2.开启该PIF的混杂模式,在XenServer/XCP host上运行如下指令:
# xe pif-param-set uuid= other-config:promiscuous="true"
是第一步中得到的 PIF的UUID。

1.3.运行下面的命令,检查pif的混杂模式是否开启:
# xe pif-param-list uuid=
命令结果中包含如下内容表示成功:
other-config (MRW): promiscuous: true


2.配置VIF为混杂模式

2.1.在XenServer/XCP host上运行下面操作,得到PIF UUID:
# xe vif-list vm-name-label=
是虚拟机在XenCenter中出现的名字
记下目标PIF的UUID,用在下一条命令中。

2.2.开启该VIF的混杂模式,在XenServer/XCP host上运行如下指令:
# xe vif-param-set uuid= other-config:promiscuous="true"
是第一步中得到的 VIF的UUID。

2.3.运行下面的命令,检查pif的混杂模式是否开启:
# xe vif-param-list uuid=
命令结果中包含如下内容表示成功:
other-config (MRW): promiscuous: true

3.重置VM的虚拟网卡,使更改生效。

运行如下命令,使更改生效:
# xe vif-unplug uuid=
# xe vif-plug uuid=
这步操作会使得VIF与VM先断开连接,再重连。
同时,也会使得VM与虚拟网桥断开,运行 vif-plug 后重新连上。

4.VM上端口开混杂模式:

CentOS:需要在系统中用 ifconfig (net-tools)或者 ip (iproute2) 开启虚拟机的eth0混杂模式
开启:# ifconfig eth0 promisc
关闭:# ifconfig eth0 -promisc
或者ip命令开启关闭:
ip link set eth0 promisc on|off
或者,重启仍有效的方式:(centos7据说失效)
在/etc/sysconfig/network-scripts/ifcfg-eth*文件中添加 PROMISC=yes
用netstat -i 检查eth是否配置promisc成功。(flag字段有‘P’)


然而实际情况没有成功,可能由于我的XCP(Xen Cloud Platform)中ovs版本或者配置不一样,vif还是抓不到外面的包。
设想了3个方案:
1.ovs上配置镜像口到vif3.0
2.创建一个linux网桥,将eth0与vif3.0接到上面,将该网桥ageing设置为0,使其相当于一个hub。
3.关闭ovs上的l3
4.在ovs上写流规则,将流经eth0的数据都转发到vif3.0

结果:
方案1,可行,实验成功。
方案2,由于Xen默认没有linux网桥的包,会提示add bridge failed: Package not installed。
google百度后得知需要编译包,据说linux网桥和ovs共存会冲突,本着尽量不给domain0增加东西的原则,放弃该方案。
后期如果流量大,OVS做镜像出现效率瓶颈的时候,可以考虑进一步实验。ovs也应该也可以设置ageing来达到转化为hub。
方案3,分析认为不可行,l3负责三层,即使关闭,二层的MAC转发表也会产生作用,转发不到。
方案4,没做,方案1的镜像方式,在实现上应该也是写的流规则。

5.OpenVswitch的镜像口配置:

确定镜像目的端口vifx.x:

xe vm-list name-label=ccj- params=dom-id

ccj-是你虚拟机的名称,得到虚拟机的dmain_id,假设结果为:
dom-id ( RO)    : 3
如果镜像到目标VM上的eth0,对应的ovs虚拟端口为vif3.0

执行下面命令,将网桥xenbr0上所有流入流出eth0的,镜像到vif3.0:

# ovs-vsctl -- set Bridge xenbr0 mirrors=@m \
 -- --id=@eth0 get Port eth0 \
 -- [email protected] get Port vif3.0 \
 -- --id=@m create Mirror name=mymirror select-dst-port=@eth0 select-src-port=@eth0 [email protected]
返回结果是镜像id
执行下面命令,检查镜像配置
#ovs-vsctl list Bridge xenbr0
_uuid : e3e03141-9754-489b-b4b8-17de2f063b44
controller : []
datapath_id : "0000009c029752bd"
datapath_type : ""
external_ids : {}
fail_mode : []
flood_vlans : []
flow_tables : {}
mirrors : [b74eaf43-92ca-48f5-9fe6-9a561a9937dd] // The mirror id is the one shown after the previous command

如果想清除镜像,运行如下命令
# ovs-vsctl clear Bridge xenbr0 mirrors

至此,我的VM(centOS)tcpdump可以抓到外面物理网络,镜像口上的数据了。

发现VM,vif会变,原因是因为XEN动态分配domain id。VM shutdown时,id=-1
所谓的解决办法:
1.做一个定时任务,比如每10s,查domain id是否更改,如果更改重做镜像
     其中最近一次的id可以存在一个文件中。
自己瞎写了个脚本,很少写shell,请勿黑: 点我去下载页
2.在xenserver中加入一个开机执行脚本,将上一步中文件暂存id置-1。
    这个目的是为了防止xenserver断电、重启等情况,目标VM分到与之前一样id的domain域,导致没有更新镜像。


参考文献:
[1]  How to Configure a Promiscuous Virtual Machine in XenServer 
[2]  OpenVswitch – Port mirroring



你可能感兴趣的:(xen,ovs,linux,ovs,xen)