电脑技术学习

VMware实现一台电脑中的网络

dn001
本文探讨在一台机器上用Vmware模拟多个电脑,并实现较复杂的网络环境下多个模拟机器的联网,并以zebra路由软件和ipv6使用为例做了测试和说明。

为什么要做这个测试?

使用vmware对于软件开发人员和网络维护人员,非常有意义。不仅仅在于它可以方便简洁的模拟出一个虚拟的机器环境以供工作使用,而且在于在对OS有部分有影响的操作如网络攻击、破坏性实验等,如果采用vmware将非常非常安全,因为虚拟环境的影响仅仅是对一个数据文件的影响,不会真正对host主机硬件设备软件程序产生其他问题。生产系统上面的系统调整在没有经过测试数据的证明,贸然的直接上线将暗含巨大的风险,如果软件开发或者系统管理人员使用vmware将非常适合进行此类的测试和研究。

另外,很多网络环境的测试和实验,我们必须使用交换机(或者hub),一堆网线,多台测试设备。在笔者从前进行过的在用cisco的25系列的路由器进行网络实验时,5台cisco路由器和一堆网线的连接工作量可不小,而且这种实验代价昂贵。

vmware workstation版本是vmware公司针对桌面用户在单机条件下开发的虚拟电脑软件。利用该软件,用户可以根据本机的情况,定制多个虚拟电脑同时运行在一个真实的操作平台下和一个复杂的网络环境下。在某种情况下可以令人惊叹的抛弃那一大堆的网络设备了!

还有一点,目前使用vmware做单个系统的资料非常多,但是注重虚拟网络环境的资料还不是非常多见,这里可以希望抛砖引玉。

VMWare是什么?

Vmware是vmware inc 的一个强大的虚拟机器软件(http://www.vmware.com/)。它有多个版本,有针对服务器的GSX、ESX版本,和针对桌面用户的workstation版本。在vmware中可以提供很完备的以太网环境,甚至在vmware中有9个虚拟的交换机可以供我们使用!更多的信息请查看他的Online Manual。

实验环境

路由器是网络中的核心设备,在实际的网络环境中进行路由器的测试学习和研究是现实的,而搭建一个较复杂的路由器环境是代价不菲的。利用linux下面的强大路由器软件zebra,借助vmware的virtual network,我们可以搭建自己的路由器实验环境,并可以根据自己的需求情况继续扩展。另外,ipv6等测试必须借助多台网络设备,并使用网络分析工具进行分析,才能更好的理解和学习。

1,环境准备:
实验环境:

1) IBM ThinkPad R40e 笔记本电脑(cpu p4 2.0G,256M内存,30Gdisk)

2) Windowns XP Home Edition + sp1

3) vmware workstation 4.0.5 build-6030 + 30days license

2,更改网络配置:

安装了vmware之后,首先我更改了vmware的网络环境(在vmware的edit菜单中找到virtual network setting)。步骤如下:

1) 点Edit下Virtual Network Setting… ,弹出Virtual network Editor对话框;

2) 在Virtual network Editor对话框中的Host Virtual Network Mapping中点Vmnet1后面的按钮…,再点弹出菜单的subnet,然后设定子网;

3) subnet1设定为192.168.1.0/255.255.255.0;mnet2,Vmnet3,Vmnet4,Vmnet8,Vmnet9的子网分别为192.168.2.0/255.255.255.0, 192.168.3.0/255.255.255.0, 192.168.4.0/255.255.255.0, 192.168.8.0/255.255.255.0, 192.168.9.0/255.255.255.0。

4) 其他vmnet空闲,最多可以设定9个子网,可以根据需要设定。


3,网络定制优化:

1) 由于默认安装的vmware采用的是ip地址通过dhcp获得,我在安装好之后就禁用了vmware的dhcpd服务,然后禁用了各个子网使用dhcp获得ip。

2) 如果为了使虚拟机器访问外部网络,应该设置一个vmnet可以使用NAT服务对外访问,默认vmnet8可以通过NAT访问外部网络。此子网段默认的网关设置为192.168.8.2,并确保NAT service服务启动。

3) 确认Automatic Bridging 的Enable Automatic Bridge的Automatically choose an available physical network adapter to bridge to Vmnet0 选项被选。

4,虚拟机定制优化

为了在一台机器运行多个虚拟机器,最好对每个虚拟机器做些优化工作。根据使用经验,在运行任务不多的虚拟机器上面,对内存的需求远大于cpu的利用。因此,我们安装R1、R2、R3、R4和R5这五个以Debian GNU/Linux为基础虚拟机器,并建议对每个虚拟机器的kernel进行优化,以减少对实际机器的系统开销。个人的做法如下:

