那么如何让这些Local Zone既不占用网络资源,又
可以访问外部网络呢?
尝试1:让Global Zone做路由
最先想到的是把Global Zone设置为路由,各Local Zone通过它访问外网。但结果不理想,该
路由对Local Zone根本不起效,在Local Zone中甚至无法ping通Global Zone的外部IP。
为此,我找来三台独立的机器进行实验,两台机器位于两个不同的子网段,第三台机器同时拥有两个网段的地址,并
设置为路由,不同子网内的机器通过它成功的进行了通信。
看来这一策略本身没有问题,但由于路由表只能在Global Zone中进行维护,我
为LocalZone添加路由的同时,给Global Zone的路由选择带来了复杂性,第一次尝试失败。
尝试2:让另一台机器充当路由
既然自己做路由有问题,我把目光转向了另一台机器,给它添加一个子网地址,并将其配成路由,Local
Zone终于可以ping通Global Zone的外部IP地址了,另一台机器的外部IP地址也
可以ping通,但是发往外网的报文却有去无回。
通过跟踪,发现原因在于自己配置的路由使用的是子网地址(也就是常说的非法地址),无法得到公网内路由的认同,因
而并没有加入其路由表中,导致报文返回的通路被截断了。
尝试3:路由 + NAT
如何让不合法的地址也能得到承认呢?IP伪装无疑是第一选择,通
过Ipfilter中的网络地址转换功能NAT,把不合法的地址变为公网认可的地址,这里也就是Global Zone的外部IP。
在上例的基础上(即让另一台机器充当路由,进行转发),启动本机的Ipfilter服务,并添加NAT规则,终
于我的Local Zone通过路由和NAT的双重合作,可以自由的访问外网了。
具体的步骤如下:
步骤1. 为机器B设置子网环境。
为机器B配置添加子网的地址,例:192.1.1.200
将机器B配置为路由,提供IP forwarding的功能。
# touch /etc/defaultrouter
# routeadm -e ipv4-forwarding
# routeadm -u
步骤2. 为本机增加缺省路由,该缺省路由是为local zone服务的,但由于路由表由global
zone统一管理,因此只能在global zone中进行添加。
# route add default 192.1.1.200
步骤3. 在本机启用Ipfilter服务的NAT功能,具体的设置方法在尝试4的步骤3中有详细的介绍。
如果设置完毕后还不能工作,可以适当的交换global zone中缺省路由的位置。
再设置一下DISPLAY,就可以在Local Zone中试试用mozilla上网了。
尝试4:路由 + NAT 的改良
但是为了访问外网,还要借用其他的机器,这看起来并不是一个完美的解决方案。后来,在Michael
Ditto的blog上找到了一片介绍如何在Global zone中使用NAT的文章,思路和上例类似,但Michael的方法更为巧妙,他采用了一个虚拟的路由,并将本机缺省路由的物理地址赋予该虚拟路由,为
Local Zone构建了一条通向外网路由的通路。
下面详细列出了改良后的实现方法。
步骤1. 设置子网环境。
参照图1中的例子,让Global Zone和Local
Zone构成了一个虚拟的子网(192.1.1.*)。
● 为Global Zone增加子网IP
在/etc/hosts中添加子网IP和hostname的映射关系:
192.1.1.100 globalzone
新建文件/etc/hostname.eri0:1, 并加入如下信息:
globalzone
● 设置各Local Zone的网络环境
# zonecfg -z zone1
...
zonecfg:zone1> add net
zonecfg:zone1:net> set
address=192.1.1.1/24 #各个zone的IP不同
zonecfg:zone1:net> set
physical=eri0
zonecfg:zone1:net> end
zonecfg:zone1> commit
zonecfg:zone1> exit
Local Zone安装完毕后,一定要先用Console的方式登陆,就
象安装了一台新的机器一样,进行初始化,之后Local Zone就可以正常使用了。
步骤2. 设置路由
Michael Ditto提供的方法非常简单,添加一个子网段可识别的虚拟路由,该路由的逻辑IP(
192.1.1.254)位于子网段中,而它的物理地址则直接使用外网路由器的物理地址,一个小小的技巧帮我省去了一台机器。这里我写了一个脚本来实现这一功能,把脚本放到/etc/rc2.d/下,每
次启动就可自动执行。
在/etc/rc2.d/下新建文件S99routeForZone,文件内容如下:
#!/usr/bin/bash
#增加的虚拟路由的IP地址为192.1.1.254
VIRTUAL_ROUTE=192.1.1.254
#找到实际使用的外部路由IP
DEFAULT_ROUTE=`netstat -rn|grep default |grep -v $VIRTUAL_ROUTE |awk 'NR==1 {printf $2 }'`
#通过arp获取外部路由的物理地址
ARP_ADDRESS=`arp $DEFAULT_ROUTE|awk '{printf $4 }'`
#将外部路由的物理地址赋予虚拟路由( 192.1.1.254)
arp -s
$VIRTUAL_ROUTE $ARP_ADDRESS
#将虚拟路由加入到全局的路由表中
route add
default $VIRTUAL_ROUTE
执行后,可
以到Local Zone中确认一下自己的路由信息:
#zlogin zone1
#netstat -rn
Routing
Table: IPv4
Destination Gateway
Flags Ref Use Interface
-------------------- -------------------- -------- ------- -------- ------------
192.1.1.0
192.1.1.1
U 1
4 eri0:1
224.0.0.0
192.1.1.1
U 1
0 eri0:1
default
192.1.1.254
UG 1 5
127.0.0.1
127.0.0.1
UH 5 80
lo0:1
#arp 192.1.1.254
需要说明的是Global Zone和Local Zone的路由表是共享的,而且只有在Global
Zone中才有增删的权限。
步骤3. 启动ipfilter服务
ipfilter是Solaris10自带的模块,不需要额外的安装。在Solaris10中,所
有的服务统一由SMF进行管理,ipfilter也不例外。
首先检查一下ipfilter服务和它所依赖的pfil服务是否已经正常启动。
# svcs -a | grep pfil
disabled 12:03:43 svc:/network/ipfilter:default
online Aug_16 svc:/network/pfil:default
online Aug_16 svc:/system/rmtmpfiles:default
从上面的输出可以看到ipfilter服务缺省并不启动的。
在root权限下启动ipfilter服务:
# svcadm enable
svc:/network/ipfilter:default
不过启动并不成功,始终显示为maintenance状态。仔细观察log文件后,才
发现是因为pfil模块缺省并未加载到网络设备中,导致了ipfilter服务的启动异常。
修改pfil的配置文件"/etc/ipf/pfil.ap",把你需要进行过滤的网口打开,然后重启机器,p
fil模块被成功加载,pfil服务和ipfilter服务也都正常启动了。
# svcs -a | grep pfil
online 8月_09 svc:/system/rmtmpfiles:default
online 13:36:55 svc:/network/pfil:default
online 14:06:26 svc:/network/ipfilter:default
提示:
-
通过SMF启动和关闭ipfilter是永久有效的,即使机器重启也会保留。
-
可以通过ifconfig -a modlist指令观察各网口所加载的模块。
-
可以等下列步骤全部完成后,再重启机器。
步骤4. 配置NAT,将子网的IP转换为公网IP
对于图1所示的例子,在
"/etc/ipf/ipnat.conf"文件中加入如下的网络地址转换的规则:
map eri0 192.1.1.0/24 -> 0/32
令新设置的NAT规则生效。
# ipnat -CF -f /etc/ipf/ipnat.conf
ipnat -l可以观察当前的NAT规则,也可以用ipmon -t -o N实时观测网络地址的转换情况。
小结
ipfilter的NAT功能加上虚拟路由为Local Zone构建了一条联通外部的网络通道:
- 虚拟路由成为各Local Zone和外部通信的可用路由;
- 从Local Zone发出的包经过ipfilter时,NAT根据规则将包头中的子网IP转换为外部可识别的共网IP;
- 转换的同时,NAT向它的内部 NAT 表发送此地址,这样当包从公网返回时,就能够把地址映射回原先的内网 IP 地址。
- 可以通过snoop和ipmon观察这一通讯的过程。
用Michael Ditto的话说,方法4玩了一个小小的手段,伪造了一个虚拟路由,并赋予它真正路由的mac地址,0
但是当你无法获取缺省路由的mac 地址时,该方法就无法奏效了,这时我们不得不借助另一台机器,也就是文中提到的尝试三,利用另一台本地的机器提供路由转发的功能,加上ipfilter的NAT进行ip伪装,L
ocal Zone也可以访问外网了。