Mac OS X中的虚拟网络接口

57

我知道在Windows中可以创建虚拟网络接口(参见这里),在Linux中使用ip-aliases也很容易实现,但是在Mac OS X中有类似的东西吗?我一直在寻找环回适配器、虚拟接口,但没有找到好的解决方案。

你可以在网络面板中创建一个基于现有接口的新接口,但它不会像真正的完全功能接口一样运作(如果原始接口不活动,则派生接口也不活动)。

在完全断开连接的情况下,需要这种情况。即使如此,在VMWare安装中运行服务器时也有必要拥有网络能力。那些虚拟机可以通过其IP地址访问,但无法通过其DNS名称访问,即使我在其中一个虚拟机上运行DNS服务器。通过配置一个接口来使用虚拟DNS服务器,我想我可以测试一些DNS场景。不幸的是,如果它们都不活动,就没有任何接口能够解析DNS名称...


在你的同一主题上,或多或少 http://compileyouidontevenknowyou.blogspot.com/2009/03/virtual-networking-with-virtualbox-on.html - Dan Rosenstark
12个回答

66

环回适配器始终处于启用状态。

ifconfig lo0 alias 172.16.123.1 将向环回适配器添加别名IP 172.16.123.1

ifconfig lo0 -alias 172.16.123.1 将其删除


1
这样创建别名是正确的,但据我所知,您不能定义与环回适配器链接的DNS服务器,因此在我的上述情况中它将无法工作。 - Hans Doggen
对我来说,这是最好的解决方案。这样我就可以从主机到虚拟机进行ping测试,反之亦然。 - Richard Octovianus
也许我的评论有点晚了,但请注意,可以在 任何 接口上创建别名。 - Greg A. Woods

30

针对以下问题进行回复:

你可以在网络面板中基于现有接口创建新的接口,但它不会像真正完全功能的接口那样运作(如果原始接口未激活,则派生接口也不会激活)。

可以按照psv141的建议,使用Tun/Tap设备并操作/Library/Preferences/SystemConfiguration/preferences.plist文件来添加基于tun或tap接口的NetworkService。Mac OS X不允许创建基于虚拟网络接口的NetworkService,但可以通过直接操作preferences.plist文件手动添加NetworkService。基本上,您将在Xcode中打开preferences.plist文件(或直接编辑XML,但是使用Xcode更加安全),并从现有以太网接口复制配置。创建新的NetworkService的位置在“NetworkServices”下,如果Mac具有以太网设备,则NetworkService配置文件也将在此属性条目下。Ethernet条目可以几乎逐字地复制,您实际更改的仅有以下字段:

  • UUID
  • UserDefinedName
  • IPv4配置,并将接口设置为您的tun或tap设备(即tun0或tap0)。
  • 如有需要,DNS服务器。

然后,您还需要操作特定的位置(请记住,Mac OS X可以根据您的“位置”配置所有网络接口)。可以在PropertyList的根目录中获取默认位置UUID,方法是查找键“CurrentSet”。确定需要哪个位置(或集)后,在Set属性下展开,并使用新NetworkService的UUID添加Global/IPv4/ServiceOrder条目。还需要在Set属性下扩展Service属性,并将UUID作为字典添加到此处,其中一个String条目的键为__LINK__,值为UUID(以其他接口为例)。

修改preferences.plist文件后,只需重新启动,NetworkService就会在SystemPreferences->Network下可用。请注意,我们模拟了一个以太网设备,因此Mac OS X网络层将指出“电缆已断开”,并且不会让您通过GUI激活接口。但是,由于底层设备是tun/tap设备并且具有IP地址,因此接口将变为活动状态,并且适当的路由将在BSD级别添加。

此操作用于进行特殊路由操作。

如果你已经完成上述步骤却仍然遇到问题,则需要通过打开/dev/下的某个设备来创建tun/tap设备。您可以使用任何程序执行此操作,但我自己更喜欢老式的C程序:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
   int fd = open("/dev/tun0", O_RDONLY);
   if (fd < 0)
   {
      printf("Failed to open tun/tap device. Are you root? Are the drivers installed?\n");
      return -1;
   }
   while (1)
   {
      sleep(100000);
   }
   return 0;
}

这个解决方案能让你打开“互联网共享”功能,将tap接口桥接到以太网或机场接口吗? - Sukima
2
我已经测试过了,是的,它可以。我能够使用这种方法通过我的WiFi共享我的OpenVPN tun0设备(来自我的以太网连接)。 - thenickdude
注意:我尝试将其应用于vmnet(VMware虚拟网络适配器),但无法使用IP激活它。(对于使用tun/tap设备的情况,本解决方案确实有效) - TCB13
有没有解决“电缆已拔出”的问题的方法?我按照说明操作,一切都很好,但是由于“电缆已拔出”,OS X 认为主机处于离线状态,尝试在浏览器中导航到任何站点时都会告诉我没有互联网连接。 - Dan Ramos
嗨,感谢您的回复。我正在 MacOS 12 Monterey 中测试您的方法,但是 open("/dev/tun0") 总是返回 false。我认为 tuntap(使用 brew install --cask tuntap 进行安装)在某个地方出了问题。有没有办法在 MacOS 12 中使用 tuntap? - Lanistor

14

关于@bmasterswizzle精彩回答,更具体地说,是回答了@DanRamos有关如何强制新接口链接状态为“up”的问题。我使用这个脚本,它的起源我无法回忆起来,但与@bmasterswizzle的答案中的“蒙娜丽莎”完美协同工作……

#!/bin/zsh