1) 最简安装了一个虚拟系统Debian 3,安装目标文件夹和该虚拟机都命名为R1;

2) 增加必须的虚拟机硬件,譬如网卡等;

3) 在其他debian linux虚拟机环境中编译好bin的软件工具,通过scp或者ftp等方式拿到R1虚拟机器中来,并做相关的配置。这里我安装了部分网络工具如iputils,iproute2,tcpdump,sshd,zebra等软件;

4) 为了做ipv6测试,在其他环境中编译一个支持ipv6 的kernel也拿到R1虚拟中;

5) 为zebra做预准备:在/usr/local/zebra/etc下更改.sample文件为conf文件;

6) 确认R1虚拟机器准备好后,关闭R1虚拟机;

7) 然后将这个安装系统的数据文件夹备份一份作为永久备份,再拷贝4份,分别命名为R2,R3,R4,R5;

8) 然后在vmware中打开现存的虚拟机器打开这新加入的4个虚拟机器,并在option中更改各自的Vitrual machine name 分别为R2,R3,R4,R5;

9) 分别更改R2,R3,R4,R5的相应设置和hostname等,并相应更改ip地址/ipv6地址等。

5,构建如下网络拓扑图:


6,测试:

分别启动R1到R5的虚拟机器,并检查虚拟网络的联通性。在每个虚拟机器中检查唯一相同网段的其他虚拟机器,以R1为例做相关测试。如果您对网络的通信过程希望有更加深入观察,请在R1的第二个console界面打开tcpdump,随时查看想要观察的信息。

1)检测网卡地址%20ifconfig%20或者ip命令:

R1:~# ip a
1: eth0: mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:0c:29:ae:a1:59 brd ff:ff:ff:ff:ff:ff
inet 192.168.8.11/24 brd 192.168.8.255 scope global eth0
inet6 fe80::20c:29ff:feae:a159/64 scope link
2: eth1: mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:0c:29:ae:a1:63 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.11/24 brd 192.168.1.255 scope global eth1
inet6 fe80::20c:29ff:feae:a163/64 scope link
3: eth2: mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:0c:29:ae:a1:6d brd ff:ff:ff:ff:ff:ff
inet 192.168.2.11/24 brd 192.168.2.255 scope global eth2
inet6 fe80::20c:29ff:feae:a16d/64 scope link
4: lo: mtu 16436 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
5: sit0: mtu 1480 qdisc noop
link/sit 0.0.0.0 brd 0.0.0.0

2)网络联通性 ping 或者ping6 或者arping命令:

R1:~# ping 192.168.8.12
PING 192.168.8.12 (192.168.8.12): 56 data bytes
64 bytes from 192.168.8.12: icmp_seq=0 ttl=64 time=14.0 ms
64 bytes from 192.168.8.12: icmp_seq=1 ttl=64 time=1.9 ms

--- 192.168.8.12 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 1.9/5.0/14.0 ms

zebra路由软件使用

1) 以运行daemon方式启动zebra,zebra就开始监听本地的2602端口,其他各个路由协议的daemon进程分别监听不同的服务端口(ripd监听tcp 2602和udp520端口,ospfd监听tcp 2604端口,bgpd监听tcp179端口和2605端口,ospf6d监听tcp (ipv4和ipv6)的2606端口)。

2) 从pc机器上telnet到R1的zebra服务,用户名口令默认都是zebra,看看界面是不是和cisco的路由器有些想象呢。 :)



3) 利用R2,R3,R4,R5其他做路由实验。注意,这里不光可以利用zebra的各种路由软件的debug观察路由协议的工作过程,还可以利用linux的tcpdump来进行更加详细的观察。

4) 启动各个虚拟机器的zebrad和相关路由协议进程服务(为了更好的实验,各个路由协议分别测试);

5) 打开动态路由发现,看看是不是一会儿各个路由器都被发现啦? :)

虚拟机器网络环境用路由器模式表示就是如下的了:



6) 我们可以充分发挥想象,利用这么多台路由器实验各种路由协议。如果你又更多的想法譬如使用串口、并口通信也大可以试一试。:)

7) zebra更加详细的使用请阅读zebra的手册和其他资料。

ipv6软件的测试环境

