<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
</head>
<body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">
Hi all,<br>
<br>
Monday at 2000 UTC I held an IRC meeting for blueprint ovs-firewall-driver to discuss implementation choices with the community. Only a handful of people attended so I wanted to open the discussion to the mailing list. 
<div><br>
</div>
<div>(I’ve also uploaded this to the wiki <<a href="https://wiki.openstack.org/wiki/Neutron/blueprint_ovs-firewall-driver#Security_groups_extension_API_addition_discussion">https://wiki.openstack.org/wiki/Neutron/blueprint_ovs-firewall-driver#Security_groups_extension_API_addition_discussion</a>>.)<br>
<div><br>
</div>
<div>tl;dr: To implement a performant OVS-based security groups solution in Neutron today, source port matching is a required addition to the security groups extension API.<br>
<br>
<br>
=== Background ===<br>
<br>
In Open vSwitch today, there are two best practice options of implementing firewalls[1]:<br>
<br>
1. reflexive learn actions (available in OVS today)<br>
2. stateless ACLs with tcp_flags=ack (available in OVS git, to be released in v2.1.0 - early 2014[6])<br>
<br>
<br>
In the same e-mail thread[2], the tradeoffs between the two choices were discussed:<br>
<br>
- reflexive learning is not as performant as it cuts into how many flows a megaflow can wildcard, e.g. the less that can be wildcarded, the more OVS will have to hit userspace for flows<br>
<br>
- "Using the learn action is strictly more correct, since it's only allowing return traffic that's in response to traffic that was previously seen.  TCP flag matching allows reasonable megaflows, but just blocking on the SYN flags isn't as secure, since an
 attacker can get traffic through--they just can't initiate a new connection."<br>
<br>
My preferred implementation is 'stateless ACLs with tcp_flags=ack' to emulate stateful behavior (at least in TCP) because reflexive learning is not as performant.<br>
<br>
<br>
=== Discussion: why? ===<br>
<br>
Following through with the 'stateless ACLs with tcp_flags=ack' approach, UDP clients on the instance will need explicit security group rules to match source IP address and source port.<br>
<br>
Example 1. A remote UDP client connecting to an instance UDP server<br>
A. nw_src=$remote_ip, tp_src=random, nw_dst=$instance_ip, tp_dst=9987<br>
B. nw_src=$instance_ip, tp_src=9987, nw_dst=$remote_ip, tp_src=random </div>
<div><br>
</div>
<div>So, in the case of the instance being a UDP server and default security groups already allowing all egress, adding a rule to allow ingress on UDP destination port 9987 will behave as expected.<br>
<br>
</div>
<div>Example 2. An instance UDP client connecting to a remote UDP server<br>
C. nw_src=$instance_ip, tp_src=random, nw_dst=$remote_ip, tp_dst=9987<br>
D. nw_src=$remote_ip, tp_src=9987, nw_dst=$instance_ip, tp_dst=random</div>
<div><br>
</div>
<div>In the case of the instance being a UDP client and default security groups already allowing all egress, we will need a new security group rule to allow ingress from source port 9987 from the remote UDP server in a stateless firewall. This is different
 behavior than the iptables-based stateful firewall implementation because it is able to add the reverse flow in its state table for a specific timeout length when it initially sees flow C.</div>
<div><br>
So, in security groups, we will need an additional rule that will define flow D (remote UDP server’s IP address, UDP source port 9987, and of course the instance’s IP address). However, if you look at the security groups API as it is today[3], you will see
 there is no match for source port (tp_src), only destination port (—port-range-min, —port-range-max).<br>
<br>
<br>
=== Suggested change: how to fix it ===<br>
<br>
So, to solve the lack of source port information, I propose the following addition to the security groups extension API to allow a match on source port: —source-port-range-min, —source-port-range-max. I already have WIP patches uploaded for neutron[4] and python-neutronclient[5]
 implementing these suggested additions. The security groups RPC API already has a field for source-port-range-min and source-port-range-max so this change would only affect the DB and frontend API.<br>
<br>
<br>
I’m open to any and all feedback.<br>
<br>
Thanks,<br>
<br>
Amir Sadoughi<br>
<br>
<br>
[1] e-mail thread on ovs-discuss mailing list. <a href="http://openvswitch.org/pipermail/discuss/2013-December/012425.html">http://openvswitch.org/pipermail/discuss/2013-December/012425.html</a><br>
[2] <a href="http://openvswitch.org/pipermail/discuss/2013-December/012433.html">http://openvswitch.org/pipermail/discuss/2013-December/012433.html</a><br>
[3] <a href="http://paste.openstack.org/show/55103/">http://paste.openstack.org/show/55103/</a><br>
[4] <a href="https://review.openstack.org/#/c/62129/">https://review.openstack.org/#/c/62129/</a><br>
[5] <a href="https://review.openstack.org/#/c/62130/">https://review.openstack.org/#/c/62130/</a></div>
<div>[6] <a href="http://openvswitch.org/pipermail/discuss/2013-December/012457.html">http://openvswitch.org/pipermail/discuss/2013-December/012457.html</a></div>
</div>
</body>
</html>