在VirtualBox中,我如何设置只能访问互联网的主机模式虚拟机?

在使用VirtualBox设置虚拟机时,我经常希望具备以下特性: - 虚拟机具有静态IP - 主机可以无需端口转发直接访问虚拟机 - 虚拟机可以访问互联网 - 我可以将笔记本电脑从一个网络移动到另一个网络(例如从家里到办公室或咖啡店),而无需担心保护或重新配置虚拟机的问题。
虚拟盒子的任何网络连接方法都不能单独满足这些要求: - NAT:如果您想从主机连接到虚拟机,需要进行端口转发。 - 仅主机:除非主机是路由器,否则虚拟机无法访问互联网。 - 桥接:暴露虚拟机给网络,不可移植。
7个回答

我可以通过在虚拟机上设置两个适配器来获得我想要的设置。
VirtualBox 4.2.12 Ubuntu 12.04 客户机
在 VirtualBox > 首选项 > 网络 中,设置一个仅主机网络。
我的称为 vboxnet0,手动配置如下: IP地址:192.168.56.1 子网掩码:255.255.255.0 无 DHCP

VirtualBox network configuration VirtualBox network configuration

然后,在虚拟机的网络设置中,设置两个适配器:
适配器1 仅主机,vboxnet0
适配器2 NAT
启动虚拟机,并通过VirtualBox提供的控制台登录。
运行以下命令查看您的适配器:
ls /sys/class/net

在我的情况下,适配器被命名为eth1和eth2(还有lo,即环回接口)。
然后,编辑您的网络配置。
sudoedit /etc/network/interfaces


# The loopback network interface
auto lo
iface lo inet loopback

# Host-only interface
auto eth1
iface eth1 inet static
        address         192.168.56.20
        netmask         255.255.255.0
        network         192.168.56.0
        broadcast       192.168.56.255

# NAT interface
auto eth2
iface eth2 inet dhcp

请注意,eth1 没有指定默认网关。 eth2 将从 DHCP 获取默认网关。

2018年3月更新

请参考此答案,由@Hugo14453提供的适用于Ubuntu 17.10及更高版本的更新版本。


