[ovs-dev] [PATCH v2] ovn-tutorial: Add a section on ACLs.

Russell Bryant rbryant at redhat.com
Wed Nov 4 15:53:32 UTC 2015


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 at redhat.com>
---
 tutorial/OVN-Tutorial.md      | 84 +++++++++++++++++++++++++++++++++++++++++++
 tutorial/automake.mk          |  4 ++-
 tutorial/ovn/env6/add-acls.sh | 21 +++++++++++
 tutorial/ovn/env6/setup.sh    | 46 ++++++++++++++++++++++++
 4 files changed, 154 insertions(+), 1 deletion(-)
 create mode 100755 tutorial/ovn/env6/add-acls.sh
 create mode 100755 tutorial/ovn/env6/setup.sh

diff --git a/tutorial/OVN-Tutorial.md b/tutorial/OVN-Tutorial.md
index 4fc06eb..667b76b 100644
--- a/tutorial/OVN-Tutorial.md
+++ b/tutorial/OVN-Tutorial.md
@@ -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
@@ -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/
diff --git a/tutorial/automake.mk b/tutorial/automake.mk
index e86ef74..f41c406 100644
--- a/tutorial/automake.mk
+++ b/tutorial/automake.mk
@@ -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)
diff --git a/tutorial/ovn/env6/add-acls.sh b/tutorial/ovn/env6/add-acls.sh
new file mode 100755
index 0000000..74cf17b
--- /dev/null
+++ b/tutorial/ovn/env6/add-acls.sh
@@ -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
diff --git a/tutorial/ovn/env6/setup.sh b/tutorial/ovn/env6/setup.sh
new file mode 100755
index 0000000..78657e9
--- /dev/null
+++ b/tutorial/ovn/env6/setup.sh
@@ -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
-- 
2.5.0




More information about the dev mailing list