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