第九章:网络

到目前为止,我们已经将所有的网络任务委托给了主机。您可以将网络配置附加到jail而不是主机,从而赋予jail更多的独立性,并使jail更容易地在主机之间移动。您还可以使用虚拟网络功能将jail连接到网络的不同部分,设置一个jail防火墙,甚至构建一个可以相互连接但不能与外界连接的jail集群。

本章假设您了解网络。如果这里有什么让你困惑的地方,去读一本基本的网络入门,然后回来。我的 系统管理员网络Networking for System Administrators Tilted Windmill Press,2015)就足够了,尽管有相当多的竞争对手。

jail可能比我在这里展示的要复杂得多。我讨论了与vnet的桥接;你可以选择路由。你可以使用 setfib(1) ,尽管vnet在jail环境中已经基本淘汰了它。你可以构建一个被jailed的负载均衡器,并在jail之间分配流量。我不会把一切都给你看。不过,一旦你理解了这些例子,你就可以在你的网络知识允许的范围内实现尽可能多的不同结构。

不过,在深入探讨之前,让我们先考虑一下host。

第九章:网络接口名称和 JailsTCP/IP 和 Jails管理网络访问多个接口和地址Ping, Traceroute, 原始套接字Jails 和环回接口虚拟网络堆栈:VNET虚拟网络设计我们的第一个虚拟网络标准 VNET JailsJail 和 VNET主机和 VNETiocage VNET jails备用接口复杂网络多桥配备多个接口的标准 Jails配备多个接口的 Iocage手动接口管道其他网络功能从DNS获取Jail地址iocage和解析器

接口名称和 Jails

与其将jail配置为使用已连接到网络接口的IP地址,不如让jail在开始之前将其IP连接到所选接口。这使您在添加和删除地址时不必不断编辑主机的/ etc/rc.conf ,但会增加一些小问题。

FreeBSD以网卡驱动程序命名网络接口。通常,您需要接口名称的唯一时间是在排除故障或执行基本系统配置时——也就是说,不经常。接口名称主要在 /etc/rc.conf 中使用,所以谁在乎它叫什么?

不过,一旦你开始在用户空间配置中使用接口名称,接口名称很快就会变得很重要。将网卡从千兆位更改为万兆位并不意味着只需在 rc.conf 中进行搜索和替换;您还必须更新所有这些用户区条目。具有多个网络接口的jail放大了这个问题。

幸运的是,FreeBSD能够重命名网络接口。在开始在jail配置中分配网络接口之前,请为网络接口分配一个类似“jail”的名称。更改网卡时,您可以为新接口分配相同的名称,并保留所有jail配置。

我将此主机的 em0 网络接口专用于jail,因此在这个 rc.conf 代码段中,我重命名了该接口并将其显示出来。

我所有的jail配置现在都可以使用界面名称 jail ,一切都将是正确的。

如果我想为jail分配多个接口,我会以它们的角色命名接口。假设我有一个用于jail的公共互联网,一个用于让jail访问我的专用网络,还有一个用于主机管理。我将为公共接口命名为jpublic, 为私有接口命名为jprivate,并且——只要我在这里——为主机管理接口命名为mgmt

从现在开始,我将在所有网络示例中使用这些接口名称。

TCP/IP 和 Jails

jail对网络的了解有限,具体取决于分配给它的地址。jail可以打开标准的TCP/IP套接字,允许您运行典型的服务器。如果你的jail可以访问 /dev/bpf ,并且你启动了一个数据包嗅探器,你只会收到广播流量和发往jail IP地址的流量。不过,您可以精确控制这些网络限制的工作方式。

管理网络访问

jail默认只访问提供给他们的网络地址,但这不是唯一的选择。ip4和ip6参数控制对内核TCP/IP堆栈的访问。两者工作方式相同。

默认设置 new 告诉内核只允许jail访问指定的IP地址。如果jail请求特定的IP地址,主机会尝试将该地址添加为新的别名。所有来自jail的流量都使用分配为源IP的第一个IP。

将这些设置为inherit ,jail可以访问主机的所有IP地址。这通常是不可取的,但正如我们将在第11章中看到的那样,这种情况并不罕见。

最后,要禁止jail使用IP家族,请将此值设置为禁用。如果我想阻止jail使用IPv4,但允许访问主机的整个IPv6地址集合,我会使用这个。

