Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

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:
<filter name='test-eth0'>
  <!- - This rule references the clean traffic filter to prevent MAC, IP and ARP spoofing. By not providing an IP address parameter, libvirt will detect the IP address the guest virtual machine is using. - ->
  <filterref filter='clean-traffic'/>

  <!- - This rule enables TCP ports 22 (ssh) and 80 (http) to be reachable - ->
  <rule action='accept' direction='in'>
    <tcp dstportstart='22'/>
  </rule>

  <rule action='accept' direction='in'>
    <tcp dstportstart='80'/>
  </rule>

  <!- - This rule enables general ICMP traffic to be initiated by the guest virtual machine including ping traffic - ->
  <rule action='accept' direction='out'>
    <icmp/>
  </rule>>

  <!- - This rule enables outgoing DNS lookups using UDP - ->
  <rule action='accept' direction='out'>
    <udp dstportstart='53'/>
  </rule>

  <!- - This rule drops all other traffic - ->
  <rule action='drop' direction='inout'>
    <all/>
  </rule>

</filter>