跳转到: 导航, 搜索

Neutron/blueprint ovs-firewall-driver

此页面已过时

请访问: https://review.openstack.org/#/c/89712/

目的

 为了通过使用现有的 OVS 库和与现有基于 iptables 的实现具有相同的功能,通过 OVS 流在 OVS neutron 代理中支持安全组扩展。在 Icehouse 中,现有的 openvswitch 插件正在被弃用,因此该蓝图与使用 openvswitch 机制驱动程序的 ML2 插件兼容。

当前的 neutron.agent.firewall.FirewallDriver 实现基于 iptables (neutron/agent/linux/iptables_firewall.py: IptablesFirewallDriver, OVSHybridIptablesFirewallDriver)。该蓝图描述了实现一个带有 Open vSwitch 的 FirewallDriver 子类。


安全组扩展 API 添加

概述

为了当今在 Neutron 中实现高性能的基于 OVS 的安全组解决方案,源端口匹配是安全组扩展 API 的必要补充。

背景

在当今的 Open vSwitch 中,有两种最佳实践选项来实现防火墙[1]

1. 反射学习动作 (OVS 今天可用)

2. 无状态 ACL,带有 tcp_flags=ack (OVS git 中可用,将于 2014 年初发布 v2.1.0[6])

在同一个电子邮件线程[2]中,讨论了这两种选择之间的权衡

- 反射学习的性能不如它会降低 megaflow 可以通配的流的数量,例如,通配的越少,OVS 必须击中用户空间的流就越多

- “使用 learn 动作从严格意义上来说更正确,因为它只允许对先前看到的流量做出响应的返回流量。TCP 标志匹配允许合理的 megaflow,但仅阻止 SYN 标志并不像安全,因为攻击者可以使流量通过——他们只是无法启动新的连接。”

我首选的实现是“带有 tcp_flags=ack 的无状态 ACL”来模拟状态行为(至少在 TCP 中),因为反射学习的性能不如。

讨论:为什么?

遵循“带有 tcp_flags=ack 的无状态 ACL”方法,实例上的 UDP 客户端需要明确的安全组规则来匹配源 IP 地址和源端口。

示例 1. 远程 UDP 客户端连接到实例 UDP 服务器

A. nw_src=$remote_ip, tp_src=random, nw_dst=$instance_ip, tp_dst=9987

B. nw_src=$instance_ip, tp_src=9987, nw_dst=$remote_ip, tp_src=random

因此,在实例是 UDP 服务器并且默认安全组已经允许所有出站流量的情况下,添加允许 UDP 目标端口 9987 上的入站流量的规则将按预期工作。

示例 2. 实例 UDP 客户端连接到远程 UDP 服务器

C. nw_src=$instance_ip, tp_src=random, nw_dst=$remote_ip, tp_dst=9987

D. nw_src=$remote_ip, tp_src=9987, nw_dst=$instance_ip, tp_dst=random

在实例是 UDP 客户端并且默认安全组已经允许所有出站流量的情况下,我们需要一个新的安全组规则来允许来自远程 UDP 服务器的源端口 9987 上的入站流量,在无状态防火墙中。这与基于 iptables 的有状态防火墙实现不同,因为 iptables 能够在初始看到流 C 时将其反向流添加到其状态表中,持续一段时间。

因此,在安全组中,我们需要一个额外的规则来定义流 D(远程 UDP 服务器的 IP 地址、UDP 源端口 9987 以及当然实例的 IP 地址)。但是,如果您查看今天的安全组 API[3],您会看到没有源端口(tp_src)的匹配项,只有目标端口(—port-range-min, —port-range-max)。

建议的更改:如何修复

因此,为了解决缺乏源端口信息的问题,我建议向安全组扩展 API 添加以下内容,以允许匹配源端口:—source-port-range-min, —source-port-range-max。我已经上传了 neutron[4] 和 python-neutronclient[5] 中实现这些建议添加的 WIP 补丁。

