OVN实验五:OVN ACL

参考

topo



              outside network
                 |
                 |
                 |
+----------------+------------------------------+
|              eth1                            |
|                                              |
|    sw outside                                |
|                                              |
|              outside-edge1                   |
+----------------------+-----------------------+
                       |
                       |
                       |
+----------------------------------------------+
|              edge1-outside                   |
|           02:0a:7f:00:01:29 10.127.0.129     |
|                                              |
|    Gateway router edge1                      |
|                                              |
|          02:ac:10:ff:00:01 172.16.255.1      |
|              edge1-transit                   |
+----------------------+-----------------------+
                       |
                       |
                       |
+----------------------+-----------------------+
|              transit-edge1                   |
|                                              |
|    sw transit                                |
|    172.16.255.0/30                           |
|                                              |
|              transit-tenant1                 |
+----------------------+-----------------------+
                       |
                       |
                       |
+----------------------+------------------------------------------------------+
|    router tenant1                                                           |
|                                                                             |
|                                                                             |
| 02:ac:10:ff:01:29                                       02:ac:10:ff:01:93   |
| 172.16.255.129                                          172.16.255.193      |
| tenant1-dmz                                             tenant1-inside      |
+----+----------------------------------------------------------+-------------+
     |                                                          |
     |                                                          |
     |                                                          |
+----+------------------------------+         +-----------------+-------------+
| dmz-tenant1                       |         |           inside-tenant1      |
|                                   |         |                               |
|             sw dmz                |         |           sw inside           |
|        172.16.255.128/26          |         |        172.16.255.192/26      |
|                                   |         |                               |
|  dmz-vm1                 dmz-vm2  |         | inside-vm1       inside-vm2   |
+-----+-----------------------+-----+         +-------+--------------+--------+
      |                       |                       |              |
      |                       |                       |              |
      |                       |                       |              |
+-----+------------+  +-------+-----------+  +--------+--------+   +-+----------------+
| 02:ac:10:ff:01:30|  | 02:ac:10:ff:01:31 |  |02:ac:10:ff:01:94|   | 02:ac:10:ff:01:95|
| 172.16.255.130   |  | 172.16.255.131    |  | 172.16.255.194  |   | 172.16.255.195   |
|      vm1         |  |      vm2          |  |     vm3         |   |     vm4          |
+-------------------  +-------------------+  +-----------------+   +------------------+

在实验三环境的基础上做下面的额外配置。

概念

在出站和入站方向都支持使用ACL:
	入站:从工作负载(from-lport)进入逻辑端口(从虚拟机出来进入逻辑网络)
	出站:从逻辑端口出去到工作负载(to-lport)(从逻辑网络出去,进入虚拟机)。

此外,为每个ACL分配一个优先级,以确定它们的匹配顺序,最高优先级首先被匹配。另外ACL可以被赋予相同的优先级。 
然而,在两个具有相同优先级并且都匹配同一个分组的ACL的情况下,将仅匹配一个ACL。
确切地说,哪一个ACL最终将被匹配是不确定的,你不能真正地确定哪个规则将应用于给定的情况。所以我建议:在大多数情况下尽量使用不同的优先级。

ACL中的匹配规则基于OVS中的流语法,对于具有编程背景的人都会觉得很熟悉。该语法在ovn-sb手册页的“Logical_Flow表”部分中进行了说明。它值得一读,特别是介绍“!=”匹配规则的那部分内容。

另外值得强调的一点是,您不能在具有type = router的端口上创建ACL匹配规则。
为了减少ACL表中的条目数,可以使用定义相同类型地址组的地址集。 
例如,一组IPv4地址/网络,一组MAC地址或一组IPv6地址可以放置在命名地址集内。 
然后地址集可以被ACL的match子句内的“name”引用(以$ name的形式)。

#允许来自交换机“ls1”上端口“ls1-vm1”的所有ip流量,同时允许相关回包通过
ovn-nbctl acl-add ls1 from-lport 1000 "inport == \"ls1-vm1\" && ip" allow-related

# 允许 ssh 到 ls1-vm1
ovn-nbctl acl-add ls1 to-lport 999 "outport == \"ls1-vm1\" && tcp.dst == 22" allow-related