即使是一个简单的 ping localhost 现在也会出现“不支持协议”错误。我可能会用这个来看看应用程序是否真的能在纯IPv6上运行。

请注意,如果禁用IP协议,但同时在该协议族中分配地址,则会重新启用该协议。jail认为,如果你分配了一个地址,你必须希望这个地址能够正常工作。

即使我允许对IP地址进行jail控制,除非我允许,否则它仍然无法控制整个网络堆栈。

多个接口和地址

大型生产主机通常有多个接口,或至少有多个VLAN,每个都专用于特定目的。如果你想让 jail(8) 在jail启动时将jail的IP地址添加到特定接口,并在jail关闭时删除该地址,请在IP地址参数中的IP地址之前列出该接口,如下所示:

用IP地址存储jail接口信息的优点是,jail配置可以很容易地移动到完全不同的主机上。

iocage的工作方式完全相同,除了它使用 ip4_addrip6_addr 参数。

这些jail现在将在启动时连接到目前被称为 jpublic 的任何网络接口。

jail地址是网络接口上的IP别名。这意味着它们被分配了 /32/128 的网络掩码,但从接口的主地址继承了一个实用的网络掩码。主地址可能连接到主机,这对大多数应用程序来说都很好。如果接口还没有地址,请使用地址分配指定网络掩码。

一个jail可以有多个IP地址。如果请求的地址尚未在主机上,主机将自动将每个地址添加为主网络接口上的别名。列出ip4.addr或ip6.addr中的地址,用逗号分隔。

不过,一旦涉及多个接口,jail.conf 语法就会发生变化。您必须使用多个 ip4.addrip6.addr 语句和 += 语法。在这里,我在jpublic接口上为jail分配了两个地址,在jprivate接口上分配了另一个地址。

您不能在 jail.conf 中组合多个IP地址和接口分配。一旦您开始将接口信息与地址一起包含在内,您必须在自己的行中列出每个地址,即使多个地址被分配给一个接口。

您还可以在多个接口上为iocage jail提供地址。使用iocage,您可以将这些作业组合在一行中。

您可以在jail中列出任意数量的接口和地址,但请记住,jail会将任何未标记接口的IP附加到它认为是主机主接口的IP上。我鼓励您明确地标记接口,以防止iocage改变主意并选择不同的接口。

多个地址和接口迫使jail决定使用哪个源地址进行出站连接。当系统可以从多个地址或多个接口发起流量时,它必须选择将哪个源地址放在传出连接上。如果jail有15个IP地址,而你通过SSH离开jail,jail会说连接来自哪里?

经验法则是,传出连接使用接口上流量离开主机的第一个地址作为其源地址。如果接口 jprivate 的主IP地址为 198.51.100.234 ,并且系统将流量从该接口路由出去,则连接来自IP 198.51.100.234

jail会稍微改变源地址选择。分配给jail的第一个地址是jail的主要地址。如果jail找不到一个更合适的地址用于传出连接,它就会使用这个地址。大多数时候,这是一个毫无意义的区别,但对与host和host的其他jail的沟通有不同寻常的影响。

多个jail可以共享一个IP,前提是且仅当这是分配给两个jail的唯一IP。你不能有一个jail有多个地址,而第二个jail共享其中一个地址。您不能在多个jail中拥有多个共享地址。jail可以共享一个且只能共享一个地址,他们会像孩子一样争论谁可以绑定到哪些TCP/IP端口。

您可以在只有一个面向网络的IP地址的主机上运行jail。如果您明确地将主机的唯一IP地址分配给jail,则jail和主机都将失去网络连接。您可以通过允许jail继承主机的IP堆栈或将jail绑定到环回地址来解决此问题。

如果将jail的ip4和ip6参数设置为 inherit ,则jail可以访问主机上的每个IP地址。您需要在备用端口上运行jail的面向外部的服务,如 SSH,或者通过 jexec 在本地管理jail。我们将在第11章讨论这个模型。

您可以将私有IP地址附加到环回接口 lo0 ,并将jail绑定到这些地址。您需要在主机的数据包过滤器上安装NAT,以便为这些jail提供网络访问权限,并使外界能够访问所需的服务。

Ping, Traceroute, 原始套接字

jail无法访问原始TCP/IP套接字。这些插座比标准的“cooked”套接字更灵活,允许主机手工制作数据包。知识渊博的用户可以使用原始套接字来操纵各种网络堆栈内部。问题是, pingtraceroute 等网络工具需要原始套接字访问。