安全组 RPC API 已经具有 source-port-range-min 和 source-port-range-max 字段,因此此更改只会影响 DB 和前端 API。iptables 防火墙已经以这种方式支持 RPC API,并且可以在 neutron/tests/unit/test_iptables_firewall.py 中添加围绕源端口的单元测试。查看 APIChangeGuidelines,此更改将属于“添加可选属性到资源表示,该属性可以由客户端提供,假设 API 之前会忽略此属性”。

脚注

[1] ovs-discuss 邮件列表上的电子邮件线程。 http://openvswitch.org/pipermail/discuss/2013-December/012425.html

[2] http://openvswitch.org/pipermail/discuss/2013-December/012433.html

[3] http://paste.openstack.org/show/55103/

[4] https://review.openstack.org/#/c/62129/

[5] https://review.openstack.org/#/c/62130/

[6] http://openvswitch.org/pipermail/discuss/2013-December/012457.html

ovs_neutron_agent 相关更改

概述

ovs_neutron_agent 在使基于 Open vSwitch 的安全组防火墙实现起作用方面存在一些障碍。这些限制在以下部分中描述。

1. 防火墙在分配本地 VLAN 之前被调用

在为给定的 Neutron 网络分配本地 VLAN 之前,基于 OVS 的防火墙将不知道在允许路径上将数据包转发到哪里。

2. 代理在初始化时移除所有流

启动时,代理会移除所有相关桥接上的所有流。此问题不在此特定蓝图的范围内,并由 blueprint neutron-agent-soft-restart 涵盖。

3. 代理在 port_bound 时移除 VIF 的流

与前一点相关,属于 VIF 的 OpenFlow 端口的所有流都从集成桥接上移除。由于防火墙被调用以在建立连接之前(即在调用 port_bound 之前)设置端口过滤器,这会使防火墙失效。为了解决此问题,我建议对属于防火墙的流使用不同的 cookie,并对属于代理的流使用单独的、不同的 cookie。这将需要 OVS 版本 1.5.0+ 才能基于 cookie 删除流(XenServer 6.2 和 Ubuntu P/Q 版本的当前版本为 1.4.6)。

现有工作和实现

neutron/agent/firewall.py

FirewallDriver:抽象基类

NoopFirewallDriver:无操作实现

neutron/agent/linux/iptables_firewall.py

IptablesFirewallDriver:基于 iptables 的 FirewallDriver 实现

OVSHybridIptablesFirewallDriver:带有附加桥接的 IptablesFirewallDriver 的子类

基于 iptables 的防火墙功能

  • 准备、更新、移除防火墙过滤器
  • 默认情况下丢弃所有数据包
  • 基于端口的 mac 地址防止 IP 欺骗(与 allowed_address_pairs 扩展兼容)
    • 允许传入 DHCP 和 ICMPv6 RA
    • 阻止传出 DHCP
  • 丢弃 INVALID 数据包
  • 允许有状态的、已建立的连接
  • 将安全组规则转换为 iptables 规则(IPv4、IPv6、TCP、UDP、ICMP、ICMPv6)
    • 使用 multiport 模块在单个 iptables 规则中使用多个 TCP/UDP 端口

neutron/agent/linux/ovs_lib.py

Open vSwitch 命令行包装器库

neutron/plugins/openvswitch/agent/ovs_neutron_agent.py

  • 处理 local、flat、vlan、gre、vxlan 类型的网络
  • 通过基于代理的 RPC 实现安全组
    • port_update、treat_devices_added、treat_devices_removed
  • 隧道上的 L2 填充功能(fdb_add、fdb_remove、fdb_update)
  • 处理集成、物理和隧道桥接
    • 将每个 Neutron 网络配置到本地 vlan
    • 通过 veth 配对将物理和隧道桥接修补到集成桥接
    • 添加基本流以实现连接

neutron/db/securitygroups_db.py, neutron/db/securitygroups_rpc_base.py, neutron/extensions/securitygroup.py

  • 安全组模型和 RPC 实现
  • 如果未指定安全组,则确保启动实例的默认安全组
    • 允许所有出站流量
    • 允许来自默认安全组中其他实例的所有入站流量