2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 01:51:26 +00:00

ovn-tutorial: Add a section on ACLs.

Add a section that gives a quick introduction to applying ACLs.  It
discusses how the ACLs are translated into OVN logical flows. It doesn't
get down to the OpenFlow level because that's not supported in
ovs-sandbox yet.  Instead, it provides a reference to an OpenStack
related blog post that talks about how OVN ACLs are used there and gives
examples of the resulting OpenFlow flows.

In theory, once we have a userspace conntrack implementation available,
we'll be able to provide better suppot for it in ovs-sandbox.

Signed-off-by: Russell Bryant <rbryant@redhat.com>
Acked-by: Kyle Mestery <mestery@mestery.com>
This commit is contained in:
Russell Bryant 2015-10-21 16:13:43 -04:00
parent 68dfc25b62
commit 0df6430eda
4 changed files with 154 additions and 1 deletions

View File

@ -628,6 +628,87 @@ see it output to OpenFlow ports 5 and 6 only.
$ ovn/env5/packet2.sh
6) Stateful ACLs
----------------
ACLs provide a way to do distributed packet filtering for OVN networks. One
example use of ACLs is that OpenStack Neutron uses them to implement security
groups. ACLs are implemented using conntrack integration with OVS.
Start with a simple logical switch with 2 logical ports.
[View ovn/env6/setup.sh][env6setup].
$ ovn/env6/setup.sh
A common use case would be the following policy applied for `sw0-port1`:
* Allow outbound IP traffic and associated return traffic.
* Allow incoming ICMP requests and associated return traffic.
* Allow incoming SSH connections and associated return traffic.
* Drop other incoming IP traffic.
The following script applies this policy to our environment.
[View ovn/env6/add-acls.sh][env6acls].
$ ovn/env6/add-acls.sh
We can view the configured ACLs on this network using the `ovn-nbctl` command.
$ ovn-nbctl acl-list sw0
from-lport 1002 (inport == “sw0-port1” && ip) allow-related
to-lport 1002 (outport == “sw0-port1” && ip && icmp) allow-related
to-lport 1002 (outport == “sw0-port1” && ip && tcp && tcp.dst == 22) allow-related
to-lport 1001 (outport == “sw0-port1” && ip) drop
Now that we have ACLs configured, there are new entries in the logical flow
table in the stages `switch_in_pre_acl`, switch_in_acl`, `switch_out_pre_acl`,
and `switch_out_acl`.
$ ovn-sbctl lflow-list
Lets look more closely at `switch_out_pre_acl` and `switch_out_acl`.
In `switch_out_pre_acl`, we match IP traffic and put it through the connection
tracker. This populates the connection state fields so that we can apply policy
as appropriate.
table=0(switch_out_pre_acl), priority= 100, match=(ip), action=(ct_next;)
table=1(switch_in_pre_acl), priority= 0, match=(1), action=(next;)
In `switch_out_acl`, we allow packets associated with existing connections. We
drop packets that are deemed to be invalid (such as non-SYN TCP packet not
associated with an existing connection).
table=1(switch_out_acl), priority=65535, match=(!ct.est && ct.rel && !ct.new && !ct.inv), action=(next;)
table=1(switch_out_acl), priority=65535, match=(ct.est && !ct.rel && !ct.new && !ct.inv), action=(next;)
table=1(switch_out_acl), priority=65535, match=(ct.inv), action=(drop;)
For new connections, we apply our configured ACL policy to decide whether to
allow the connection or not. In this case, well allow ICMP or SSH. Otherwise,
well drop the packet.
table=1(switch_out_acl), priority= 2002, match=(ct.new && (outport == “sw0-port1” && ip && icmp)), action=(ct_commit; next;)
table=1(switch_out_acl), priority= 2002, match=(ct.new && (outport == “sw0-port1” && ip && tcp && tcp.dst == 22)), action=(ct_commit; next;)
table=1(switch_out_acl), priority= 2001, match=(outport == “sw0-port1” && ip), action=(drop;)
When using ACLs, the default policy is to allow and track IP connections. Based
on our above policy, IP traffic directed at `sw0-port1` will never hit this flow
at priority 1.
table=1(switch_out_acl), priority= 1, match=(ip), action=(ct_commit; next;)
table=1(switch_out_acl), priority= 0, match=(1), action=(next;)
Note that conntrack integration is not yet supported in ovs-sandbox, so the
OpenFlow flows will not represent what youd see in a real environment. The
logical flows described above give a very good idea of what the flows look like,
though.
[This blog post][openstack-ovn-acl-blog] discusses OVN ACLs from an OpenStack
perspective and also provides an example of what the resulting OpenFlow flows
look like.
[ovn-architecture(7)]:http://openvswitch.org/support/dist-docs/ovn-architecture.7.html
[Tutorial.md]:./Tutorial.md
[ovn-nb(5)]:http://openvswitch.org/support/dist-docs/ovn-nb.5.html
@ -659,3 +740,6 @@ see it output to OpenFlow ports 5 and 6 only.
[env5setup]:./ovn/env5/setup.sh
[env5packet1]:./ovn/env5/packet1.sh
[env5packet2]:./ovn/env5/packet2.sh
[env6setup]:./ovn/env6/setup.sh
[env6acls]:./ovn/env6/add-acls.sh
[openstack-ovn-acl-blog]:http://blog.russellbryant.net/2015/10/22/openstack-security-groups-using-ovn-acls/

View File

@ -28,7 +28,9 @@ EXTRA_DIST += \
tutorial/ovn/env4/packet5.sh \
tutorial/ovn/env5/setup.sh \
tutorial/ovn/env5/packet1.sh \
tutorial/ovn/env5/packet2.sh
tutorial/ovn/env5/packet2.sh \
tutorial/ovn/env6/setup.sh \
tutorial/ovn/env6/add-acls.sh
sandbox: all
cd $(srcdir)/tutorial && MAKE=$(MAKE) ./ovs-sandbox -b $(abs_builddir) $(SANDBOXFLAGS)

21
tutorial/ovn/env6/add-acls.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
set -o xtrace
ovn-nbctl acl-add sw0 from-lport 1002 "inport == \"sw0-port1\" && ip" allow-related
ovn-nbctl acl-add sw0 to-lport 1002 "outport == \"sw0-port1\" && ip && icmp" allow-related
ovn-nbctl acl-add sw0 to-lport 1002 "outport == \"sw0-port1\" && ip && tcp && tcp.dst == 22" allow-related
ovn-nbctl acl-add sw0 to-lport 1001 "outport == \"sw0-port1\" && ip" drop

46
tutorial/ovn/env6/setup.sh Executable file
View File

@ -0,0 +1,46 @@
#!/bin/bash
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# See "Simple two-port setup" in tutorial/OVN-Tutorial.md.
#
set -o xtrace
# Create a logical switch named "sw0"
ovn-nbctl lswitch-add sw0
# Create two logical ports on "sw0".
ovn-nbctl lport-add sw0 sw0-port1
ovn-nbctl lport-add sw0 sw0-port2
# Set a MAC address for each of the two logical ports.
ovn-nbctl lport-set-addresses sw0-port1 00:00:00:00:00:01
ovn-nbctl lport-set-addresses sw0-port2 00:00:00:00:00:02
# Set up port security for the two logical ports. This ensures that
# the logical port mac address we have configured is the only allowed
# source and destination mac address for these ports.
ovn-nbctl lport-set-port-security sw0-port1 00:00:00:00:00:01
ovn-nbctl lport-set-port-security sw0-port2 00:00:00:00:00:02
# Create ports on the local OVS bridge, br-int. When ovn-controller
# sees these ports show up with an "iface-id" that matches the OVN
# logical port names, it associates these local ports with the OVN
# logical ports. ovn-controller will then set up the flows necessary
# for these ports to be able to communicate each other as defined by
# the OVN logical topology.
ovs-vsctl add-port br-int lport1 -- set Interface lport1 external_ids:iface-id=sw0-port1
ovs-vsctl add-port br-int lport2 -- set Interface lport2 external_ids:iface-id=sw0-port2