ipv6是ip协议的下一个版本,并随着网络技术的发展,越来越进入大家的视线。这里做一个简单的ipv6的测试,以便检验利用vmware新建立的网络。建议在测试虚拟机器的其他console界面打开tcpdump -6 详细观察ipv6的协议工作情况。

1) Ipv6测试准备:
在安装系统时候已经安装了iproute和iputils都是可以对ipv6进行测试的工具,另外部分linux版本默认是没有加载ipv6支持模块的,在每个请加载之。

R1:~# modprobe ipv6 && lsmod |grep ipv6

如果成功加载ipv6模块请进行下面

R1:~# ip -6 a s
1: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qlen 1000
inet6 fe80::20c:29ff:feae:a159/64 scope link
2: eth1: <BROADCAST,MULTICAST,UP> mtu 1500 qlen 1000
inet6 fe80::20c:29ff:feae:a163/64 scope link
3: eth2: <BROADCAST,MULTICAST,UP> mtu 1500 qlen 1000
inet6 fe80::20c:29ff:feae:a16d/64 scope link
4: lo: <LOOPBACK,UP> mtu 16436
inet6 ::1/128 scope host

2) 发现网络上其他ipv6设备:

ipv6协议将不再支持arp协议,因此在ipv6中发现网络上其他ipv6设备可以使用如下方式:

R1:~# ping6 -I eth0 ff02::1
PING ff02::1(ff02::1) from fe80::20c:29ff:feae:a159 eth0: 56 data bytes
64 bytes from ::1: icmp_seq=1 ttl=64 time=0.200 ms
64 bytes from fe80::20c:29ff:fe07:1b34: icmp_seq=1 ttl=64 time=6.22 ms (DUP!)
64 bytes from fe80::20c:29ff:fe94:1776: icmp_seq=2 ttl=64 time=1.56 ms (DUP!)

这里采用ipv6中的本地连接多播地址(link-local multicast address)ff02::1来发现 同网络上的其他ipv6设备。这里发现的fe80::20c:29ff:fe07:1b34和fe80::20c:29ff:fe94:1776分别属于R2的eth0的ipv6地址和R3的eth0地址。(由于R4没有开启ipv6,将不能看到R4的相应ipv6地址)

R1:~# ping6 -I eth0 fe80::20c:29ff:fe07:1b34
PING fe80::20c:29ff:fe07:1b34(fe80::20c:29ff:fe07:1b34) from fe80::20c:29ff:feae:a159 eth0: 56 da bytes
64 bytes from fe80::20c:29ff:fe07:1b34: icmp_seq=1 ttl=64 time=6.10 ms
64 bytes from fe80::20c:29ff:fe07:1b34: icmp_seq=2 ttl=64 time=89.1 ms

--- fe80::20c:29ff:fe07:1b34 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 1.835/32.373/89.185/40.209 ms

ipv6中的ping命令是iputil工具包中的ping6命令,必须注意的是 由于有多个网卡接口,必须使用 -I 指定使用哪个网卡接口。

3) 发现ipv6路由:

默认路由中ipv6路由表如下:

R1:~# ip -6 r
fe80::/64 dev eth0 metric 256 mtu 1500 advmss 1440
fe80::/64 dev eth1 metric 256 mtu 1500 advmss 1440
fe80::/64 dev eth2 metric 256 mtu 1500 advmss 1440
ff00::/8 dev eth0 metric 256 mtu 1500 advmss 1440
ff00::/8 dev eth1 metric 256 mtu 1500 advmss 1440
ff00::/8 dev eth2 metric 256 mtu 1500 advmss 1440
default dev eth0 proto kernel metric 256 mtu 1500 advmss 1440
default dev eth1 proto kernel metric 256 mtu 1500 advmss 1440
default dev eth2 proto kernel metric 256 mtu 1500 advmss 1440
unreachable default dev lo proto none metric -1 error -101

4) 测试本地ipv6服务

linux系统目前支持ipv6的服务器软件已经非常多,常用的软件如opensshd/sshd,apache,bind,telnetd, iptables-ipv6,nmap等。这里以sshd作为一个测试。

R1:~# ssh -6 ::1
Host key not found from database.
Key fingerprint:
xobit-pihuz-gypek-lokad-leliz-hupim-pavek-pyvem-canam-nefaf-laxax
You can get a public key's fingerprint by running
% ssh-keygen -F publickey.pub
on the keyfile.
Are you sure you want to continue connecting (yes/no)?

5) ipv6-in-ipv4 tunnel测试