虽然 pingtraceroute 是排除网络连接故障的首选工具,但也有测试网络功能的替代方案。我常用的命令是 host(1) ,尤其是当jail的名称服务器不在本地网络上时。如果你能运行类似 host mwl.io 的命令并得到答案,那么你的jail很可能有网络连接。如果您的名称服务器位于本地局域网上,请尝试使用另一个网络感知命令,如 fetch(1) 。正在运行fetch https://mwl.io 将在新的FreeBSD安装上生成OpenSSL错误,因为FreeBSD没有附带受信任的证书颁发机构包——但仅仅出现该错误就意味着你的jail与远程主机进行了交互。网络正常工作。(您可以运行 fetch -o - --no-verity-peer https://mwl.io 忽略TLS错误,但这是一种糟糕的做法,所以不要。)

如果您信任jail所有者和在该jail中运行的应用程序,则可以使用 allow.raw_sockets 参数(iocage的 allow_raw_socket )允许原始IP套接字访问。设置此参数并重新启动jail将允许 pingtraceroute 工作。

一般来说,jail的网络限制只影响IPv4、IPv6、本地套接字和路由。您可能希望jail包含TCP/IP组件的应用程序,甚至包含非TCP/IP组件。此类应用程序需要特权来创建通用IP套接字。 allow.socket_af 参数(iocage中的 allow_socket_af )允许jail创建jail协议之外的网络套接字。通过启用此功能,您允许jail操纵任意网络特征。如果您需要为不受信任的应用程序或jail所有者启用此功能,您可以考虑将此jail切换到完全虚拟化。

Jails 和环回接口

jail和主机之间以及同一主机上的jail之间的所有TCP/IP通信都发生在环回接口 lo0 上。(连接到 lo1 等接口的私有jail在该接口上相互通信,但与主机的任何通信仍然通过 lo0 。)如果你在jail上,并且通过SSH连接到主机,则连接永远不会连接到外部网络。这是大多数操作系统的标准行为,但它对jail有影响。

一个IP地址可以连接到多个jail,前提是且仅当这是所有jail的唯一IP。大多数jail需要一个外部地址才能访问网络,因此它们也不能连接到环回地址 127.0.0.1::1 。许多软件包都希望 localhost 可用,包括标准FreeBSD安装中的一堆东西。默认情况下,jail没有环回地址,因此他们使用默认地址:jail连接的第一个IP。你自己试试;在主机上运行 tcpdump -i lo0 ip on ,然后去jail运行 ping 127.0.0.1

这满足了软件的要求。这也意味着,当一个被监禁的守护进程连接到 lookback 上的端口时,它实际上是连接到jail的外部IP地址。如果您指望守护进程仅绑定到环回地址作为安全措施,那么您的假设是无效的。在 localhost 上监听的守护进程实际上是在监听面向网络的地址。

显而易见的做法是为jail创建一个环回接口,或者甚至为每个jail提供自己的环回,并为每个jail分配一个唯一的私有IP。虽然它将这些地址与网络隔离开来,但它并没有将jail彼此隔离。环回地址可以相互到达。根本问题是每个jail都使用主机的网络堆栈。主机的网络堆栈非常清楚如何访问所有这些地址。本地主机上的TCP/IP旨在通信,而不是隔离。

真正将jail彼此分开的唯一方法是为每个jail分配一个虚拟网络堆栈或vnet。

虚拟网络堆栈:VNET

虚拟网络堆栈——Virtual Networking Stacks

Unix系统传统上只有一个网络堆栈。它可能支持多个路由表,让不同的应用程序将流量发送到不同的网络,但在大多数情况下,所有的网络堆栈都是一个整体。每个程序都可以看到主机上的每个接口。

FreeBSD可以创建虚拟网络堆栈或vnet。vnet完全控制分配给该vnet的任何接口。您可以为jail创建虚拟接口,根据需要将它们连接在一起,并在您的机器内完全创建自己的网络。

你会读到关于vnet漏洞的抱怨。它们最初出现在FreeBSD 8-CURRENT中,与其他大型新复杂软件一样,也存在问题。Vnets经过了十多年的广泛测试,仅在FreeBSD 12中默认启用。 如果你看到一条抱怨vnets的消息,请检查日期。这并不是说vnet是完美的——bug可能发生在任何地方。但它们有望发挥作用,被广泛使用,错误报告与任何其他FreeBSD错误一样受到重视。

