OVS驱动程序与当前的iptables防火墙驱动程序具有相同的API接口,将安全组和端口的状态保留在防火墙内。创建类“SGPortMap”以保持防火墙状态的一致,并负责从端口映射到安全组,或者相反。每个端口和安全组都通过其封装必要信息的自身对象所表示。
注:
Open vSwitch防火墙驱动程序使用register 5标识与流关联的端口,使用register 6标识特别应用于conntrack zones区的网络。
Ingress/Egress 术语
在本文中,ingress 和 egress是相对于连接到OVS的VM实例(或连接到OVS的netns)而言的:
-
ingress 应用在最终进入VM(netns)的流量,假设没有被丢弃
-
egress 应用在由VM(netns)发出的流量
. .
_______|\ _______|\
\ ingress \ \ ingress \
/_______ / /_______ /
|/ .-----------------. |/
' | | '
| |-----------( netns interface )
( non-VM, non-netns )---| OVS |
( interface: phy, patch ) | |------------( VM interface )
. | | .
/|________ '-----------------' /|________
/ egress / / egress /
\ ________\ \ ________\
\| \|
' '
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
请注意,这些术语在OVS代码和文档中的用法不同,其中它们是相对于OVS网桥而言的,ingress应用于进入了OVS网桥的流量,egress应用于离开OVS网桥的流量。
防火墙API调用
防火墙驱动程序执行两个主要调用,以便创建或更新端口安全组 - prepare_port_filter和update_port_filter。这两个方法都依赖于已经在驱动程序中定义的安全组对象,并且工作方式与它们的iptable类似项相同。对象的定义将在后面的部分中描述。prepare_port_filter只能在端口创建其间调用一次,用于定义端口的初始规则。当端口更新时,所有过滤规则都将被删除,并根据驱动中关于安全组的可用信息生成新规则。
可以通过调用update_security_group_rules在防火墙驱动程序中定义安全组规则,此方法将重写给定安全组的所有规则。如果一个远程安全组被修改,则调用update_security_group_members以确定此远程安全组应允许的IP地址集。调用这个方法不会对现有的实例端口产生任何影响。换句话说,如果端口正在使用安全组,其规则通过调用以上方法被改变,则不会为此端口生成新规则。必须调用update_port_filter才能使更改生效。
上面所有的机制都是由安全组RPC方法控制的,这意味着防火墙驱动程序没有基于所提供的变动决定更新哪个端口的逻辑,它仅在从控制器调用时完成动作。
OpenFlow 规则
首先,每个连接根据输入或输出端口被分成ingress和egress流程。每个端口包含初始硬编码,默认可接受的ARP、DHCP和已建立连接流。要检测已建立的连接,流必须首先被conntrack的action=ct()的规则进行标记。可接受的流意味着连接的ingress报文可直接发送到端口,并且离开的egress报文被integration网桥正常交换。
不符合上述规则的连接将依据其方向,分别发送到ingress或egress过滤表。规则以位于单独表中的安全组规则为基础的原因,是为了在删除过程中方便检测这些规则。
对于没有远程组ID和具有远程组ID的安全组规则处理不同。没有远程组ID的安全组规则通过函数create_flows_from_rule_and_port扩展为几个OpenFlow规则。具有远程组ID的安全组规则由三组流表示。前两组是联合流(conjunctive flow),将在下一个描述。第三组与匹配conjunctive ID,并接受动作。
安全组规则的流优先级
OpenFlow规范指出一个报包不应与多个相同优先级流匹配[1]。防火墙驱动程序使用8级优先级实现这一目标。方法flow_priority_offset为给定的安全组规则计算其优先级。优先权的使用对于联合流(conjunction flow)至关重要,这将在后面的联合流(conjunction flow)示例中描述。
我是说…[1]尽管OVS似乎可以神奇地处理下面的重叠流有些情况下,我们不应该依赖它。
- [1] 虽然某些情况下OVS看上去可神奇的处理流的重叠,但是我们不应依赖于此.
conjunctive flows的使用
对于具有远程组ID的安全组规则,需要匹配remote_group_id地址的nw_src字段,并且匹配端口MAC地址的dl_dst字段的流(此处适用于ingress规则;对于egress规则字段是相反的)。如果没有联合(conjunction),这将导致存在O(n*m)条流,其中n和m分别是远程组ID和安全组中的端口数量。
为每个元组(remote_group_id, security_group_id, direction, ethertype, flow_priority_offset)分配一个conj_id。类ConjIdMap处理此映射关系。如果多个规则属于以上的同一个元组,则这些安全组规则共享相同的conj_id。
联合流(conjunctive flow)由两个维度组成。属于维度一的流由方法create_flows_for_ip_address生成,并负责基于IP地址的由远程组ID指定的过滤器。属于维度二的流由方法create_flows_from_rule_and_port生成,并通过方法substitute_conjunction_actions进行修改,表示其远程组ID以外的规则部分。
两个维度的流是基于每个端口的,不包含远程组信息。当一个端口有多个安全组规则时,这些流可以重叠。为了避免这种情况,对流进行排序,并送入函数merge_port_ranges 或 merge_common_rules进行重排。
规则示例与解释
以下示例显示了同一主机上的两个端口。他们有不同的安全组,并且允许ICMP流量从第一个安全组到第二个安全组。端口具有以下属性:
Port 1
- plugged to the port 1 in OVS bridge
- IP address: 192.168.0.1
- MAC address: fa:16:3e:a4:22:10
- security group 1: 可发出ICMP报文
- allowed address pair: 10.0.0.1/32, fa:16:3e:8c:84:13
Port 2
- plugged to the port 2 in OVS bridge
- IP address: 192.168.0.2
- MAC address: fa:16:3e:24:57:c7
- security group 2:
- 可从安全组1接收ICMP报文
- 可从安全组1接收TCP报文
- 可从安全组2接收目的端口为80的TCP报文
- 可从安全组3接收IP报文
- allowed address pair: 10.1.0.0/24, fa:16:3e:8c:84:14
|table_0| 包含一个低优先级规则,用于继续数据包在|table_60|的处理,又名TRANSIENT表。|table_0|留给其它优先级高于防火墙的特性使用,例如DVR。唯一的要求是在特性完成其处理之后,它需要将数据包传递到TRANSIENT表处理。这个TRANSIENT表区分了ingress流量和egress流量,并将端口标识值(对于egress流量,标识值基于交换机端口号,对于ingress流量基于网络ID和目的MAC地址)加载到register 5中;register 6包含一个标识网络的值(也是OVSDB的端口标签)将连接隔离到单独的conntrack区zones。
table=60, priority=100,in_port=1 actions=load:0x1->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,71)
table=60, priority=100,in_port=2 actions=load:0x2->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,71)
table=60, priority=90,dl_vlan=0x284,dl_dst=fa:16:3e:a4:22:10 actions=load:0x1->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,81)
table=60, priority=90,dl_vlan=0x284,dl_dst=fa:16:3e:8c:84:13 actions=load:0x1->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,81)
table=60, priority=90,dl_vlan=0x284,dl_dst=fa:16:3e:24:57:c7 actions=load:0x2->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,81)
table=60, priority=90,dl_vlan=0x284,dl_dst=fa:16:3e:8c:84:14 actions=load:0x2->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,81)
table=60, priority=0 actions=NORMAL
- 1
- 2
- 3
- 4
- 5
- 6
- 7
以下流表,|table_71| 实现ARP欺骗保护、IP欺骗保护,允许与IP地址分配(dhcp,dhcpv6,slaac,ndp)相关的出口流量,并允许ARP回复流量。并且还标识未被跟踪的连接,稍后与从conntrack中获取的信息进行一并处理。当从conntrack获取信息时请注意“actions”字段中的“zone=NXM_NX_REG6[0…15]“。它表明每个端口都有自身的conntrack区,这个区由“register 6”中的值定义(OVSDB的端口标记标识此网络)。它是为了避免接受属于具有相同conntrack参数的不同端口的已建立流量。
|table_71|表中的第一条规则是删除conntrack信息,对于Neutron逻辑端口直接连接到Hypervisor的用例。在此用例中,内核会在数据包到达Open vSwitch之前进行conntrack查询。在conntrack信息清除之后,跟踪的数据包送回同一个流表中处理。
table=71, priority=110,ct_state=+trk actions=ct_clear,resubmit(,71)
- 1
下面的规则允许ICMPv6流量:多播侦听者、邻居请求(neighbour solicitation) 和 邻居广播(neighbour advertisement)。
table=71, priority=95,icmp6,reg5=0x1,in_port=1,icmp_type=130 actions=resubmit(,94)
table=71, priority=95,icmp6,reg5=0x1,in_port=1,icmp_type=131 actions=resubmit(,94)
table=71, priority=95,icmp6,reg5=0x1,in_port=1,icmp_type=132 actions=resubmit(,94)
table=71, priority=95,icmp6,reg5=0x1,in_port=1,icmp_type=135 actions=resubmit(,94)
table=71, priority=95,icmp6,reg5=0x1,in_port=1,icmp_type=136 actions=resubmit(,94)
table=71, priority=95,icmp6,reg5=0x2,in_port=2,icmp_type=130 actions=resubmit(,94)
table=71, priority=95,icmp6,reg5=0x2,in_port=2,icmp_type=131 actions=resubmit(,94)
table=71, priority=95,icmp6,reg5=0x2,in_port=2,icmp_type=132 actions=resubmit(,94)
table=71, priority=95,icmp6,reg5=0x2,in_port=2,icmp_type=135 actions=resubmit(,94)
table=71, priority=95,icmp6,reg5=0x2,in_port=2,icmp_type=136 actions=resubmit(,94)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
以下规则实现ARP欺骗保护:
table=71, priority=95,arp,reg5=0x1,in_port=1,dl_src=fa:16:3e:a4:22:10,arp_spa=192.168.0.1 actions=resubmit(,94)
table=71, priority=95,arp,reg5=0x1,in_port=1,dl_src=fa:16:3e:8c:84:13,arp_spa=10.0.0.1 actions=resubmit(,94)
table=71, priority=95,arp,reg5=0x2,in_port=2,dl_src=fa:16:3e:24:57:c7,arp_spa=192.168.0.2 actions=resubmit(,94)
table=71, priority=95,arp,reg5=0x2,in_port=2,dl_src=fa:16:3e:8c:84:14,arp_spa=10.1.0.0/24 actions=resubmit(,94)
- 1
- 2
- 3
- 4
运行到实例的DHCP和DHCPv6流量,但是实例中的DHCP服务器流量被阻断.
table=71, priority=80,udp,reg5=0x1,in_port=1,tp_src=68,tp_dst=67 actions=resubmit(,73)
table=71, priority=80,udp6,reg5=0x1,in_port=1,tp_src=546,tp_dst=547 actions=resubmit(,73)
table=71, priority=70,udp,reg5=0x1,in_port=1,tp_src=67,tp_dst=68 actions=resubmit(,93)
table=71, priority=70,udp6,reg5=0x1,in_port=1,tp_src=547,tp_dst=546 actions=resubmit(,93)
table=71, priority=80,udp,reg5=0x2,in_port=2,tp_src=68,tp_dst=67 actions=resubmit(,73)
table=71, priority=80,udp6,reg5=0x2,in_port=2,tp_src=546,tp_dst=547 actions=resubmit(,73)
table=71, priority=70,udp,reg5=0x2,in_port=2,tp_src=67,tp_dst=68 actions=resubmit(,93)
table=71, priority=70,udp6,reg5=0x2,in_port=2,tp_src=547,tp_dst=546 actions=resubmit(,93)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
以下规则为有效的IP和MAC地址组合获取conntrack信息,其它报文被丢弃。
table=71, priority=65,ip,reg5=0x1,in_port=1,dl_src=fa:16:3e:a4:22:10,nw_src=192.168.0.1 actions=ct(table=72,zone=NXM_NX_REG6[0..15])
table=71, priority=65,ip,reg5=0x1,in_port=1,dl_src=fa:16:3e:8c:84:13,nw_src=10.0.0.1 actions=ct(table=72,zone=NXM_NX_REG6[0..15])
table=71, priority=65,ip,reg5=0x2,in_port=2,dl_src=fa:16:3e:24:57:c7,nw_src=192.168.0.2 actions=ct(table=72,zone=NXM_NX_REG6[0..15])
table=71, priority=65,ip,reg5=0x2,in_port=2,dl_src=fa:16:3e:8c:84:14,nw_src=10.1.0.0/24 actions=ct(table=72,zone=NXM_NX_REG6[0..15])
table=71, priority=65,ipv6,reg5=0x1,in_port=1,dl_src=fa:16:3e:a4:22:10,ipv6_src=fe80::f816:3eff:fea4:2210 actions=ct(table=72,zone=NXM_NX_REG6[0..15])
table=71, priority=65,ipv6,reg5=0x2,in_port=2,dl_src=fa:16:3e:24:57:c7,ipv6_src=fe80::f816:3eff:fe24:57c7 actions=ct(table=72,zone=NXM_NX_REG6[0..15])
table=71, priority=10,reg5=0x1,in_port=1 actions=resubmit(,93)
table=71, priority=10,reg5=0x2,in_port=2 actions=resubmit(,93)
table=71, priority=0 actions=drop
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
|table_72|表仅接受已建立或相关的连接,并实现由安全组定义的规则。因为这个egress连接也可能是其它端口的ingress连接,虽然还没有切换但最终将由ingress管道处理。
安全组规则定义的所有已建立或新连接都是accepted,稍后解释。所有无效的数据包都将被丢弃。在下面的情况下,我们允许所有ICMP egress流量。
table=72, priority=75,ct_state=+est-rel-rpl,icmp,reg5=0x1 actions=resubmit(,73)
table=72, priority=75,ct_state=+new-est,icmp,reg5=0x1 actions=resubmit(,73)
table=72, priority=50,ct_state=+inv+trk actions=resubmit(,93)
- 1
- 2
- 3
下面的流中的“ct_mark=0x1”很重要。被稍后介绍的规则标记为不再存在的流将检查此值。这些通常是某些安全组规则允许的连接,但是安全组规则已被删除。
table=72, priority=50,ct_mark=0x1,reg5=0x1 actions=resubmit(,93)
table=72, priority=50,ct_mark=0x1,reg5=0x2 actions=resubmit(,93)
- 1
- 2
所有其他未标记且已建立或相关的连接被允许。
table=72, priority=50,ct_state=+est-rel+rpl,ct_zone=644,ct_mark=0,reg5=0x1 actions=resubmit(,94)
table=72, priority=50,ct_state=+est-rel+rpl,ct_zone=644,ct_mark=0,reg5=0x2 actions=resubmit(,94)
table=72, priority=50,ct_state=-new-est+rel-inv,ct_zone=644,ct_mark=0,reg5=0x1 actions=resubmit(,94)
table=72, priority=50,ct_state=-new-est+rel-inv,ct_zone=644,ct_mark=0,reg5=0x2 actions=resubmit(,94)
- 1
- 2
- 3
- 4
在下面,流被标记为已建立连接但是又没有在之前的流中匹配,意味着它们不再具有接受的安全组规则。
table=72, priority=40,ct_state=-est,reg5=0x1 actions=resubmit(,93)
table=72, priority=40,ct_state=+est,reg5=0x1 actions=ct(commit,zone=NXM_NX_REG6[0..15],exec(load:0x1->NXM_NX_CT_MARK[]))
table=72, priority=40,ct_state=-est,reg5=0x2 actions=resubmit(,93)
table=72, priority=40,ct_state=+est,reg5=0x2 actions=ct(commit,zone=NXM_NX_REG6[0..15],exec(load:0x1->NXM_NX_CT_MARK[]))
table=72, priority=0 actions=drop
- 1
- 2
- 3
- 4
- 5
在下表|table_73|中,所有检测到的ingress连接都发送到ingress管道。由于这些连接已被egress管道接受,因此剩余的egress连接被发送到正常的|table_94|表的 Flood’n’Learn 交换逻辑中。
table=73, priority=100,reg6=0x284,dl_dst=fa:16:3e:a4:22:10 actions=load:0x1->NXM_NX_REG5[],resubmit(,81)
table=73, priority=100,reg6=0x284,dl_dst=fa:16:3e:8c:84:13 actions=load:0x1->NXM_NX_REG5[],resubmit(,81)
table=73, priority=100,reg6=0x284,dl_dst=fa:16:3e:24:57:c7 actions=load:0x2->NXM_NX_REG5[],resubmit(,81)
table=73, priority=100,reg6=0x284,dl_dst=fa:16:3e:8c:84:14 actions=load:0x2->NXM_NX_REG5[],resubmit(,81)
table=73, priority=90,ct_state=+new-est,reg5=0x1 actions=ct(commit,zone=NXM_NX_REG6[0..15]),resubmit(,91)
table=73, priority=90,ct_state=+new-est,reg5=0x2 actions=ct(commit,zone=NXM_NX_REG6[0..15]),resubmit(,91)
table=73, priority=80,reg5=0x1 actions=resubmit(,94)
table=73, priority=80,reg5=0x2 actions=resubmit(,94)
table=73, priority=0 actions=drop
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
|table_81|与|table_71|相似,允许基本ingress流量获取IP地址和ARP查询。请注意,VLAN标记必须在报文直接注入到端口之前通过在action列表中增加strip_vlan去除。未跟踪的数据包被发送以获取conntrack信息。
table=81, priority=100,arp,reg5=0x1 actions=strip_vlan,output:1
table=81, priority=100,arp,reg5=0x2 actions=strip_vlan,output:2
table=81, priority=100,icmp6,reg5=0x1,icmp_type=130 actions=strip_vlan,output:1
table=81, priority=100,icmp6,reg5=0x1,icmp_type=131 actions=strip_vlan,output:1
table=81, priority=100,icmp6,reg5=0x1,icmp_type=132 actions=strip_vlan,output:1
table=81, priority=100,icmp6,reg5=0x1,icmp_type=135 actions=strip_vlan,output:1
table=81, priority=100,icmp6,reg5=0x1,icmp_type=136 actions=strip_vlan,output:1
table=81, priority=100,icmp6,reg5=0x2,icmp_type=130 actions=strip_vlan,output:2
table=81, priority=100,icmp6,reg5=0x2,icmp_type=131 actions=strip_vlan,output:2
table=81, priority=100,icmp6,reg5=0x2,icmp_type=132 actions=strip_vlan,output:2
table=81, priority=100,icmp6,reg5=0x2,icmp_type=135 actions=strip_vlan,output:2
table=81, priority=100,icmp6,reg5=0x2,icmp_type=136 actions=strip_vlan,output:2
table=81, priority=95,udp,reg5=0x1,tp_src=67,tp_dst=68 actions=strip_vlan,output:1
table=81, priority=95,udp6,reg5=0x1,tp_src=547,tp_dst=546 actions=strip_vlan,output:1
table=81, priority=95,udp,reg5=0x2,tp_src=67,tp_dst=68 actions=strip_vlan,output:2
table=81, priority=95,udp6,reg5=0x2,tp_src=547,tp_dst=546 actions=strip_vlan,output:2
table=81, priority=90,ct_state=-trk,ip,reg5=0x1 actions=ct(table=82,zone=NXM_NX_REG6[0..15])
table=81, priority=90,ct_state=-trk,ipv6,reg5=0x1 actions=ct(table=82,zone=NXM_NX_REG6[0..15])
table=81, priority=90,ct_state=-trk,ip,reg5=0x2 actions=ct(table=82,zone=NXM_NX_REG6[0..15])
table=81, priority=90,ct_state=-trk,ipv6,reg5=0x2 actions=ct(table=82,zone=NXM_NX_REG6[0..15])
table=81, priority=80,ct_state=+trk,reg5=0x1 actions=resubmit(,82)
table=81, priority=80,ct_state=+trk,reg5=0x2 actions=resubmit(,82)
table=81, priority=0 actions=drop
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
与表|table_72|类似,|table_82|接受已建立和相关的连接。在这种情况下,我们允许来自security group 1的所有ICMP流量,在本例中仅是port 1。前四个流匹配IP地址,并且接下来的两个流匹配ICMP协议。这六个流定义了联合流(conjunction flow),接下来的两个流定义了它们的动作。
table=82, priority=71,ct_state=+est-rel-rpl,ip,reg6=0x284,nw_src=192.168.0.1 actions=conjunction(18,1/2)
table=82, priority=71,ct_state=+est-rel-rpl,ip,reg6=0x284,nw_src=10.0.0.1 actions=conjunction(18,1/2)
table=82, priority=71,ct_state=+new-est,ip,reg6=0x284,nw_src=192.168.0.1 actions=conjunction(19,1/2)
table=82, priority=71,ct_state=+new-est,ip,reg6=0x284,nw_src=10.0.0.1 actions=conjunction(19,1/2)
table=82, priority=71,ct_state=+est-rel-rpl,icmp,reg5=0x2 actions=conjunction(18,2/2)
table=82, priority=71,ct_state=+new-est,icmp,reg5=0x2 actions=conjunction(19,2/2)
table=82, priority=71,conj_id=18,ct_state=+est-rel-rpl,ip,reg5=0x2 actions=strip_vlan,output:2
table=82, priority=71,conj_id=19,ct_state=+new-est,ip,reg5=0x2 actions=ct(commit,zone=NXM_NX_REG6[0..15]),strip_vlan,output:2,resubmit(,92)
table=82, priority=50,ct_state=+inv+trk actions=resubmit(,93)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
还有一些具有远程组ID的安全组规则。下一个我们看看与TCP相关的规则。与这些规则对应的流摘录如下:
table=82, priority=73,ct_state=+est-rel-rpl,tcp,reg5=0x2,tp_dst=0x60/0xffe0 actions=conjunction(22,2/2)
table=82, priority=73,ct_state=+new-est,tcp,reg5=0x2,tp_dst=0x60/0xffe0 actions=conjunction(23,2/2)
table=82, priority=73,ct_state=+est-rel-rpl,tcp,reg5=0x2,tp_dst=0x40/0xfff0 actions=conjunction(22,2/2)
table=82, priority=73,ct_state=+new-est,tcp,reg5=0x2,tp_dst=0x40/0xfff0 actions=conjunction(23,2/2)
table=82, priority=73,ct_state=+est-rel-rpl,tcp,reg5=0x2,tp_dst=0x58/0xfff8 actions=conjunction(22,2/2)
table=82, priority=73,ct_state=+new-est,tcp,reg5=0x2,tp_dst=0x58/0xfff8 actions=conjunction(23,2/2)
table=82, priority=73,ct_state=+est-rel-rpl,tcp,reg5=0x2,tp_dst=0x54/0xfffc actions=conjunction(22,2/2)
table=82, priority=73,ct_state=+new-est,tcp,reg5=0x2,tp_dst=0x54/0xfffc actions=conjunction(23,2/2)
table=82, priority=73,ct_state=+est-rel-rpl,tcp,reg5=0x2,tp_dst=0x52/0xfffe actions=conjunction(22,2/2)
table=82, priority=73,ct_state=+new-est,tcp,reg5=0x2,tp_dst=0x52/0xfffe actions=conjunction(23,2/2)
table=82, priority=73,ct_state=+est-rel-rpl,tcp,reg5=0x2,tp_dst=80 actions=conjunction(22,2/2),conjunction(14,2/2)
table=82, priority=73,ct_state=+est-rel-rpl,tcp,reg5=0x2,tp_dst=81 actions=conjunction(22,2/2)
table=82, priority=73,ct_state=+new-est,tcp,reg5=0x2,tp_dst=80 actions=conjunction(23,2/2),conjunction(15,2/2)
table=82, priority=73,ct_state=+new-est,tcp,reg5=0x2,tp_dst=81 actions=conjunction(23,2/2)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
此处仅显示维度二的流,因为其它流与上一个ICMP示例相似。有更多的流量,但为了显示简洁只覆盖端口范围从64到127的流。
联合(conjunction)ID 14和15对应于来自安全组1的数据包,并且联合(conjunction)ID 22和23对应于来自安全组2的数据包。这些流来自以下安全组规则,
- 可从安全组1接收TCP报文
- 可从安全组2接收目的端口为80的TCP报文
- 1
- 2
并且这些规则被函数merge_port_ranges处理为:
- 可从安全组1接收端口号不等于80的TCP报文
- 可从安全组1或2接收端口等于80的TCP报文
- 1
- 2
在转换为流之前,确保只有一个匹配流即使TCP目标端口是80。
剩下的是L4协议不可知规则。
table=82, priority=70,ct_state=+est-rel-rpl,ip,reg5=0x2 actions=conjunction(24,2/2)
table=82, priority=70,ct_state=+new-est,ip,reg5=0x2 actions=conjunction(25,2/2)
- 1
- 2
任何与之前的TCP流匹配的IP包都与其中一个流匹配,但相应的安全组规则有不同的远程组ID。与上面的TCP示例不同,没有方便的方法表达protocol != TCP 或 icmp_code != 1。所以OVS防火墙使用的优先级与以前的TCP流不同,因此以免混淆它们。
删除不再允许的连接的机制与表|table_72|中的相同。
table=82, priority=50,ct_mark=0x1,reg5=0x1 actions=resubmit(,93)
table=82, priority=50,ct_mark=0x1,reg5=0x2 actions=resubmit(,93)
table=82, priority=50,ct_state=+est-rel+rpl,ct_zone=644,ct_mark=0,reg5=0x1 actions=strip_vlan,output:1
table=82, priority=50,ct_state=+est-rel+rpl,ct_zone=644,ct_mark=0,reg5=0x2 actions=strip_vlan,output:2
table=82, priority=50,ct_state=-new-est+rel-inv,ct_zone=644,ct_mark=0,reg5=0x1 actions=strip_vlan,output:1
table=82, priority=50,ct_state=-new-est+rel-inv,ct_zone=644,ct_mark=0,reg5=0x2 actions=strip_vlan,output:2
table=82, priority=40,ct_state=-est,reg5=0x1 actions=resubmit(,93)
table=82, priority=40,ct_state=+est,reg5=0x1 actions=ct(commit,zone=NXM_NX_REG6[0..15],exec(load:0x1->NXM_NX_CT_MARK[]))
table=82, priority=40,ct_state=-est,reg5=0x2 actions=resubmit(,93)
table=82, priority=40,ct_state=+est,reg5=0x2 actions=ct(commit,zone=NXM_NX_REG6[0..15],exec(load:0x1->NXM_NX_CT_MARK[]))
table=82, priority=0 actions=drop
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
注:
单个节点上的conntrack区zone现在基于端口插入的网络。这使得Hypervisor上的流量与east-west东西向流量有所不同。例如,如果一个端口的VIP,迁移到其它节点的端口上,则新端口将不包含关于与VIP有关的以前流量的conntrack信息。
OVS 防火墙集成点
在报文走完OVS的防火墙管道后,发送到三个表中。这三个表可以被其它假定与OVS防火墙共同工作的机制使用,典型的如L2代理扩展。
Egress 管道
如果数据包被认为是可被egress管道接受的,发送它们到|table_91| 和 |table_94| 进行处理,以便通过提交到一个NORMAL动作action上将它们转发到目的地。NORMAL动作引发对以太网 flood/learn 的处理流程。
两个表用于区分连接的第一个数据包以及后续数据包。这是出于性能原因的考虑,允许日志logging扩展仅记录连接的第一个数据包。每个连接会话的第一个接受的数据包将转到|table_91|,后续的数据包将转到|table_94|。
注意表|table_91|仅重新提交报文到表|table_94|,其中包含实际的NORMAL动作;这允许在一个单一的地方NORMAL动作可以被其它组件覆盖(当前由服务于“networking-bgpvpn”的“networking-bagpipe”驱动程序使用)。
Ingress 管道
ingress管道接受的每个连接的第一个数据包将发送至表|table_92|。此表中的默认动作是DROP,因为此时数据包已被传递到其目标端口。这个集成点基本上是为日志扩展提供的。
如果ingress过滤处理的结果是丢弃数据包,将其发送到表|table_93|。
iptables hybrid 驱动升级路径
在升级过程中,代理需要将每个实例的TAP设备重新插入到integration网桥,与此同时尝试不断开现有的连接。可以采用以下方法中的一种:
-
暂停正在运行的实例,以防止短时间内其网络接口没有防火墙规则。这可能是由于防火墙驱动程序调用OVS以获取有关端口OVS的信息。一旦实例暂停,没有流量后,可以从integration网桥上删除qvo接口,从qbr网桥上分离tap设备,并将tap设备插回到integration网桥。完成后,防火墙规则应用于OVS TAP接口,实例从暂停状态开始运行。
-
为实例的tap接口设置drop规则,删除qbr网桥和相关veth接口,将tap设备插入integration网桥,应用OVS防火墙规则,最后删除实例的drop规则。
-
计算节点可以一次升级一个。自由节点可以切换到使用OVS防火墙,来自其它节点的实例可以实时迁移到自由节点。一旦第一个节点被清空,它的防火墙驱动程序就可以切换到OVS驱动程序。
总结流表功能如下:
- |table_0| replace::
table 0
(LOCAL_SWITCHING) - |table_60| replace::
table 60
(TRANSIENT) - |table_71| replace::
table 71
(BASE_EGRESS) - |table_72| replace::
table 72
(RULES_EGRESS) - |table_73| replace::
table 73
(ACCEPT_OR_INGRESS) - |table_81| replace::
table 81
(BASE_INGRESS) - |table_82| replace::
table 82
(RULES_INGRESS) - |table_91| replace::
table 91
(ACCEPTED_EGRESS_TRAFFIC) - |table_92| replace::
table 92
(ACCEPTED_INGRESS_TRAFFIC) - |table_93| replace::
table 93
(DROPPED_TRAFFIC) - |table_94| replace::
table 94
(ACCEPTED_EGRESS_TRAFFIC_NORMAL)