环境搭建
VirtualBox虚拟机
-
主机虚拟网卡 创建两个虚拟网卡(
管理
/主机网络管理
/创建
),他们的网段不同,IP网络不互通- vboxnet0
- vboxnet1
-
虚拟机
-
Ubuntu001 挂
vboxnet0
网卡 -
Ubuntu002 挂
vboxnet1
网卡 -
Ubuntu003 同时挂
vboxnet0
和vboxnet1
网卡注意一个细节,挂载在不同网卡槽(VirtualBox提供四个插槽,分别是网卡1/2/3/4)会导致网卡设备名称变化。为了确认一个网卡设备和物理网卡的关联,可以通过MAC地址来确定。
- 在VirtualBox对应虚拟机的设置面板上,在 网络->对应网卡插槽->[高级]MAC地址 可以看到该网卡的MAC地址
- 对应ubuntu上目标设备的MAC的地址则可以通过
cat /sys/class/net/<divice>/address
找到
通过挂载仅主机网络类型的网卡,你无法访问互联网以获得一些更新,安装过程可能会出现无网络继续的选项,选它。
-
启动网卡设备
如何判断网卡设备启动正常呢?通常使用ip a
列出所有的网卡,如果能找到你的网卡便表示你的网卡设备已经成功安装。但是到这一步还不够,你必须为你的网卡绑定上设计网段的IP。你应该知道ifconfig
可以查看所有网卡的网络IP,你可能会遇到ubuntu启动后网卡自动未绑定IP的情况。这时候你可以通过以下两个方法来完成手动绑定(也可以指定IP,而不是使用DHCP服务分配的IP)。
临时分配IP
可以通过以下命令临时挂载/启动(系统重启后恢复):
# Ubuntu001, 注意这里的网卡设备名称应跟你的环境一致
sudo ifconfig enp0s8 192.168.56.2 netmask 255.255.255.0 up
# Ubuntu002, 注意这里的网卡设备名称应跟你的环境一致
sudo ifconfig enp0s9 192.168.57.2 netmask 255.255.255.0 up
# Ubuntu003, 注意这里的网卡设备名称应跟你的环境一致
sudo ifconfig enp0s8 192.168.56.3 netmask 255.255.255.0 up
sudo ifconfig enp0s9 192.168.57.3 netmask 255.255.255.0 up
持久化分配IP
或者通过在配置文件(/etc/netplan/50-cloud-init.yaml
)中写入以下配置(ubuntu18LTS以后使用netplan代替/etc/network/interfaces,可参考此文),这样启动时会自动挂载/启动网卡:
# ubuntu001
network:
version: 2
ethernets:
enp0s8:
dhcp4: no
addresses: [192.168.56.2/24]
# ubuntu002
network:
version: 2
ethernets:
enp0s9:
dhcp4: no
addresses: [192.168.57.2/24]
# ubuntu003
network:
version: 2
ethernets:
enp0s8:
dhcp4: no
addresses: [192.168.56.3/24]
enp0s9:
dhcp4: no
addresses: [192.168.57.3/24]
在本次实验课,建议通过第一种方式来实现,方便随时重启恢复网络环境。
至此完成了实验环境的搭建。你得到了:
- 两张网卡设备(vboxnet0、vboxnet1)
- 宿主机(Master)和三台虚拟主机(Ubuntu00{123}),分别挂载了两张网卡设备,并给他们分配了IP地址
这里实验得以继续的一个前提是,宿主机中创建的虚拟网卡设备,可以在虚拟机中同时使用——但挂载的设备名称不同。
实验一:本地互联
ubuntu001
-ubuntu003
和ubuntu002
-ubuntu003
是彼此能通的,但是ubuntu001-ubuntu002之间不通。
一种方式是让所有虚拟机均挂载同一张网卡,给ubuntu001多配置一个网卡+IP,这样ubuntu001-ubuntu002之间可以通过x.x.57.0/24网段互通。
或者通过宿主机来ipforward转发流量
ip forward
开启ip forward功能
# ubuntu003
## 方法一:修改配置文件
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
## 方法二:临时修改
sudo sysctl -w net.ipv4.ip_forward=1
## 查看配置生效
cat /proc/sys/net/ipv4/ip_forward
添加iptables规则(如果默认规则就是ACCEPT也可以不需要单独添加ACCEPT记录)
# ubuntu003
sudo iptables -A FORWARD -i enp0s8 -o enp0s9 -j ACCEPT
sudo iptables -A FORWARD -i enp0s9 -o enp0s8 -j ACCEPT
添加路由记录
# ubuntu001
## 增加从ubuntu001(192.168.56.2)本地到任意192.168.57.0/24网段的包经过x.x.56.3转发
sudo ip route add 192.168.57.0/24 via 192.168.56.3 dev enp0s8
# ubuntu002
## 增加从ubuntu002(192.168.57.2)本地到任意192.168.56.0/24网段的包经过x.x.57.3转发
sudo ip route add 192.168.56.0/24 via 192.168.57.3 dev enp0s9
完成配置,可以通过ping测试ubuntu001和ubuntu002之间是否通了。
实验二:外网连接
通过宿主机NAT上网
虚拟机目前可以互联,但是还无法连到外部Internet网络。如何实现?VirtualBox提供了本地NAT功能,通过管理->全局设定->网络面板增加NAT网络配置:
然后在ubuntu003中添加这个启用了NAT能力的网卡:
注意有两个类似的「连接方式」:网络地址转换(NAT)和NAT网络,他们的区别官方是这样介绍的,主要的区别就是只有NAT网络能修改NAT网络的网段和DHCP等配置。这里我们选择NAT网络。
重新启动ubuntu003,此时我们观察/sys/class/net/
会发现多了一个网卡设备,我们启用它并分配对应的IP:
# ubuntu003 /etc/netplan/50-cloud-init.yaml添加以下配置
network:
version: 2
ethernets:
enp0s3:
dhcp4: no
addresses: [10.0.2.3/24] # 跟VirtualBox的NAT网络配置一致
gateway4: 10.0.2.1 # VirtualBox配置的默认NAT网关为x.x.x.1(会配置一个默认网关路由, Flags=G)
nameservers:
addresses: [8.8.8.8, 8.8.4.4] # 为了访问外网域名, 需要配置DNS
配置生效后可以看到多了一个enp0s3
网卡,并且可以ping通外网域名。增加enp0s3
网卡配置后执行route -n
会发现多了两条路由:
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.2.1 0.0.0.0 UG 0 0 0 enp0s3
10.0.2.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s3
第二条是配置的addresses静态地址路由,所有访问10.0.2.0/24的请求命中此路由,直接转发到目标地址;
第一条则是gateway4网关路由,任意未匹配的目标IP地址都会发给此网关,所有外网地址都不在10.0.2.0/24网段,因此会经过10.0.2.1转发。
通过虚拟机NAT上网
在ubuntu003通过VirtualBox提供的NAT服务连上外网后,希望ubuntu001/ubuntu002这两个节点使用同样的NAT技术,通过ubuntu003来转发上外网。
首先在ubuntu003上配置NAT,让来自ubuntu001/002(192.168.0.0/16网段覆盖了两个机器的网段)的流量通过NAT转发。
# ubuntu003
# 配置源端为192.168.0.0/16的流量经过NAT转发到enp0s3网卡
sudo iptables -t nat -A POSTROUTING -o enp0s3 -s 192.168.0.0/16 -j MASQUERADE
其次是修改ubuntu001/002的路由表,让出外网的包能打到ubuntu003网关上。以ubuntu002节点为例,目前它的路由表为:
# route -n
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.56.0 192.168.57.3 255.255.255.0 UG 0 0 0 enp0s9
192.168.57.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s9
两条记录分别来自:
- 第一条,通过
sudo ip route add 192.168.56.0/24 via 192.168.57.3 dev enp0s9
命令手动添加的路由,它导致ubuntu002(192.168.57.2)->ubuntu001(192.168.56.2)
的流量通过192.168.57.3
进行转发。 - 第二条,通过
/etc/netplan/50-cloud-init.yaml
配置enp0s9的静态IP地址为192.168.57.2/24
后自动生成的一条路由,这使得我们可以通过192.168.57.2
直接访问ubuntu002。
现在目标是将所有指向外网的包都通过192.168.57.3
进行转发,故执行sudo ip route add 0.0.0.0/0 via 192.168.57.3 dev enp0s9
新增一条路由记录。发现此路由跟上述第一条路由重复,都是指向192.168.57.3,可以在配置文件直接配置网关,netplan启动时会自动新增一条默认路由指向192.168.57.3。
# ubuntu002
## sudo vim /etc/netplan/50-cloud-init.yaml
network:
version: 2
ethernets:
enp0s9:
dhcp4: no
addresses: [192.168.57.2/24]
gateway4: 192.168.57.3 # 指定此网卡的网关
nameservers:
addresses: [8.8.8.8, 8.8.4.4] # 为了访问外部域名, 顺便配置DNS
修改配置生效后,ubuntu002的完整路由表变成:
# ubuntu002
## route -n
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.57.3 0.0.0.0 UG 0 0 0 enp0s9
192.168.57.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s9
最终的拓扑关系如下图:
实验三:隧道网络搭建[beta]
ipip-fou隧道
以ipip隧道为例,先执行创建隧道:
# ubuntu001/ubuntu002
## 加载内核模块ipip
modprobe ipip
## 加载内核模块fou
modprobe fou
# ubnutu001(192.168.56.2)
## 本地开启监听接收指定端口的fou包
ip fou add port 5602 ipproto 4
## 创建一个隧道设备(name tun1 type ipip),指定其建连网络地址(local ... remote ...)
ip link add name tun1 type ipip local 192.168.56.2 remote 192.168.57.2 ttl 225 encap fou encap-sport auto encap-dport 5702
# 启动网卡
ip link set tun1 up
# ubnutu002(192.168.57.2)
## 本地开启监听接收指定端口的fou包
ip fou add port 5702 ipproto 4
## 创建一个隧道设备(type ipip)
ip link add name tun1 type ipip local 192.168.57.2 remote 192.168.56.2 ttl 225 encap fou encap-sport auto encap-dport 5602
# 启动网卡
ip link set tun1 up
创建的ipip隧道相当于一张虚拟网卡设备,需要给它配置IP/路由,流量便打到隧道上进行发送:
# ubuntu001
ip addr add 177.0.0.0/31 dev tun1
# ubuntu002
ip addr add 177.0.0.1/31 dev tun1
至此可以ubuntu001可以通过隧道设备(177.0.0.0 dev tun1)与ubuntu002上的隧道设备(177.0.0.1 dev tun1)通信。
下面抓包看看一个包的完整传播路径:
参考文章