17.14.11.5. 编写您自己的过滤器
由于 libvirt 仅提供了几个示例网络过滤器,您可能会考虑自行编写。在计划进行操作时,您可能需要了解网络过滤子系统及其内部工作的方式。当然,您还必须了解并理解您需要过滤的协议,以便不再比您需要通过的服务外任何流量,而且事实上您要允许的流量通过。
网络过滤子系统目前仅适用于 Linux 主机物理机器上,且仅适用于 QEMU 和 KVM 虚拟机类型。在 Linux 上,它建立在对 ebtables、iptables 和 ip6tables 的支持之上,并利用了其功能。考虑在 第 17.14.10 节 “支持的协议” 中找到的列表,可使用 ebtables 实施以下协议:
- mac
- STP(跨树协议)
- vlan (802.1Q)
- ARP, rarp
- ipv4
- ipv6
任何通过 IPv4 运行的协议都会使用 iptables 支持,通过 IPv6 上的协议使用 ip6tables 来实施。
通过使用 Linux 主机物理机器,由 libvirt 网络过滤子系统创建的所有流量过滤规则首先通过 ebtables 实施的过滤支持,之后仅通过 iptables 或 ip6tables 过滤器实施。如果过滤器树具有协议的规则,其中包括: mac、stp、vlan arp、rarp、ipv4 或 ipv6;将首先自动使用列出的 ebtable 规则和值。
可以为同一协议创建多个链。链的名称必须具有之前枚举协议的前缀。要创建处理 ARP 流量的额外链,可以使用名称 arp-test 的链,如指定。
例如,可以使用 ip protocol 过滤器根据源和目标端口过滤 UDP 流量,并为要接受的 UDP 数据包指定属性、源和目标 IP 地址和端口。这允许使用 ebtables 进行早期过滤 UDP 流量。但是,一旦 IP 或 IPv6 数据包(如 UDP 数据包)已通过 ebtables 层,且在过滤树中至少有一个规则实例化 iptables 或 ip6tables 规则,也需要为这些过滤层提供 UDP 数据包通过。这可以通过包含相应 udp 或 udp-ipv6 流量过滤节点的规则来实现。
例 17.11. 创建自定义过滤器
假设需要过滤器来满足以下要求列表:
- 防止虚拟机的接口来自 MAC、IP 和 ARP 欺骗
- 仅打开虚拟机接口的 TCP 端口 22 和 80
- 允许虚拟机从接口发送 ping 流量,但不允许虚拟机在接口上 ping
- 允许虚拟机进行 DNS 查找(UDP 为端口 53)
防止欺骗网络过滤器的要求由现有的
清理流量网络过滤器实现
,因此要执行此操作的方式是从自定义过滤器引用它。
要启用 TCP 端口 22 和 80 的流量,添加了两条规则来启用这种类型的流量。要允许客户机虚拟机发送 ping 流量,为 ICMP 流量添加一条规则。出于简单原因,允许从客户机虚拟机启动常规 ICMP 流量,不会指定给 ICMP 回显请求和响应消息。所有其他流量将阻止访问或由客户机虚拟机启动。要执行此操作,则会添加丢弃所有其他流量的规则。假设 guest 虚拟机名为
test
,并且要将我们过滤器与 的接口名为 eth0
,系统将创建一个名为 test-eth0
的过滤器。
这些注意事项的结果是以下网络过滤 XML: