Skip to content

Commit

Permalink
ovn-tutorial: Add a section on ACLs.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Kyle Mestery <[email protected]>
  • Loading branch information
russellb committed Nov 4, 2015
1 parent 68dfc25 commit 0df6430
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 1 deletion.
84 changes: 84 additions & 0 deletions tutorial/OVN-Tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Let’s 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, we’ll allow ICMP or SSH. Otherwise,
we’ll 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 you’d 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
Expand Down Expand Up @@ -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/
4 changes: 3 additions & 1 deletion tutorial/automake.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 21 additions & 0 deletions tutorial/ovn/env6/add-acls.sh
Original file line number Diff line number Diff line change
@@ -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 changes: 46 additions & 0 deletions tutorial/ovn/env6/setup.sh
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 0df6430

Please sign in to comment.