前言

网上的教程参差不齐,有的还挺具有误导性的,于是打算在这里记录一下我的做法。

我的做法能够解决以下这些网上的教程存在的问题

  • 拨号上网的环境,无法使用主机代理。
  • 网络环境改变后(比如路由器分配的 ip 改变了),需要重新设置代理。
  • 如果主机没有连接网络,那虚拟机和主机没法通过网络通信(虽然此时代理也用不了)
  • 终端里敲命令太麻烦了。

这篇文章将会尽可能详细的描述操作过程,同时解释其中的原理以帮助读者理解,一些我认为读者没必要知道的内容将会省略。

预备知识

网络地址转换(NAT)

不需要深入理解,你只需要知道,路由器具有它的功能,你也可以把使用 NAT 的地方看成一个简单的路由器(即使是虚拟的)。

VMware 虚拟网

VMware 具有“虚拟网络”的功能,而我们可以利用此功能虚拟出一个“路由器”,我们只需要将主机和虚拟机连接在同一个“路由器”下,便可以实现双向通信,这就是虚拟机使用主机侧代理软件的核心思路。

虚拟网络编辑器

这一步主要起到验证作用,为的是知道 VMware 自动创建的 NAT 类型虚拟网是否存在,叫什么名字。一般而言只需要检查,并没有什么需要修改的内容。

VMware 自带了一个虚拟网络编辑器,我们可以在这里查看所有 VMware 所创建的虚拟网的信息。

p

打开之后点击一下“更改设置”来显示全部内容。
在这里我们注意到,VMware 默认已经为我们创建了一个 NAT 类型的虚拟网,其名称为 VMnet8(需要记一下这个名字)。
( VMware 默认都会创建一个 NAT 类型虚拟网,故此处不再赘述如何创建并配置一个 NAT 虚拟网)

p

我们可以将这个 NAT 类型的虚拟网看成一个虚拟的路由器,于是我们只需要同时将主机和虚拟机连接在这个“路由器”下面,就可以实现双向通信了,接下来我将陈述该怎么做。
(只要“将主机虚拟适配器连接到此网络”保持勾选状态,主机就已经连接到这个“路由器”了)

把虚拟机连接到“路由器”

这一步我们要做的事情是:将虚拟机连接到上述虚拟网。

首先,每台虚拟机都有一个“网络适配器”的选项。

p

这个选项可以在 顶栏的“虚拟机”/在虚拟机上右键 -> "设置" 找到

在这里,我们可以选择要将虚拟机连接到“虚拟网络编辑器”中的哪个网络。
我们将网络选择为之前记住的:VMnet8。

p

这样,就相当于把虚拟机连接在虚拟“路由器”的下面了。

配置代理

在这一步之前,我们已经将虚拟机和主机连接在了同一个“虚拟路由器”的下面,现在,我们只需要知道主机在该“虚拟路由器”下的 ip 地址和代理端口,便可以完成代理的设置。

主机的 ip 地址

我们可以打开主机的任务管理器,找到上面记住的 VMnet8 。

p

这个地址就是主机在这个“虚拟路由器”下的地址,我们需要将其记录下来。

代理端口

以代理软件“v2rayN”为例。

首先,我们需要打开“允许来自局域网的连接”来保证来自虚拟机的连接不会被主机拒绝。
(这里的图是旧版软件,新版的开关在“基础设置”里)

p

然后,我们可以在软件主界面的底部看到 SOCKS5 和 HTTP 代理端口:

旧版软件:

p

注意:我们需要的端口号只是后面的 1079 和 1080,前面的 127.0.0.1 是指向本机的网络地址,我们无法在虚拟机中使用它指向主机。我们需要将端口号以及其对应的协议(HTTP/SOCKS5)记录下来。

新版软件:

p

我们把“局域网”后面对应的协议(socks/http)和端口(1081/1082)记录下来就行啦。

在虚拟机中配置代理

此处以 Ubuntu 为例。
我们已经知道了主机在“虚拟路由器”下的地址以及代理软件的端口,现在我们只需要在虚拟机当中将代理信息设置为上方记录的 ip 地址与端口即可。

打开 Ubuntu 的设置,选择“网络”选择卡。

p

可以看到其下有一个“网络代理”设置。

点开,将代理模式调成手动,输入上方记录的 主机 ip 地址 和 代理软件端口(把协议也对应上)
(这里的图对应的是上面的旧版软件)

p

那么虚拟机的代理就配置完成了,我们可以尝试使用一下。

p

可以看到,主机代理软件的日志中出现了来自虚拟机的访问记录,这说明代理已经配置完成。

杂谈

Ubuntu 设置中的代理设置,其本质是添加环境变量 http_proxyhttps_proxyALL_PROXY 等。只有能够主动检测并读取这些环境变量的软件才能自动使用代理,比如 git 的 http 协议模式、wgetcurlpip等。某些软件包的代理可能需要额外进行手动配置,比如 git 的 ssh 模式和 git 协议模式。

虚拟机“网络适配器”的 NAT模式 默认也是指向 VMnet8 的,不过为了清晰起见,上方依旧使用“自定义”指向 VMnet8 。