将每个jail放在自己的vnet中,为jail提供了一个完全隔离的网络堆栈。每个jail都有自己的环回接口,允许在不向其他jail泄露信息的情况下进行本地网络连接。您可以将数据包过滤器管理委托给jail,允许jail所有者将自己锁在jail之外,而不是在主机级别进行。Vnet隔离甚至可以防止DTrace和数据包嗅探器等调试器。

Vnets并不完美。运行比主机旧的FreeBSD版本的jail可能会发现,由于内核结构不同, netstat(1)sockstat(1) 等程序无法正常工作。一些网络感知程序需要访问 /dev/mem/dev/kmem ,这些程序永远不应该暴露在jail里。(jail在尝试使用它们时应该收到“拒绝许可”的消息,但仍然;不要暴露它们。)不过,总的来说,vnet比继承主机网络堆栈的一小部分有了巨大的改进。

jail完全控制着它的vnet。jail可以直接进入。像 allow.raw_socketsallow.socket_af 这样的参数实际上是打开的,不能关闭。

在本节中,我们将假设您的jail运行的FreeBSD版本与主机非常相似。jail和host之间的差异越大,你的难度就越大,正如第10章所讨论的那样。

虚拟网络设计

不要在所有jail上加上vnet参数并重新启动它们。你会完全破坏连接。从设计带有接口和网桥的虚拟网络开始。

接口是将主机连接到其他设备的管道。FreeBSD有几种不同类型的虚拟接口可用于jail。我们将重点介绍 epair(4) ,它实际上相当于通过网线连接的两个以太网接口。epair接口有一个A端和一个B端。为了保持一致性,始终将A端连接到网桥,将B端连接到jail。(或者决定“B代表桥接”,然后换一种方式。无论你选择什么,都要保持一致!)每个epair接口都有一个以e开头的名称,即接口编号,以及这个接口的终点,所以要么是 e0a ,要么是 e0b 。然后,它会得到一个尾随标签,描述epair的功能。对于jail,请使用jail名称。这意味着 e0a_lowest 接口是jail loghost 上的第一个epair接口,并连接到网桥。

桥接器将接口连接在一起。网桥执行与标准以太网交换机相同的功能。网络纯粹主义者应该注意,FreeBSD的 bridge(4) 虚拟网桥就像交换机一样过滤流量。连接到网桥的所有接口都可以相互通信,但不能窥探彼此的流量。

这种虚拟网络的诀窍在于,并非所有接口都需要是虚拟的。我可以将我所有的jail插入一个虚拟网桥,这样它们就可以互相看到,然后添加主机的物理外部接口。突然间,我插入虚拟网桥的所有虚拟接口都可以与主机之外的非虚拟网络通信。

你可能希望你的jail只与彼此沟通。不要将真正的接口连接到桥上,jail将与世界隔绝。

也许你的jail需要连接到多个网络。为每个jail提供多个接口,并连接到多个网桥。将主机的一个VLAN添加到网桥中,网桥就可以看到该VLAN。

如果你的jail网络比“我所有的jail都通过主机的jail接口连接到外部世界”稍微复杂一点,停下来。拿出一张纸。画一张地图。标记所有网段。在哪些组件上绘制箭头,指向哪些分段。使用颜色。这可能看起来很幼稚,但如果你不能画出一幅图,你就无法组装虚拟网络。如果你试图复制一个现有的环境——比如,如果你正在构建一个应该反映你组织生产环境的测试平台——获取该环境的图表并将其用作基础。

我们的第一个虚拟网络

在最初的测试中,我们使用了一个非常简单的网络。我们只有一个物理接口,jailether 。我们所有的jail都将连接到一个包含该接口的网桥,并通过该网桥连接到本地网络。我们将在标准jail和iocage中考虑这一点。

无论哪种方式,选择一个物理界面来专用于jail。从界面中删除所有IP网络配置;只要把它提出来,给它起个名字。

现在,您可以针对该接口配置vnet jail。

标准 VNET Jails

完全可以手动创建一个epair界面,将一端连接到jail,另一端连接到桥,将桥连接到网口,然后打开jail。不过,没有人有时间做这一切,尤其是当FreeBSD包含为你做这件事的脚本时。