# 阻止所有到ls1-vm1的IPv4/IPv6流量
ovn-nbctl acl-add ls1 to-lport 998 "outport == \"ls1-vm1\" && ip" drop

注意“allow-related”的使用。 它的作用是这样:它允许反向相关的流量(例如,响应,fragements等)通过。 在第二条规则中,为了允许从服务器回来的SSH响应流量通过,我就使用了 allow-related 。
我们再来看看地址集。 如前文所述,地址集是相同类型的地址组。 使用ovn-nbctl北向数据库命令创建地址集,然后在ACL中调用地址集。 这里有几个创建地址集的例子:

ovn-nbctl create Address_Set name=wwwServers addresses=172.16.1.2,172.16.1.3
ovn-nbctl create Address_Set name=www6Servers addresses=\"fd00::1\",\"fd00::2\"
ovn-nbctl create Address_Set name=macs addresses=\"02:00:00:00:00:01\",\"02:00:00:00:00:02\"

注意使用带有包含‘:’字符的地址集的双引号。 如果你在命令中不使用双引号,将会报错。

实验

# 通过为每个服务器创建一个静态NAT规则来允许从外部访问DMZ中的服务器。
# 为vm1创建snat-dnat规则并应用于edge1
ovn-nbctl -- --id=@nat create nat type="dnat_and_snat" logical_ip=172.16.255.130 external_ip=10.127.0.250 -- add logical_router edge1 nat @nat

# 为vm2创建snat-dnat规则并应用于edge1
ovn-nbctl -- --id=@nat create nat type="dnat_and_snat" logical_ip=172.16.255.131 external_ip=10.127.0.251 -- add logical_router edge1 nat @nat

# 此时里外都能主动访问对方。

# 添加默认ACL策略(对不匹配任何转发规则的流量进行丢弃)
ovn-nbctl acl-add dmz to-lport 900 "outport == \"dmz-vm1\" && ip" drop
ovn-nbctl acl-add dmz to-lport 900 "outport == \"dmz-vm2\" && ip" drop

# 此时里外都不能访问对方

# 允许所有ip流量和相关连接回包通过
ovn-nbctl acl-add dmz from-lport 1000 "inport == \"dmz-vm1\" && ip" allow-related
ovn-nbctl acl-add dmz from-lport 1000 "inport == \"dmz-vm2\" && ip" allow-related

# 此时虚拟机可以主动访问外面

# 允许外部到DMZ服务器的入站HTTPS (tcp 443端口)和回包流量:
ovn-nbctl acl-add dmz to-lport 1000 "outport == \"dmz-vm1\" && tcp.dst == 443" allow-related
ovn-nbctl acl-add dmz to-lport 1000 "outport == \"dmz-vm2\" && tcp.dst == 443" allow-related

实验二

接下来的操作会使它更加安全:阻止所有出站访问,并且只允许从dmz访问tcp 3306。 
我们将配置一个地址集来表示DMZ内的一些地址。 
注意在“acl-add”命令中使用了单引号。 
我们实际上是通过地址集名称来引用它,前缀是一个'$'字符。 
因为我们不希望bash将其解释为一个变量,所以我们使用了单引号。

# 为dmz服务器创建一个地址集。 使用/31掩码
ovn-nbctl create Address_Set name=dmz addresses=\"172.16.255.130/31\"

# 允许源IP为dmz地址集内的IP地址,且目标端口为3306
ovn-nbctl acl-add inside to-lport 1000 'outport == "inside-vm3" && ip4.src == $dmz && tcp.dst == 3306' allow-related
ovn-nbctl acl-add inside to-lport 1000 'outport == "inside-vm4" && ip4.src == $dmz && tcp.dst == 3306' allow-related

# 添加默认ACL策略(对不匹配任何转发规则的流量进行丢弃)
ovn-nbctl acl-add inside to-lport 900 "outport == \"inside-vm3\" && ip" drop
ovn-nbctl acl-add inside to-lport 900 "outport == \"inside-vm4\" && ip" drop

# 只有vm1和vm2能访问vm3和vm4
# vm3和vm4不能互相访问。