Mac OS X中的虚拟网络接口

时间:2008-09-17 20:41:12

标签: macos networking

我知道您可以在Windows中创建虚拟网络接口(请参阅here),在Linux中,使用ip-aliases也很容易,但Mac OS X是否存在类似的情况?我一直在寻找环回适配器,虚拟接口,但找不到一个好的解决方案。

您可以在网络面板中基于现有界面创建新界面,但它不会充当真正的全功能界面(如果原始界面处于非活动状态,则派生的界面也处于非活动状态)。

在完全断开连接的情况下工作时需要此方案。即便如此,在VMWare安装中运行服务器时具有网络功能也是有意义的。这些虚拟机可以通过其IP地址访问,但不能通过其DNS名称访问,即使我在其中一个虚拟机中运行DNS服务器也是如此。通过配置接口以使用虚拟DNS服务器,我想我可以测试一些DNS场景。不幸的是,如果DNS名称都不是非活动的,那么没有接口可以解析DNS名称......

12 个答案:

答案 0 :(得分:53)

环回适配器始终处于运行状态。

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

ifconfig lo0 -alias 172.16.123.1 将其删除

答案 1 :(得分:22)

特别回复:

  

您可以在网络面板中基于现有界面创建新界面,但它不会充当真正的全功能界面(如果原始界面处于非活动状态,则派生的界面也处于非活动状态)。

这可以使用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配置文件也将位于此属性条目下。以太网条目可以逐字复制,您实际要改变的唯一字段是:

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

然后您还可以操作您想要此NetworkService的特定位置(请记住,Mac OS X可以根据您的“位置”配置所有网络接口)。可以在PropertyList的根中获取默认位置UUID作为键“CurrentSet”。确定所需的位置(或集合)后,展开Set属性,并使用新NetworkService的UUID在Global / IPv4 / ServiceOrder下添加条目。同样在Set属性下,您需要展开Service属性并在此处将UUID作为字典添加,其中一个字符串条目带有键__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;
}

答案 2 :(得分:8)

关于@bmasterswizzle的{​​{3}} - 更具体地说 - 关于如何强制新界面的链接状态为“up”的@DanRamos'问题。我使用此脚本,我不记得的,但其工作非常有效(与BRILLIANT answer协调)......

#!/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 & # continuously reads from buffer and dumps to null

但无论如何。有用。链接灯:绿色✅。 喜欢它

enter image description here

答案 3 :(得分:5)

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

答案 4 :(得分:5)

其他一些人似乎暗示了这一点,但以下演示了在OS X 10.9.5上使用ifconfig在虚拟接口上创建vlan并测试DNS(使用minidns):

#include <iomanip>
#include <iostream>
#include <string>

std::string::size_type find(const std::string& s1,
                            const std::string& s2)
    // return the position of s2 within s1,
    // else npos if it is not present.
{
    using size_type = std::string::size_type;
    size_type curPos = 0;
    size_type lim    = s1.size();
    size_type innerLim = s2.size();

    for (; curPos<lim; ++curPos) { // loop through s1
        if (lim < curPos+innerLim) {
            break; // not enough space left
        }
        size_type innerPos = 0;
        for(; innerPos < innerLim // loop through s2, while matching
                && curPos + innerPos < lim
                && s1[innerPos+curPos] == s2[innerPos];
                ++innerPos) ; // do nothing in the loop
        if (innerPos == innerLim) { // matched the whole loop
            return curPos;
        }
    }
    return std::string::npos; // never matched
}

bool contains(const std::string& s1,
              const std::string& s2)
{
    return find(s1, s2)!=std::string::npos;
}


int main()
{
    std::cout
        << std::boolalpha
        << contains("abc", "")      << '\n' // true
        << contains("abc", "abc")   << '\n' // true
        << contains("abc", "bc")    << '\n' // true
        << contains("abc", "abcd")  << '\n' // false
        << contains("abc", "abd")   << '\n' // false
        << contains("abc", "xyz")   << '\n';// false
}

答案 5 :(得分:1)

你是什么意思

  

“但它不会充当真正的全功能界面(如果原始界面处于非活动状态,则派生的界面也处于非活动状态”

我可以创建一个新界面,以现有界面为基础,然后禁用现有界面,新界面仍然有效。但是,创建第二个接口不会创建真实的接口(当您使用ifconfig进行检查时),它只会为现有接口分配第二个IP(但是,这个可以是DHCP,而第一个是硬编码的)。

所以我理解你是对的,你想要创建一个界面,而不是绑定到任何真正的界面?那么这个界面将如何使用?例如。如果您断开所有WLAN并拔出所有网络电缆,如果您向其发送流量,此接口会将流量发送到哪里?也许你的问题有点不清楚,如果重新措辞它可能会有很大的帮助,所以很明显,一旦你拥有了这个“虚拟界面”,你实际上正在尝试做什么。

正如您在问题中提到的“alias IP”,这将意味着别名界面。但是别名接口始终绑定到真实接口。区别在于Linux这样的界面真的 IS 一个接口(例如eth0的别名接口可能是eth1),而在Mac上,没有创建真正的接口,而是创建虚拟接口,可以独立配置和使用,但它在物理上仍然是相同的接口,因此不会生成新的命名接口(您只有两个接口,实际上都是en0,但两者都可以启用/禁用独立配置)。

答案 6 :(得分:1)

看一下本教程,它适用于FreeBSD,但也适用于OS X. http://people.freebsd.org/~arved/vlan/vlan_en.html

答案 7 :(得分:0)

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

为什么呢?因为OS X Server在没有静态IP的情况下变得如此FREAKY ......

所以在与DAYS进行摔跤后制作NAT和DHCP以及防火墙......

我正在尝试这是相似的......

会让你知道它是怎么回事......

答案 8 :(得分:0)

转到网络偏好设置。

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

选择您想要arp的现有接口(例如Ethernet 1),并为新端口(例如Ethernet 1.1)提供所需的服务名称,然后按create。

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

ifconfig -a将确认您在接口上有多个IP,并且在重新启动时它们仍然存在。

它是一台Mac。不要打它,做到这一点很容易。

答案 9 :(得分:0)

如果您在开发环境中并且想要访问已在localhost / host机器上运行的某些服务。在docker for mac中你有另一个选项。在docker容器中使用docker.for.mac.localhost而不是localhost。 应使用docker.for.mac.host.internal代替Docker Community Edition 17.12.0-ce-mac46 2018-01-09中的docker.for.mac.localhost。 这允许您从docker容器中连接到您的Mac上运行的服务。请参阅下面的链接

understanding the docker.for.mac.localhost behavior

release notes

答案 10 :(得分:-1)

ifconfig interfacename create将创建一个虚拟接口,

答案 11 :(得分:-1)

这是一个很好的指南:http://gerrydevstory.com/2012/08/20/how-to-create-virtual-network-interface-on-mac-os-x/

基本上,您在系统首选项的“网络”窗格中选择网络适配器,然后单击“复制服务”设备。重复服务后,您可以在其中一个专用地址范围内手动分配IP。然后ping它以确保;)