目录 /usr/share/example.jailes/ 包含一大堆供jail管理员使用的脚本和文档。其中一些只适用于较旧的FreeBSD版本,而另一些则与我们正在做的事情无关。复制 /usr/share/example.jail/jib 脚本,并将其放在放置系统脚本的任何位置。在这些示例中,我使用 /usr/local/scripts/jibJib 代表 Jail Interface Bridge ,它可以在任何有四个或更少网桥的虚拟网络上自动创建和销毁epair界面。

现在配置我们的第一个vnet jail。这是vnet友好的jail.conf的开始。

这些条目从任何jail所需的基本设置开始。我们定义一个放置jail文件的路径,设置主机名,定义启动和关闭命令,并将 devfs 放入jail中。jail(8) 启动和停止jail时记录的exec参数不是强制性的,但我将使用它们来说明一些功能。

现在,让我们建立一个vnet jail。

vnet参数告诉 jail(8) 为该jail分配其自己的虚拟网络堆栈。

vnet.interface 参数告诉 jail(8) 将哪个接口插入该jail。我们正在使用epair接口,所以我称该接口为 e0b_loghost

jail的个人 exec.prestart 参数调用 jib 来添加接口。请注意,我使用 += 语法设置了此参数。我已经在 jail.conf 的顶部定义了一个全局默认的 exec.prestart 。这个新条目将添加到默认值中。

jib addm 命令创建jail的epair接口,并将一端添加到桥上。如果这座桥不存在,jib就会创建它。我在这里给出了两个论点,loghost jailether。这转化为:创建一个标记为loghost的epair接口,并将一端连接到包含接口jailether的桥上。

jail的 exec.poststop 调用jib destruction ,删除了不必要的epair接口。它需要一个论点,即破坏epair接口。

现在开始jail。

Jail 和 VNET

登录jail并运行ifconfig。您将看到两个接口,lo0和e0b_loghost。你有一个网络!

仔细一看,网络没有IP配置。一个非vnet jail依赖于主机的网络,但vnet jails无法访问主机的网络。进入jail的 /etc/rc.conf ,像在任何其他FreeBSD主机上一样配置网络。

重启jail,你就可以上网了。

私有vnet允许在不牺牲安全性的情况下在jail配置中具有更大的灵活性。如果你允许访问 /dev/bpf ,你既可以嗅探数据包,也可以使用DHCP分配jail地址。如果主机加载了防火墙内核模块,并且您将防火墙设备暴露给jail,则可以在jail内运行PF。

主机和 VNET

在登录新的vnet jail之前,先看看主机。你会注意到两个新的接口,jailetherbridgee0a_lowest 。让我们先看看这座桥。桥上的一堆东西只对网络人士感兴趣,但有些东西很有启发性。

这座桥是以添加到其中的第一个物理接口命名的。该接口名为 jailether ,所以这就是 jailetherbridge

每个网桥成员都出现在以下列表中。第一个成员是jail的 epair 接口 e0a_lowest 的A端。第二个成员是物理接口,jailether 。每增加一座vnet jail,这座桥都会增加一名成员。如果你看到一个不属于此桥的jail的接口,那么你就搞砸了 jail.conf 条目。

有一件事你看不到,那就是 e0b_loghost 接口,它连接到jail的一端。 ifconfig 命令仅显示连接到当前网络堆栈的接口。你在jail里看不到接口,就像你在桌面上运行 ifconfig 看不到服务器的接口一样。去jail登记。

iocage VNET jails

iocage程序可以为您管理网桥和接口。它默认使用一个非常简单的网络,一个通过主机主接口访问网络的网桥。(“主界面”被定义为“任何可以点击默认路线的界面。”我们将讨论更改它,但现在还是继续吧。)

通过将 vnet 设置为 on 来创建一个vnet jail。您还必须设置一个IP地址,包括网络掩码。如果你想让jail到达本地局域网以外的网络,还可以定义 defaultrouter 参数。然后你需要一个名字和版本,就像任何其他iocage jail一样。

当jail被创建时,看看你的网卡。您将发现一个新添加的 bridge0 ,其中包含主机的主网卡和jail的一半 epair 。iocage程序用一个数字命名新的 epair 接口vnet。接口描述给出了jail名称。

关闭所有jail并不会摧毁这座桥。人们可能会在该网桥上配置DHCP、数据包过滤器或NetFlow等服务,因此它需要保持不变。如果它冒犯了您,请使用 ifconfig bridge0 destroy 手动删除它——但一旦您启动另一个vnet jail,它就会重新出现。