由于ipv4在网络中已经实现了多年,而且Internet的发展更加促使ipv4的发展,目前ipv6在网络中的实际情况是ipv6象一个孤岛被ipv4的海洋包围,各个ipv6网络的连接还需要通过ipv4网络,实际中比较常见的有ipv6-in-ipv4隧道等。这里利用本虚拟环境进行点对点的IPv6-in-IPv4 tunnel的实验(R1-R2)。

在R1机器上面:

ip -6 addr add 3ffe:3200::1/24 dev eth0 #给eth0设定一个本地ipv6地址,以CERNET的测试ipv6地址为例
ip tunnel add 6to4 mode sit remote 192.168.8.12 local 192.168.8.11 #加入一个6to4通道
ip link set dev 6to4 up #激活6to4通道
ip -6 addr add 3ffe:3200::1/24 dev 6to4 #给通道加入本地ipv6地址
ip -6 r add 3ffe:3200::2/24 dev 6to4 #加入使用通道设备的ipv6路由,由于使用的点对点的测试,目的网络是对端的ipv6地址

在R2机器上面:

ip -6 addr add 3ffe:3200::2/24 dev eth0
ip tunnel add 6to4 mode sit remote 192.168.8.11 local 192.168.8.12
ip link set dev 6to4 up
ip -6 addr add 3ffe:3200::2/24 dev 6to4
ip -6 r add 3ffe:3200::1/24 dev 6to4

也可以加入R3,R4,R5的ipv6 tunnel,以供更加复杂的测试。


在R1和R2设备上面,使用ping6命令查看对端的ipv6地址可以到达;

在R1和R2设备上面,使用ssh -6 ipv6地址通过ipv6 tunnel登录点对点连接的其他ipv6设备;

R1:~# ssh -6 3ffe:3200::2
Host key not found from database.
Key fingerprint:
xobit-pihuz-gypek-lokad-leliz-hupim-pavek-pyvem-canam-nefaf-laxax
You can get a public key's fingerprint by running
% ssh-keygen -F publickey.pub
on the keyfile.
Are you sure you want to continue connecting (yes/no)? yes
Host key saved to /root/.ssh2/hostkeys/key_22_3ffe:3200::1.pub
host key for 3ffe:3200::1, accepted by root Wed Mar 31 2004 19:12:51 +0800
root's password:
Authentication successful.
R2:~# w
08:16:21 up 3:02, 3 users, load average: 0.00, 0.01, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/7 3ffe:3200::11 08:16 0.00s 0.13s 0.04s w
R2:~#

Ok,我们已经通过ipv6-in-ipv4的tunnel看到我们使用ipv6地址登录到另外的设备上面了!

此过程在R2上面的tcpdump结果:

08:23:35.833428 3ffe:3200::2.1047 > 3ffe:3200::1.ssh: S 2462930696:2462930696(0) win 5760 <mss 1440,sackOK,timestamp 19066103 0,nop,wscale 0>
08:23:35.835364 192.168.8.12 > 192.168.8.11: 3ffe:3200::1.ssh > 3ffe:3200::2.1047: S 1730732585:1730732585(0) ack 2462930697 win 5632 <mss[|tcp]> (encap)
08:23:35.860756 3ffe:3200::2.1047 > 3ffe:3200::1.ssh: . ack 1 win 5760 <nop,nop,timestamp 19066109 11103448>
08:23:35.919035 192.168.8.12 > 192.168.8.11: 3ffe:3200::1.ssh > 3ffe:3200::2.1047: P 1:50(49) ack 1 win 5632 <nop,nop,[|tcp]> (encap)
08:23:35.925164 3ffe:3200::2.1047 > 3ffe:3200::1.ssh: . ack 50 win 5760 <nop,nop,timestamp 19066127 11103532>
08:23:35.925193 3ffe:3200::2.1047 > 3ffe:3200::1.ssh: P 1:50(49) ack 50 win 5760 <nop,nop,timestamp 19066135 11103532>
08:23:35.926647 192.168.8.12 > 192.168.8.11: 3ffe:3200::1.ssh > 3ffe:3200::2.1047: . ack 50 win 5632 <nop,nop,[|tcp]> (encap)
08:23:35.936087 192.168.8.12 > 192.168.8.11: 3ffe:3200::1.ssh > 3ffe:3200::2.1047: P 50:538(488) ack 50 win 5632 <nop,nop,[|tcp]> (encap)
08:23:35.954300 3ffe:3200::2.1047 > 3ffe:3200::1.ssh: P 50:546(496) ack 538 win 6432 <nop,nop,timestamp 19066165 11103549>
08:23:35.994265 192.168.8.12 > 192.168.8.11: 3ffe:3200::1.ssh > 3ffe:3200::2.1047: . ack 546 win 6432 <nop,nop,[|tcp]> (encap)
08:23:35.995267 3ffe:3200::2.1047 > 3ffe:3200::1.ssh: P 546:706(160) ack 538 win 6432 <nop,nop,timestamp 19066204 11103607>
08:23:35.995479 192.168.8.12 > 192.168.8.11: 3ffe:3200::1.ssh > 3ffe:3200::2.1047: . ack 706 win 6432 <nop,nop,[|tcp]> (encap)
08:23:36.117795 192.168.8.12 > 192.168.8.11: 3ffe:3200::1.ssh > 3ffe:3200::2.1047: P 538:1578(1040) ack 706 win 6432 <nop,nop,[|tcp]> (encap)
08:23:36.127435 3ffe:3200::2.1047 > 3ffe:3200::1.ssh: . ack 1578 win 8320 <nop,nop,timestamp 19066260 11103731>
08:23:36.127761 192.168.8.12 > 192.168.8.11: 3ffe:3200::1.ssh > 3ffe:3200::2.1047: P 1578:1610(32) ack 706 win 6432 <nop,nop,[|tcp]> (encap)
08:23:36.137272 3ffe:3200::2.1047 > 3ffe:3200::1.ssh: . ack 1610 win 8320 <nop,nop,timestamp 19066311 11103740>
08:23:36.145247 3ffe:3200::2.1047 > 3ffe:3200::1.ssh: P 706:738(32) ack 1610 win 8320 <nop,nop,timestamp 19066382 11103740>
08:23:36.147153 192.168.8.12 > 192.168.8.11: 3ffe:3200::1.ssh > 3ffe:3200::2.1047: . ack 738 win 6432 <nop,nop,[|tcp]> (encap)
08:23:36.151282 3ffe:3200::2.1047 > 3ffe:3200::1.ssh: P 738:826(88) ack 1610 win 8320 <nop,nop,timestamp 19066385 11103760>
08:23:36.156464 192.168.8.12 > 192.168.8.11: 3ffe:3200::1.ssh > 3ffe:3200::2.1047: . ack 826 win 6432 <nop,nop,[|tcp]> (encap)
08:23:36.157473 192.168.8.12 > 192.168.8.11: 3ffe:3200::1.ssh > 3ffe:3200::2.1047: P 1610:1698(88) ack 826 win 6432 <nop,nop,[|tcp]> (encap)
08:23:36.163413 3ffe:3200::2.1047 > 3ffe:3200::1.ssh: . ack 1698 win 8320 <nop,nop,timestamp 19066396 11103770>
08:23:36.163446 3ffe:3200::2.1047 > 3ffe:3200::1.ssh: P 826:1922(1096) ack 1698 win 8320 <nop,nop,timestamp 19066399 11103770>
08:23:36.178682 192.168.8.12 > 192.168.8.11: 3ffe:3200::1.ssh > 3ffe:3200::2.1047: P 1698:2810(1112) ack 1922 win 8768 <nop,nop,[|tcp]> (encap)
08:23:36.182715 3ffe:3200::2.1047 > 3ffe:3200::1.ssh: P 1922:3018(1096) ack 2810 win 11120 <nop,nop,timestamp 19066432 11103791>
08:23:36.188978 192.168.8.12 > 192.168.8.11: 3ffe:3200::1.ssh > 3ffe:3200::2.1047: P 2810:3922(1112) ack 3018 win 10960 <nop,nop,[|tcp]> (encap)
08:23:36.234615 3ffe:3200::2.1047 > 3ffe:3200::1.ssh: . ack 3922 win 13344 <nop,nop,timestamp 19066491 11103802>

总结
vmware不仅仅作为一个模拟机器,它所提供的网络环境也是一个让人称道的真实网络,配合多种网络工具,我们对你所想象的网络的将更加容易的实现。

参考资料

http://www.vmware.com/
http://www.zebra.org/
http://www.ipv6.net.edu.cn/
LDP的IPv6-Linux-Howto
developerWorks Linux文章《在 Linux 上构建网络路由器》

关于作者
forrestrun, 从事过网络教学工作并参与过多项大型网络工程,目前为国内某著名网站系统工程师和架构师,一直关注tcp/ip技术、linux以及cisco网络技术。您可以通过forrestrun@163.com和他联系。