Red Hat Training

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

18.12.11.6. 自定义过滤器示例

虽然上述 XML 中的其中一个规则包含 guest 虚拟机的 IP 地址作为源或目标地址,但流量的过滤可以正常工作。原因在于,规则的评估会基于每个接口在内部进行,而规则将根据已发送的(tap)接口发送或接收数据包,而不是根据哪个源或目标 IP 地址进行评估。

例 18.12. 网络接口描述的 XML 示例

测试客户机虚拟机的域 XML 中可能的网络接口描述的 XML 片段如下所示:
   [...]
    <interface type='bridge'>
      <source bridge='mybridge'/>
      <filterref filter='test-eth0'/>
    </interface>
   [...]
要更严格地控制 ICMP 流量并强制只能从客户机虚拟机发送 ICMP 回显请求,并且仅由 guest 虚拟机接收 ICMP 回显响应,可使用以下两个规则替换上述 ICMP 规则:
  <!- - enable outgoing ICMP echo requests- ->
  <rule action='accept' direction='out'>
    <icmp type='8'/>
  </rule>
  <!- - enable incoming ICMP echo replies- ->
  <rule action='accept' direction='in'>
    <icmp type='0'/>
  </rule>

例 18.13. 第二个自定义过滤器示例

本例演示如何构建类似的过滤器,但使用位于 guest 虚拟机上的 ftp 服务器扩展要求列表。此过滤器的要求有:
  • 防止客户机虚拟机接口来自 MAC、IP 和 ARP 欺骗
  • 在客户机虚拟机接口中只打开 TCP 端口 22 和 80
  • 允许 guest 虚拟机从接口发送 ping 流量,但不允许在接口上 ping guest 虚拟机
  • 允许客户机虚拟机执行 DNS 查找(UDP 给端口 53)
  • 启用 ftp 服务器(在活动模式下),以便它可以在 guest 虚拟机内运行
要求允许在客户机虚拟机内运行 FTP 服务器到需要,允许端口 21 能够访问 FTP 控制流量,并让客户机虚拟机能够建立源自虚拟客户机的 TCP 端口 20 到 FTP 客户端的传出 TCP 连接(FTP 活动模式)。本例中提供了几种方式编写此过滤器,以及两个可能的解决方案。
第一个解决方案利用 TCP 协议的 state 属性,在 Linux 主机物理机的连接跟踪框架中提供 hook。对于客户机虚拟机发起的 FTP 数据连接(FTP 活跃模式)的 RELATED 状态,用于检测 guest 虚拟机发起的 FTP 数据连接后果(或与 的 的关系)现有的 FTP 控制连接,从而使其允许通过防火墙传递数据包。然而,RELATED 状态仅适用于 FTP 数据路径传出 TCP 连接的第一个数据包。之后,其状态为 ESTABLISHED,然后适用于传入和传出方向。所有这些都与源自虚拟客户机的 TCP 端口 20 的 FTP 数据流量相关。然后,这会导致以下解决方案:
<filter name='test-eth0'>
  <!- - This filter (eth0) 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 port 21 (FTP-control) to be reachable - ->
  <rule action='accept' direction='in'>
    <tcp dstportstart='21'/>
  </rule>

  <!- - This rule enables TCP port 20 for guest virtual machine-initiated FTP data connection related to an existing FTP control connection - ->
  <rule action='accept' direction='out'>
    <tcp srcportstart='20' state='RELATED,ESTABLISHED'/>
  </rule>

  <!- - This rule accepts all packets from a client on the FTP data connection - ->
  <rule action='accept' direction='in'>
    <tcp dstportstart='20' state='ESTABLISHED'/>
  </rule>

  <!- - This rule enables TCP port 22 (SSH) to be reachable - ->
  <rule action='accept' direction='in'>
    <tcp dstportstart='22'/>
  </rule>

  <!- -This rule enables TCP port 80 (HTTP) to be reachable - ->
  <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>
在使用 RELATED 状态尝试过滤器前,您必须确定适当的连接跟踪模块已加载到主机物理机器的内核。根据内核的版本,您必须在建立与客户端虚拟机的 FTP 连接前运行以下两个命令之一:
  • #modprobe nf_conntrack_ftp - where available OR
  • #modprobe ip_conntrack_ftp (如果以上不可用)
如果 FTP 以外的协议与 RELATED 状态结合使用,则必须加载其相应的模块。模块可用于协议:ftp、tftp、irc、sip、sctp 和 amanda。
第二个解决方案使用之前解决方案的连接的状态标志。此解决方案利用了事实:当检测到流量流的第一个数据包时,连接的 NEW 状态是有效的。因此,如果接受流的第一个数据包,则流将变为连接,因此进入 ESTABLISHED 状态。因此,可以编写常规规则,以允许 ESTABLISHED 连接到达 guest 虚拟机或由 guest 虚拟机发送。这是为由 NEW 状态标识的最第一个数据包编写特定规则,并指示数据可被接受的端口。所有数据包都用于未明确接受的端口,从而不会到达 ESTABLISHED 状态。从该端口发送的所有后续数据包也会被丢弃。
<filter name='test-eth0'>
  <!- - This filter references the clean traffic filter to prevent MAC, IP and ARP spoofing. By not providing and IP address parameter, libvirt will detect the IP address the VM is using. - ->
  <filterref filter='clean-traffic'/>

  <!- - This rule allows the packets of all previously accepted connections to reach the guest virtual machine - ->
  <rule action='accept' direction='in'>
    <all state='ESTABLISHED'/>
  </rule>

  <!- - This rule allows the packets of all previously accepted and related connections be sent from the guest virtual machine - ->
  <rule action='accept' direction='out'>
    <all state='ESTABLISHED,RELATED'/>
  </rule>

  <!- - This rule enables traffic towards port 21 (FTP) and port 22 (SSH)- ->
  <rule action='accept' direction='in'>
    <tcp dstportstart='21' dstportend='22' state='NEW'/>
  </rule>

  <!- - This rule enables traffic towards port 80 (HTTP) - ->
  <rule action='accept' direction='in'>
    <tcp dstportstart='80' state='NEW'/>
  </rule>

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

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

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

</filter>