确实如此。除非我们想变得复杂。我们做的。

备用接口

我不希望我的jail使用主机的管理接口。这就是为什么我有这个 jailether 接口,这样jail就可以在网络上吐垃圾,而不会干扰我的原始主机。参数 vnet_default_interface 指定要添加到网桥的系统接口,而不是主机的主接口。我不仅想使用接口 jailether ,我还希望所有iocagejail都使用该接口。这意味着我需要更改iocage对此参数的默认设置。

关闭你所有的iocage vnet jail。删除现有的 bridge0 接口。重新启动iocage vnet jails,iocage将创建一个具有适当接口的新桥。

复杂网络

如果你想要一大堆桥,每座桥上都有jail,那该怎么办?再次,绘制网络图。命名你的桥。显示您希望每个jail插入的位置。然后,您可以使用iocage的接口映射参数 interfaces 将jail接口分配给网桥。 interfaces 参数始终采用 vnet:bridge 格式。iocage程序创建vnet接口,但它假设如果你将接口映射到特定的网桥,你就对这些网桥负责。在这里,我映射了jail www1上的vnet接口,以连接到网桥 jailetherbridge

如果您有多个接口,请用逗号分隔:

也为每个接口分配IP地址:

为什么jail会有多个接口?我很高兴你问我!

多桥

对于大多数应用程序来说,拥有一个连接到外部世界的单一接口的网桥是很好的,但如果你试图模拟一个更复杂的设置呢?也许你想在防火墙后面测试一个应用程序,或者测试那些具有多层负载均衡器和数据包过滤器的多层web服务器/数据库设置之一,谁知道呢?也许你不能把价值数百万美元的专有防火墙放在jail里,但你可以在将应用程序部署到测试环境之前,模拟基本架构并解决明显的问题。

我们将在虚拟网络中添加第二层。现有的网桥 jailetherbridge 将保持不变。我们正在添加另一个网桥 jailprivbridge ,它使用 192.0.2.0/24 的IP范围。数据库服务器将仅连接到专用网桥,而应用程序服务器将连接到面向以太网的网桥和专用网桥。

您知道如何将数据库主机连接到网桥;只需将 jailetherbridge 入口更改为 jailprivbridge 。这种配置的唯一诀窍是了解如何创建桥,然后如何将多个接口连接到jail。

配备多个接口的标准 Jails

jib 命令需要一个现有的接口来构建网桥,因此我们将在主机上创建一个环回接口。我将把这个接口称为 jailpriv 。(我会拼出 jailprivate ,但得到的网桥名称太长。)在启动时使用这些 rc.conf 条目创建这个接口:

重新启动后,您可以将专用网桥连接到此接口。

现在配置一个具有多个接口的jail。jail loghost将连接到公共和专用网络。

vnet.interface 参数有两个接口名称,用逗号分隔。请注意,接口没有引用。引用会导致它们被视为一个单元,当你只有一个界面时,这很好,但当你想要多个条目时,这会适得其反。

棘手的部分是 exec.prestart jib命令。 addm loghost 部分基本上意味着“将loghost接口添加到这些网桥中”。然后,它列出了要将每个接口添加到的网桥。接口按顺序添加到网桥中——也就是说,第一个接口连接到第一个网桥,第二个接口连接到第二个网桥,以此类推。

vnet.interface 中显示的第一个接口 e0b_loghost 被粘到 exec.prestart jib addm loghost 命令 jailether 末尾显示的第个网桥上。 vnet.interface 中显示的第二个接口 e1b_loghost 连接到显示的第二桥 jailprivjib 脚本允许您列出最多四个接口和桥。

如果你在配置jail时出错,最终得到新创建的接口,但没有运行jail,运行 jib destroy loghost 将删除该jail的所有接口。

启动jail并在所有接口上配置IP地址。您应该能够ping通专用网桥和面向以太网的网桥。专用网桥上的主机与外界没有连接,除非您将其中一个双接口主机配置为数据包过滤防火墙。

配备多个接口的 Iocage

在尝试使用之前,您必须在 rc.conf中 创建 jailprivbridgejailetherbridge 接口。在这里,我创建了接口 bridge0bridge1lo1 ,为它们指定了所需的名称,并向这些桥添加了接口:

我们现在可以使用这些网桥。

