在同一接口上转发流量

在同一接口上转发流量

我正在运行一个托管一组服务的服务器,每个服务都在单独的 Docker 容器中运行。此外,还有一个运行 pfSense 的 KVM 充当防火墙。防火墙有一个连接到外部网络的物理接口和一个连接到内部容器网络的虚拟网卡,使用 Docker 端的 MACVLAN,因此每个容器都有自己的 IP 地址,但它们都在同一个子网中。

出于安全原因,容器需要隔离,并且原则上不能相互通信(仅与外部网络通信)。为此,MACVLAN 配置为 VEPA 模式,允许来自和流向父设备的流量,但不允许流向同一父设备上的其他地址。

现在,我想允许特定容器之间的特定流量,因此 pfSense 必须将流量路由到接收流量的相同接口,同时考虑配置的防火墙规则(读取,如果内部接口上的传入流量符合 PASS 规则,则它将被转发到同一接口/同一子网上的主机)。

我似乎无法让该场景发挥作用(内部接口上的主机之间没有流量,来自和到外部网络的流量按预期工作)。关于如何继续,有什么想法吗?

在 FreeBSD 中或者 pfSense 中是否有任何配置项可以特别防止这种情况发生,例如“在自己的接口上过滤流量”或“实际上这种情况不应该发生,因为流量在路由器前面的交换机上转发,因为它是同一个子网,所以不采取任何措施”?

有趣的是,pfSense 甚至没有回复 ARP 请求(可能有相同的原因):

[root@server ~]# ip r
default via 10.0.20.1 dev server proto static metric 410 
10.0.20.0/24 dev server proto kernel scope link src 10.0.20.2 metric 410

21:52:49.651286 ARP, Request who-has 10.0.20.4 tell 10.0.20.2, length 28
21:52:50.673895 ARP, Request who-has 10.0.20.4 tell 10.0.20.2, length 28
21:52:51.697860 ARP, Request who-has 10.0.20.4 tell 10.0.20.2, length 28
21:52:52.721992 ARP, Request who-has 10.0.20.4 tell 10.0.20.2, length 28

我假设响应是 10.0.20.0/24 接口的 MAC 地址。跟踪是在该接口的防火墙上进行的(从防火墙到 10.0.20.4 的 PING 工作正常)。

手动添加条目时,我可以看到 ICMP 回显请求,但没有回复:

[root@server ~]# arp -s 10.0.20.4 02:42:0a:00:14:04
10.0.20.4                ether   02:42:0a:00:14:04   CM                    server

22:00:21.403515 IP 10.0.20.2 > 10.0.20.4: ICMP echo request, id 5622, seq 1, length 64
22:00:22.450162 IP 10.0.20.2 > 10.0.20.4: ICMP echo request, id 5622, seq 2, length 64
22:00:23.473790 IP 10.0.20.2 > 10.0.20.4: ICMP echo request, id 5622, seq 3, length 64
22:00:24.497803 IP 10.0.20.2 > 10.0.20.4: ICMP echo request, id 5622, seq 4, length 64

答案1

这在一定程度上取决于你打算如何让一个容器引用另一个容器。值得考虑的是,这种网络拓扑是否适合你的用例和安全策略。

如果希望容器 A 通过主机名或 IP 地址直接寻址容器 B,则需要遵循第 2 层交换和第 3 层路由:

  • 如果它们位于同一子网中,则它们只能通过交换机直接相互寻址(正如您所建议的那样,这将被 VEPA 阻止)。 pfSense 主机仅在以下情况下才会看到流量:
    • 流量目标 IP 位于容器子网之外,在这种情况下,容器将把流量发送到默认网关进行路由;或者
    • 流量直接发送到 pfSense 主机名/IP 地址。
  • 如果您将每个容器放在不同的子网(甚至是单独的虚拟网络)上,那么它们之间的流量将通过网关(pfSense)路由。这将使 pfSense 控制防火墙策略。
  • 如果你能确定哪些容器组可以直接相互访问的策略,那么将它们分组到虚拟/docker 网络中会更有意义;这样问题就解决了。在这种情况下,你将网络拓扑与安全策略相结合。这通常更容易做到正确、维持,也更容易让别人理解。

你可以看看 Docker Macvlan 的802.1q 中继桥接模式这可能使得将多个容器网络连接到同一个 libvirt/pfSense 接口变得更容易。

或者,容器之间可能只有非常狭窄且一致的方式进行访问。在这种情况下,您可以考虑端口转发。您可以:

  • 确定你希望其他容器可以访问的特定容器服务
  • 在 pfSense 上,将 MACVLAN 接口特定端口上的传入流量转发到所需容器的 IP/端口
  • 当其他容器需要访问该服务时,它们使用 pfSense 主机的 IP 地址(和指定端口)(不是目标容器)

在这种情况下,其他容器对目标服务的位置一无所知 - 它也可能直接托管在 pfSense 主机上。但请注意,这扩展性不佳,并且仅适用于简单的 TCP/UDP 流量(FTP 设置起来可能很麻烦)。

可能还存在一些其他 Docker 或 libvirt 网络功能,允许您在虚拟网络上的容器之间定义更详细的防火墙策略,尽管我自己还没有深入研究过这一点。

相关内容