Red Hat Training

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

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:
<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>