Message ID | 1446652412-13609-1-git-send-email-rbryant@redhat.com |
---|---|
State | Accepted |
Headers | show |
Thanks for writing this up Russell! I found super pedantic (possible) nit, but otherwise, this reads fine to me and was helpful in understanding how ACLs work. Thanks! Acked-by: Kyle Mestery <mestery@mestery.com> On Wed, Nov 4, 2015 at 9:53 AM, Russell Bryant <rbryant@redhat.com> wrote: > 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> > --- > 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. > To my eyes, looks like an extra space after "traffic" above, but it's super pedantic, so only re-spin if you need to for some other reason. :) > +* 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 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev >
On 11/04/2015 10:58 AM, Kyle Mestery wrote: > Thanks for writing this up Russell! I found super pedantic (possible) > nit, but otherwise, this reads fine to me and was helpful in > understanding how ACLs work. Thanks! > > Acked-by: Kyle Mestery <mestery@mestery.com <mailto:mestery@mestery.com>> Thanks for the review! I fixed the typo you pointed out and pushed this to master. > > On Wed, Nov 4, 2015 at 9:53 AM, Russell Bryant <rbryant@redhat.com > <mailto:rbryant@redhat.com>> wrote: > > 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 > <mailto:rbryant@redhat.com>> > --- > tutorial/OVN-Tutorial.md | 84 > +++++++++++++++++++++++++++++++++++++++++++ > tutorial/automake.mk <http://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. > > > To my eyes, looks like an extra space after "traffic" above, but it's > super pedantic, so only re-spin if you need to for some other reason. :) There is indeed an extra space there. I removed it.
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
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> --- 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