[[ "$UID" -ne "0" ]] && echo "You must be root. Goodbye..." && exit 1
echo "starting"
exec 4<>/dev/tap0
ifconfig tap0 10.10.10.1 10.10.10.255
ifconfig tap0 up
ping -c1 10.10.10.1
echo "ending"
export PS1="tap interface>"
dd of=/dev/null <&4 & # continuously reads from buffer and dumps to null

我不是很确定我理解结尾处的提示更改,或者...

dd of=/dev/null <&4 & # 持续从缓冲区读取并转储到 null

但无论怎样,它都有效。链接指示灯:绿色✅。喜欢它

输入图像描述


你如何通过脚本销毁tap适配器? - Juuso Ohtonen
如果你想进行Python实现,你可能想要使用https://dev59.com/l2nWa4cB1Zd3GeqP5_eJ#15139727作为基础。 - Juuso Ohtonen
6
出现以下错误:line 5: /dev/tap0: Operation not permitted。 - Jay
还在使用 MacOS 12 Monterey 吗?我测试了一下,失败了。 - Lanistor
您需要Tunnelblick以及以下信息才能使用Tunnelblick的TAP设备驱动程序:https://groups.google.com/g/tunnelblick-discuss/c/v5wnQCRZ8HY/m/Q8nhFBx1BgAJ安装Tunnelblick后,您可以在终端(或脚本)中使用以下命令加载tap kext:/Applications/Tunnelblick.app/Contents/Resources/openvpnstart loadKexts 2 - Tobias Hochgürtel

10

还有一些人似乎暗示了这一点,但以下演示了如何使用ifconfig创建一个虚拟局域网并测试基于OS X 10.9.5上的虚拟接口的DNS(使用minidns):

$ sw_vers -productVersion
10.9.5
$ sudo ifconfig vlan169 create && echo vlan169 created
vlan169 created
$ sudo ifconfig vlan169 inet 169.254.169.254 netmask 255.255.255.255 && echo vlan169 configured
vlan169 configured
$ sudo ./minidns.py 169.254.169.254 &
[1] 35125
$ miniDNS :: * 60 IN A 169.254.169.254


$ dig @169.254.169.254 +short test.host
Request: test.host. -> 169.254.169.254
Request: test.host. -> 169.254.169.254
169.254.169.254
$ sudo kill 35125
$ 
[1]+  Exit 143                sudo ./minidns.py 169.254.169.254
$ sudo ifconfig vlan169 destroy && echo vlan169 destroyed
vlan169 destroyed

6

可以使用TUN/TAP设备。 http://tuntaposx.sourceforge.net/

(注:TUN/TAP是一种虚拟网络设备,可用于在计算机之间传输数据包。链接提供了相关信息。)

用户yar通过一篇博客文章提出了类似的建议。我看过它,但由于时间不足和我不再需要,所以没有测试它。尽管如此,还是谢谢。 - Hans Doggen

2
如果你在开发环境中,想要访问已经运行在本地主机上的一些服务。在Docker for Mac中,你有另一个选项,使用docker.for.mac.localhost代替docker容器中的localhost。 从Docker Community Edition 17.12.0-ce-mac46 2018-01-09开始,应该使用docker.for.mac.host.internal代替docker.for.mac.localhost。 这允许你从Docker容器内部连接到运行在Mac上的服务。请参考下面的链接: 了解docker.for.mac.localhost的行为 发布说明

1
非常感谢你! - DragonBobZ

1

打开网络偏好设置。

在网络适配器列表底部,点击+图标

选择您要arp的现有接口(例如以太网1),并为新端口指定您想要的服务名称(例如以太网1.1),然后按创建。

现在您在GUI中拥有了新的虚拟接口,并且可以以正常方式管理IP地址等。

ifconfig -a将确认您在接口上拥有多个IP,这些IP在重新启动时仍将存在。

这是一台Mac。不要与它对抗,用简单的方法解决问题。


4
如原问题所述,这并不能实现虚拟接口与物理接口隔离的期望效果。你所描述的命令仅仅是将同一物理接口与第二个IP配置别名。 - bleater

1
你说的意思是什么?
“但它不会作为一个真正完全功能的接口(如果原始接口处于非活动状态,则派生接口也处于非活动状态”。”

?

我可以创建一个新的接口,基于已经存在的接口,然后禁用现有的接口,新的接口仍然可以工作。但是创建第二个接口并不会创建一个真正的接口(当您使用ifconfig检查时),它只会为已经存在的接口分配第二个IP地址(但是,这个IP地址可以是DHCP,而第一个IP地址可以是硬编码的)。

所以,我是否正确理解您的意思,您想创建一个不绑定到任何真实接口的接口?那么这个接口将如何使用?例如,如果您断开所有WLAN并拔掉所有网络电缆,如果您向该接口发送流量,它会将流量发送到哪里?也许您的问题有点不清楚,如果您重新表述一下,明确您实际上想要使用这个“虚拟接口”做什么,那么这可能会很有帮助。

根据您在问题中提到的“别名IP”,这意味着一个别名接口。但是,别名接口总是绑定到一个真实接口上。不同之处在于,在Linux中,这样的接口确实是一个接口(例如,eth0的别名接口可以是eth1),而在Mac上,则不会创建任何真实接口,而是创建了一个虚拟接口,可以独立配置和使用,但它仍然是同一个物理接口,因此不会生成新的命名接口(您只有两个接口,实际上都是en0,但两者都可以独立启用/禁用和配置)。


0

我已经采用运行PFSense,一个基于BSD的路由器/防火墙来实现这个目标...

为什么?因为OS X Server没有静态IP就会变得非常糟糕...

所以在与它搏斗了几天后,我决定使用Parallels...

会让你知道进展如何...


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接