使用iocage的 interfaces 属性以逗号分隔的对将虚拟接口分配给网桥。在这里,我将虚拟接口 vnet0 附加到网桥 jailetherbridge ,将 vnet1 附加到 jailprivibridge

配置多个IP地址非常相似,除了IP地址参数使用管道而不是冒号来配对接口和地址:

现在,您可以在私人和公共网桥上启动 www1 并ping。(记住,vnet jails控制自己的套接字,不需要特殊的ping权限。)

当你把一个jail搬到一座完全私人网桥桥上时,你会发现一个小问题。那个网桥没有外部通道,但如果没有一条看起来合法的默认路线,iocage就不会建造jail。这里的关键是合法的外观。将 defaultrouter 参数设置为jail子网上未使用的IP,iocage将立即启动jail。

手动接口管道

隐藏所有繁琐命令行的脚本和命令很好,但有时你别无选择,只能手动挖掘和设置网络。也许你需要两个jail之间的虚拟交叉电缆,或者你正试图模拟你的网络管理员开玩笑地称之为生产网络的交换机和电缆的老鼠窝。ifconfig 命令允许你创建逻辑接口并在vnet之间切换接口。例如,我正在创建一个单一的 epair 接口,并将一端连接到主机防火墙,另一端连接到网桥故障转移。这正是iocage和 jib 在创建接口时所做的。

创建一个虚拟界面,如桥或肩章,只需要声明它的存在。 ifconfig 命令返回设备名称和编号。

虽然 ifconfig 只告诉您 epair 的一端,但它会创建两端。如果你想要一个特定的设备号,请在创建接口时声明它。如果我想专门使用设备9:

为您的 epair 接口指定有意义的名称:

现在我们必须决定把这些接口放在哪里。对于我们之前的所有示例,epair 的一端都连接到一个网桥上。另一个被关在jail里。一般来说,我将接口的一端尽可能靠近主机。在这里,我将 e0a_firewal l连接到网桥故障转移:

epair 另一端的 e0b_firewall 接口需要移动到vnetjail防火墙中。每个jail都以其jail命名。(在你问之前:是的,主机的网络堆栈也作为一个名为vnet 0的vnet运行。)用 ifconfig 分配接口的vnet。

该接口将从主机的网络堆栈中消失,并重新出现在jail中。

您可以在vnets之间移动任何接口。假设你在jail里运行你的网络服务器,但它的流量足够大,需要一个专用接口。

你的jail现在有一个私人物理接口。

其他网络功能

jail还有其他各种联网功能。您可以从DNS获取jail的IP地址,利用PF在一个IP上托管多个jail,并让iocage配置jail的解析器。

从DNS获取Jail地址

您的DNS服务器中已经有一个权威的主机名和地址列表,那么为什么您可能想在 jail.conf 中维护第二个列表呢?就我而言,这是因为我编造了我所有的jail名字,而不费心把它们放进DNS。不过,从DNS中获取jail IP地址对于许多环境来说都是非常有意义的。

ip_hostname 参数告诉 jail(8) 查找 host.hostname 参数值的IPv4和IPv6地址,并将返回的第一个地址分配为jail的IPv4和IPv6地址。

jail的 name 参数从来不是默认值,但如果将 ip_hostname 设置为默认值,则可以将jail定义简化为这样的值。

此功能在iocage中作为 ip_hostname 参数可用。

ip_hostname 参数将DNS添加为启动依赖项。如果你把DNS服务器关起来,请验证你的DNS服务器即使在完全冷启动的情况下也能自我引导。在UPS和柴油发电机断电后,您的网络将如何重新启动?我建议在提供DNS服务的jail中避免使用 ip_hostname 。鸡和蛋的自助问题让每个不必解决它们的人都很开心。

iocage和解析器

iocage程序默认将主机的 /etc/resolv.conf 复制到每个jail。这是一个不错的默认设置,但您可能需要不同的配置。如果你的主机有一大堆jail,你可以再添加一个作为递归DNS服务器,或者你可能想将特定的jail定向到某个DNS服务器。

resolver 参数允许您在命令行上配置jail的 resolv.conf。分号成为换行符。假设我想让jail www1 使用这个 resolv.conf

我会这样设置 resolv 属性:

要还原为默认值,请将 resolvr 设置为 /etc/resolv.confnone

resolver 配置是使用默认jail设置为全局默认值的主要候选者。

此时,您应该能够以任何需要的方式配置网络。让我们看看用jail来处理奇怪的事情。