需求:

  1. 因为学习需要,需要在vmware下coding,不免就需要查资料等,需要访问外网,但不想在虚拟机上再安装一个clash,想直接利用windows下clash的allow lan功能来共享网络。
  2. 虚拟机上ip最好是静态的,便于与开发板进行通信。
  3. 由于很多内容在windows下完成更便捷,也需要完成wsl访问外网的配置。

VMware三种网络模式

分为桥接,NAT模式,Host-Only模式三种模式,(很多内容参考这篇文章:VMware的三种网络模式,),一般vmware会虚拟出 vmnet0,vmnet1,vmnet8三个虚拟交换机,后两个会生成两个虚拟网卡,这两个虚拟网卡通常可以在windows下 更改适配器选项 中看到。(个人:主机有多少不同的网卡,就可以与多少不同的局域网进行通信,不管是物理网卡还是虚拟网卡)

桥接模式

原理:桥接模式是最简单的一种,桥接模式就是将主机网卡与虚拟机虚拟的网卡利用虚拟网桥进行通信。主机网卡也起到了交换机的作用,主机网卡,虚拟交换机下的那四个交换机都处于同一个网域内,掩码,网关应该一致,各机器之间也可以相互ping通。

配置:在vmware中将网络配置为桥接模式后,各虚拟机可以访问互联网,想通过windows clash访问网络的话可以配置虚拟机网络代理,将其配置成主机ip+clash中设的端口号

这样就可以访问外网。但如果要使用静态ip的话,有两个比较大的问题,第一,不同wifi下,ip的网络id部分不一定是一样的,如果在把虚拟机配置成了 192.168.1.1/24下的地址,而又恰好连上了地址为 192.168.2.1/24的网络,虚拟机就无法上网,如果没连一个wifi就改一次ip就太过麻烦了。第二,就算配置的ip刚好和网络匹配,配置的静态ip也可能和网络中的其他设配ip重合,导致无法上网。此方案不太可行。

NAT模式

原理:NAT模式下,左框图和右框图是两个不同的网络,如果没有下面那个vmware network adapter,主机和虚拟机之间是无法相互访问的。右框图近似是一个完整的局域网,要通信时,通过NAT地址转换,映射ip和端口,通过主机网卡的ip与外界通信。(桥接需要你连接的路由器给你的虚拟机分配真实的ip,NAT模式不用,它通过路由器分配给你主机的ip访问网络,这中间需要NAT地址转换)。虚拟机如何与主机通信呢,vmware为主机虚拟了一个vmnet8网卡,该网卡地址是与右框图下网络地址是匹配的,因此,主机是可以通过改地址访问虚拟机网络,虚拟机也可以通过该地址访问主机。多次试验后,发现vmnet8网卡地址似乎是不变的,这也有利于后面配置静态ip。

配置:将虚拟机配置为nat模式后,虚拟机可以通过虚拟交换机——网卡进行上网,但这无法访问外网,可以将虚拟机的代理地址配置为 vmnet8地址+clash中的端口号。vmnet8地址通常不会变,一次配置就可以长久使用。

经配置后,虚拟机可以上网,也可以访问外网,要使用静态ip的话,可以按照vmnet8的格式随意配置,网关地址的话,我是将使用dhcp后找到的,是192.168.228.2,也不会随意改变。这样配置后,没有使用真实存在的ip,也不用担心和别人的ip冲突。

Ubuntu配置后不能生效,需要重启网络或者重启Ubuntu

1
/etc/init.d/network-manager restart

Host-Only模式

原理:Host-Only模式其实就是NAT模式去除了虚拟NAT设备,然后使用VMware Network Adapter VMnet1虚拟网卡连接VMnet1虚拟交换机来与虚拟机通信的。由于右框图设备位于一个局域网内,主机vmnet1也处于那个局域网,主机与右框图中的设备可以通信。但右框图设备没有虚拟NAT,不能把自己的ip转化成一个真实有效的ip,无法直接通过网卡访问互联网。但既然主机和虚拟机仍然可以通信,那么虚拟机也可以通过主机的代理软件访问互联网。

同样是配置虚拟的代理,为此处ip,port,配置过程完全一致。

与NAT模式相比缺陷是,如果哪天主机没使用代理软件了,hostonly就没法上网了,而NAT模式只需要关闭代理就可以上网。

wsl下网络配置

WSL2 默认采用了一个 NAT 网络,这对于大多数情况而言都是没有问题的,但是如果想要把 WSL 中的服务直接暴露出来,就不得不考虑做端口转发等问题。以及如果要使用 IPv6,自带的 NAT 方案也不能满足。如果想让wsl对外暴露ip,可以参考这篇文章:wsl2 通过桥接网络实现被外部局域网主机直接访问

wsl和vmware通过代理软件访问外网主要步骤差不多,区别是vmware是通过图形界面配置,wsl通过命令行配置,具体内容可参考下文:WSL2配置代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#!/bin/sh
hostip=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }')
wslip=$(hostname -I | awk '{print $1}')
port=7890

PROXY_HTTP="http://${hostip}:${port}"

set_proxy(){
export http_proxy="${PROXY_HTTP}"
export HTTP_PROXY="${PROXY_HTTP}"

export https_proxy="${PROXY_HTTP}"
export HTTPS_proxy="${PROXY_HTTP}"

export ALL_PROXY="${PROXY_SOCKS5}"
export all_proxy=${PROXY_SOCKS5}

git config --global http.https://github.com.proxy ${PROXY_HTTP}
git config --global https.https://github.com.proxy ${PROXY_HTTP}

echo "Proxy has been opened."
}

unset_proxy(){
unset http_proxy
unset HTTP_PROXY
unset https_proxy
unset HTTPS_PROXY
unset ALL_PROXY
unset all_proxy
git config --global --unset http.https://github.com.proxy
git config --global --unset https.https://github.com.proxy

echo "Proxy has been closed."
}

test_setting(){
echo "Host IP:" ${hostip}
echo "WSL IP:" ${wslip}
echo "Try to connect to Google..."
resp=$(curl -I -s --connect-timeout 5 -m 5 -w "%{http_code}" -o /dev/null www.google.com)
if [ ${resp} = 200 ]; then
echo "Proxy setup succeeded!"
else
echo "Proxy setup failed!"
fi
}

if [ "$1" = "set" ]
then
set_proxy

elif [ "$1" = "unset" ]
then
unset_proxy

elif [ "$1" = "test" ]
then
test_setting
else
echo "Unsupported arguments."
fi

可以在~/.bashrc中添加如下内容,并将其中的路径修改为上述脚本的路径:

1
alias proxy="source /path/to/proxy.sh"

然后输入如下命令:

1
source ~/.bashrc

那么可以直接在任何路径下使用如下命令:

  • proxy set:开启代理
  • proxy unset:关闭代理
  • proxy test:查看代理状态