现在要从您的主机访问客户端,您是否需要在主机机器的/etc/hosts中添加一个路由和名称?您的主机没有连接到192.168.56.0网络吗? - Mojo
不!VirtualBox为您在主机上创建了一个网络接口。(算了。) - Mojo
1更新:VirtualBox 4.3引入了一个NAT服务,看起来可能会消除对两个接口的需求。6.4. 网络地址转换服务 - Christian Long
4这对我帮助很大,我在开发中使用Virtualbox,当我在家的时候,一切都正常工作,因为我已经按照自己的喜好设置了网络。但是当我切换到其他网络(家庭、公司等)时,噩梦就开始了。我不得不更改网站的URL,删除一些系统文件,重启不知道多少次,等等。这个解决方案不关心你当前所连接的网络,这也是我喜欢它的原因...只需将电脑插入任何网络,专注于工作即可。 - Nabil Kadimi
对我来说,我不需要网络和广播。有了它,它就无法正常工作,我不知道为什么。 - vee
1谢谢。不为主机接口定义网关地址解决了我的问题。 - Florian
2太好了。/etc/network/interfaces配置是关键,谢谢!!! - Byron Whitlock
我没有一个名为/etc/network的文件夹。 - Joost Döbken
1请注意,eth1没有指定默认网关。eth2将从dhcp获取一个默认网关。 - Pere Pages
谢谢,它起作用了,但我想知道为什么VirtualBox只能使用这个IP范围"192.168.56.x",如果我尝试设置为"192.168.9.9",它会获得静态IP,但Apache停止响应来自主机的请求。而前一个IP正常工作。这让我绞尽脑汁很久了。我只是放弃了。 :( - Mohd Abdul Mujib
在这种情况下,主机将被分配什么IP地址?(用于更新客户防火墙规则) - dangel
警告:在VirtualBox工具中更改主机模式网络信息的位置在5.2.12版本(可能是5.2.x)中有些变化。 - mdpc

网络配置在Ubuntu 17.10.1中发生了变化。现在使用netplan配置。
我按照这个指南here进行操作。
作为Christian的答案的迁移,按照以下步骤进行:
在/etc/netplan目录下创建一个新的配置文件,用于保存主机适配器的配置。
例如:sudo nano /etc/netplan/02-netcfg.yaml
输入以下内容来配置静态IP地址为192.168.56.12,其中enp0s3是您的主机适配器的名称。
network:
    version: 2
    renderer: networkd
    ethernets:
        enp0s3:
            addresses:
                - 192.168.56.12/24
            dhcp4: no

然后运行以下两个命令:
sudo netplan generate
sudo netplan apply

NAT应该可以在没有配置的情况下工作,请运行ifconfig命令查看结果。
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.56.12  netmask 255.255.255.0  broadcast 192.168.56.255
        inet6 fe80::a00:27ff:fe06:6cdd  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:06:6c:dd  txqueuelen 1000  (Ethernet)
        RX packets 252  bytes 23076 (23.0 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 208  bytes 30015 (30.0 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.3.15  netmask 255.255.255.0  broadcast 10.0.3.255
        inet6 fe80::a00:27ff:fe4d:a6b8  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:4d:a6:b8  txqueuelen 1000  (Ethernet)
        RX packets 95  bytes 94894 (94.8 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 85  bytes 7436 (7.4 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

1谢谢!我在我的旧回答中添加了一个更新部分,并链接到这个新信息。 - Christian Long
1我已经按照你的解决方案进行了操作,但是在enp0s8上缺少网络地址转换(NAT)支持。我手动在netplan中为enp0s8添加了启用dhcp4的设置,最终成功使enp0s3和enp0s8都正常工作。希望这对其他人有所帮助。 - Dzmitry Prakapenka

我可以用Christian Long的解决方案来解决我的问题。 我添加了两个适配器:
适配器1 - NAT
适配器2 - 仅主机,vboxnet0
唯一的区别在于虚拟机的接口文件:
sudoedit /etc/network/interfaces

# The loopback network interface
auto lo
iface lo inet loopback
# NAT
auto eth0
iface eth0 inet dhcp
# Host only
auto eth1
iface eth1 inet dhcp

在VirtualBox网络配置中,我保留了DHCP的勾选。
虚拟机重新启动后,一切正常运行。

这对我来说是可行的,但我希望虚拟机能够拥有静态IP地址。一旦我这样做,互联网就停止工作了。如果我将两者都设置为使用DHCP,那么一切都正常。我该如何让主机模式接口获得静态IP地址呢? - Umar Farooq Khawaja
只有一个有效。谢谢。+1 - Jorge Campos

有另一种简单的方法,我们不需要创建一个新的NAT适配器。
在主机上,请添加以下iptables规则。这将通过主机将数据包转发到互联网:
sudo iptables -A FORWARD -o eth0 -i vboxnet0 -s 192.168.56.0/24 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A POSTROUTING -t nat -j MASQUERADE
您还需要通过以下命令在主机上启用IP转发:
sudo sysctl -w net.ipv4.ip_forward=1

1这只适用于Linux主机。 - Derek Mahar
我们需要运行"dnsmasq"服务。在链接https://unix.stackexchange.com/a/384187/61742中,我们有关于@Danatela所建议的完整信息。谢谢! - Eduardo Lucio
1@EduardoLucio 请给予Long Bui相应的功劳。我只是编辑了这篇帖子,使其更易读。 - Danatela
@Long Bui 谢谢你的贡献!加油!加油!加油!加油!加油!=D - Eduardo Lucio
@DerekMahar 同样地,在Windows系统中,使用内置的Internet Connection Sharing (ICS)应该是可以的,甚至可能还可以使用IP转发功能:https://serverfault.com/questions/929081/how-can-i-enable-packet-forwarding-on-windows。 - YumeYao

我刚刚添加了2个适配器:
适配器1 仅主机,vboxnet0
适配器2 NAT
现在一切都很完美,我可以从主机访问虚拟机,并且虚拟机也能上网。

我在Android x86上尝试了这个解决方案,但它只使用一个适配器,我以为是第一个适配器,但实际上是随机的。它只使用NAT或Host-only适配器,而不是两者都使用,你有什么想法为什么会这样?与桥接适配器相比,NAT具有优势,因为它可以使用我在主机操作系统上配置的VPN连接。 - baptx

是的,我遇到过这个问题,真是太痛苦了!但是我通过在我的物理电脑上安装Squid Cache代理服务器解决了这个问题,这样,我的仅限主机内部访问的虚拟机就可以连接到互联网啦!
对于任何想要了解它如何工作的人,我制作了一个3分钟快速指南。点击这里

我也使用过这个解决方案。不幸的是,它只适用于使用HTTP协议的应用程序。对于像Android x86上的WhatsApp这样的应用程序,我们需要像Dante这样的SOCKS代理,但是我无法再让这个解决方案工作了,使用redsocks:https://android.stackexchange.com/questions/221389/how-to-send-all-internet-traffic-to-a-socks5-proxy-server-in-local-network/221448#221448 - baptx

在我的情况下,尽管我在VirtualBox的仅主机网络设置中设置了IP 192.168.250.1,但我无法在vboxnet0上看到它(例如使用"ip addr"命令)。直到我创建了文件/etc/netplan/02-vbox.yaml,其中包含以下内容。
network:
    version: 2
    renderer: networkd
    ethernets:
        vboxnet0:
            addresses:
                - 192.168.250.1/24
            dhcp4: no

并运行“netplan generate && netplan apply”