前述
我們知道無論是VMware,Virtual Box還是HyperV 都支持 NAT/Bridge/Host-Only 三種上網方式。其中 NAT 是我最常用,最熟悉的。
需要說明的是,無論是NAT 還是 Bridge, 虛擬機與宿主機、虛擬機與虛擬機、虛擬機與外網、宿主機與外網之間都是通的!!!(不要相信CSDN某些人的博客,實踐出真知!)
下面就用qemu 模擬實現下 NAT與Bridge。無論哪種本質上都是在宿主機側的設置,因為虛擬機的IP網關設置不屬於必須操作!
注:建議看完NAT自己實現下host-only模式. host-only 虛擬機是不通外網的(提示,按照NAT的步驟,但不設置防火牆試試)
openwrt 虛擬機安裝方式
由於 openwrt 官方下載的鏡像並不是我們以為的 iso 的格式。因此特地記錄下
- 查看鏡像文件格式
➜ Wdir qemu-img info openwrt-19.07.4-x86-generic-combined-ext4.img
image: openwrt-19.07.4-x86-generic-combined-ext4.img
file format: raw
virtual size: 272 MiB (285736960 bytes)
disk size: 272 MiB
如上可以知道,鏡像是 raw 格式的,需要轉換為 qemu 能識別的 qcow2 格式。
- 轉換鏡像
➜ Wdir qemu-img convert -f raw -O qcow2 openwrt-19.07.4-x86-generic-combined-ext4.img openwrt-19.07.4-x86-generic-combined-ext4.qcow2
➜ Wdir ls -l |grep openwrt
-rw-r--r-- 1 nobody kvm 285736960 12月 3 16:00 openwrt-19.07.4-x86-generic-combined-ext4.img
-rw-r--r-- 1 nobody kvm 285736960 12月 3 16:00 openwrt-19.07.4-x86-generic-combined-ext4.qcow2
-rw-r--r-- 1 lester lester 8414308 9月 8 21:24 openwrt-19.07.4-x86-generic-combined-ext4.img.gz
➜ Wdir
如上我們的到了一個 qcow2 格式的鏡像文件,qemu 可以直接使用。如果你曾經安裝過 qemu 虛擬機,就會知道 qemu 下的虛擬機文件是qcow2 格式的。創建虛擬機步驟略。
NAT
NAT實現需要借助於防火牆,這里用iptables來做轉發與網絡地址轉換!
涉及到虛擬機網卡 vnet0(虛擬機起來后,host端生成的網卡,不是虛擬機內的網卡),網橋 br,宿主機網卡 enp1s0
原理
NAT 普遍被用在路由器中。一個路由設備通常由一個 WAN 口用於連接外網也就是光貓或其他路由設備,多個LAN 口用於連接其他上網的設備,一個由本地 LAN 口組成的網橋 br 用於 DHCP等。
通常本地設備獲取的地址都是 192.168.x.x 的IP地址,這些地址都是由運行在網橋上的 dhcp server來分配的。網橋上是一定要有地址的,通常是 192.168.x.1
WAN 口用於鏈接外網。所有 LAN 側報文(本地交互除外)都會經由 WAN 轉發到外網。
# 注: 虛線部分代表有網絡地址轉換
入棧: 外網數據 -> WAN ------> br 網橋 -> LAN
出棧: 外網數據 <- WAN <------ br 網橋 <- LAN
iptable與更詳細的設置參考
宿主機設置:
# 注: br 為手動創建的網橋。vnet0 為虛擬機在host 上生成的網卡,不是虛擬機內部的網卡
brctl addbr br # 創建網橋
brctl addif br vnet0 # 添加成員
ifconfig br up
報文轉發流程圖
# 出棧
虛擬機網卡(eth0)-> 虛擬機網卡(vnet0)->網橋(br)---- iptable forward -----宿主機網卡(enp1s0)->發出
# 入棧
虛擬機網卡(eth0)<- 虛擬機網卡(vnet0)<-網橋(br)---- iptable forward -----宿主機網卡(enp1s0)<-收到
如上,需要配置iptable的轉發,讓報文能夠從 br 轉到 enp1s0 上,這步很重要(host-only 可以跳過)。(需要 /proc/sys/net/ipv4/ip_forward 為 1)
# 1. 簡單粗暴的操作
iptables -F # 清空防火牆規則
iptables -P FORWARD ACCEPT # 接受所有轉發
# 2. 也可以這樣,定義精細的規則
iptables -A FORWARD -i br -o enp1s0 -j ACCEPT
iptables -A FORWARD -o br -i enp1s0 -j ACCEPT
另外要知道 NAT 發出的報文原地址是enp1s0 的地址,這就要求iptable也要做地址轉換(host-only 可以跳過)
iptable -t nat -A POSTROUTING -s 192.168.122.0/24 -j MASQUERADE
至此,NAT 設置完畢,設置地址ping測試就行了
# 宿主機
ifconfig br 192.168.122.1/24
# 虛擬機內
ifconfig eth0 192.168.122.10/24
ip route add default via 192.168.122.1 dev eth0
這時候在虛擬機 eth0 上測試 ping 8.8.8.8 是ok的
虛擬機:
宿主機:
Bridge
本文僅借助了 Linux 網橋設備實現了橋接功能,與 QEMU 的實現並不一樣!
實際上,qemu 是利用
來實現的橋接。借助 macvlan 來實現復用主機網卡。所以你會發現qemu在設置橋接模式時候並沒有出現新的網橋設備,反而多了一個名字為 macvtapX 的網卡,且這個網卡的 MAC 地址與虛擬機的 MAC 地址一樣!
宿主機報文轉發流程圖
# 出棧
網橋(br)-> 宿主機網卡(enp1s0)->發出
# 入棧
網橋(br)<- 宿主機網卡(enp1s0)<-收到
虛擬機報文轉發流程圖
思考為什么這時候不需要iptable做 forward 規則(因為vnet0,enp1s0 都是網橋子網卡,這時候相當於二層交換機的兩個端口,因此是互通的,不需要三層的iptable支持轉發)
# 出棧
虛擬機網卡(eth0)-> 虛擬機網卡(vnet0)->網橋(br)-> 宿主機網卡(enp1s0)->發出
# 入棧
虛擬機網卡(eth0)<- 虛擬機網卡(vnet0)<-網橋(br)<- 宿主機網卡(enp1s0)<-收到
宿主機設置:
brctl addbr br
brctl addif br enp1s0 # 添加網卡
brctl addif br vnet0 # 添加網卡
ifconfig br up
# 注意此時宿主機網卡不能配置地址,或者說配置地址也沒用,需要把地址配置到網橋br上
ifconfig br 192.168.100.125/24
ip route add default via 192.168.100.1 dev br
宿主機:
虛擬機:
然后在虛擬機做dhcp,或者手動配置(手動配置需要確保地址與宿主機網卡地址在同一網段,比如地址設為 192.168.100.10/24)
現在在虛擬機ping 網關,主機或者8.8.8.8 都是通的