<div dir="ltr">Hi devs,<div><br></div><div style>After some discussions and more thinking today, I'm including an updated proposal below. I have a more clear idea on how I see the IPsec gateways hooking into the virtual topology, I've elaborated on that and made the DTOs simpler and no longer require two gateways per connection. You can skip to the last section, the rest hasn't changed.</div>
<div style><br></div><div style><div><font face="courier new, monospace">Feature description</font></div><div><font face="courier new, monospace">-------------------</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">IPSec VPN setup compatible with AWS's VPC private gateway.</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">The setup should include redundancy/failover.</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">Amazon VPC connectivity (See [0])</font></div><div><font face="courier new, monospace">---------------------------------</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">Since want fail-over, we need Amazon's 'dynamically-routed' flavour of</font></div><div><font face="courier new, monospace">IPsec. This is what a fully redundant setup looks like:</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">                        ~~~~~~~~~~~~~~~~~~</font></div><div><font face="courier new, monospace">                        Amazon VPC Subnets</font></div>
<div><font face="courier new, monospace">                        ~~~~~~~~┬~~~~~~~~~</font></div><div><font face="courier new, monospace">                                │</font></div><div><font face="courier new, monospace">                           ┌────┴────┐</font></div>
<div><font face="courier new, monospace">                           ╎  GW-1   ╎</font></div><div><font face="courier new, monospace">                           └─┬─────┬─┘</font></div><div><font face="courier new, monospace">       link-local-address-A  ╎     ╎ link-local-address-B</font></div>
<div><font face="courier new, monospace">             BGP-instance-A  ╎     ╎ BGP-instance-B</font></div><div><font face="courier new, monospace">                             ╎     ╎ </font></div><div><font face="courier new, monospace">                         ┌───┘     └────┐</font></div>
<div><font face="courier new, monospace">                         ╎              ╎</font></div><div><font face="courier new, monospace">                    ┌────┴────┐    ┌────┴────┐</font></div><div><font face="courier new, monospace">                    ╎ IPsec-A ╎    ╎ IPsec-B ╎</font></div>
<div><font face="courier new, monospace">                    └────┬────┘    └────┬────┘</font></div><div><font face="courier new, monospace">        Public-Address-A ╎              ╎ Public-Address-B</font></div><div><font face="courier new, monospace">                         ╎              ╎</font></div>
<div><font face="courier new, monospace">                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</font></div><div><font face="courier new, monospace">                             Internet</font></div><div><font face="courier new, monospace">                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</font></div>
<div><font face="courier new, monospace">                         ╎              ╎</font></div><div><font face="courier new, monospace">        Public-Address-C ╎              ╎ Public-Address-D</font></div><div><font face="courier new, monospace">                    ┌────┴────┐    ┌────┴────┐</font></div>
<div><font face="courier new, monospace">                    ╎ IPsec-C ╎    ╎ IPsec-D ╎</font></div><div><font face="courier new, monospace">                    └────┬────┘    └────┬────┘</font></div><div><font face="courier new, monospace">                         ╎              ╎</font></div>
<div><font face="courier new, monospace">                         └───┐     ┌────┘</font></div><div><font face="courier new, monospace">                             ╎     ╎ </font></div><div><font face="courier new, monospace">             BGP-instance-C  ╎     ╎ BGP-instance-D</font></div>
<div><font face="courier new, monospace">       link-local-address-C  ╎     ╎ link-local-address-D</font></div><div><font face="courier new, monospace">                           ┌─┴─────┴─┐</font></div><div><font face="courier new, monospace">                           ╎  GW-2   ╎</font></div>
<div><font face="courier new, monospace">                           └────┬────┘</font></div><div><font face="courier new, monospace">                                ╎</font></div><div><font face="courier new, monospace">                        ~~~~~~~~┴~~~~~~~~~~</font></div>
<div><font face="courier new, monospace">                        Other cloud subnets</font></div><div><font face="courier new, monospace">                        ~~~~~~~~~~~~~~~~~~~</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">It works like this:</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">  - Two IPsec connections are established: IPsec-A - IPsec C, and</font></div>
<div><font face="courier new, monospace">    IPsec B - IPsec D respectively.</font></div><div><font face="courier new, monospace">  - For each IPsec connection pair (A-C, B-D) /30 network of link-local</font></div><div><font face="courier new, monospace">    addresses is reserved. These addresses (LLA-A,B,C and D) are locally</font></div>
<div><font face="courier new, monospace">    bound by each gateway behind the IPsec tunnels.</font></div><div><font face="courier new, monospace">  - At this point, with the tunnels established, GW-1's traffic</font></div>
<div><font face="courier new, monospace">    addressed to LLA-C will always take source address LLA-A and go</font></div><div><font face="courier new, monospace">    through the A-C tunnel. Both gateways can now run two BGP instances</font></div>
<div><font face="courier new, monospace">    each on the link-local-addresses, and packets between the subnets</font></div><div><font face="courier new, monospace">    behind each gateway can start to flow through either IPsec tunnel.</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">(implementation note below - skip to next section if not interested)</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">Note that on this setup IPsec instances need to accept and encrypt</font></div><div><font face="courier new, monospace">traffic from/to any network on either side, and they do not know that</font></div>
<div><font face="courier new, monospace">when they establish the tunnel. Because the Linux kernel ipsec</font></div><div><font face="courier new, monospace">implementation is policy based (you need Security Associations between</font></div>
<div><font face="courier new, monospace">each pair of subnets that may communicate through the tunnel) this poses</font></div><div><font face="courier new, monospace">a problem. It may be solved in two different ways (needs testing):</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">  - Statically add SA's localnet-0.0.0.0/0. Meaning that anytime the</font></div><div><font face="courier new, monospace">    IPsec instance sees a packet coming from one of the known local</font></div>
<div><font face="courier new, monospace">    networks the tuple of that network with <a href="http://0.0.0.0/0">0.0.0.0/0</a> will match and let</font></div><div><font face="courier new, monospace">    the traffic through. This may be just fine, as we will be fully in</font></div>
<div><font face="courier new, monospace">    control of what traffic makes it to the IPsec instance.</font></div><div><font face="courier new, monospace">  - Have the BGP instance notify the IPsec instance to add the SA's</font></div>
<div><font face="courier new, monospace">    dynamically. This is obviously more complicated, specially because</font></div><div><font face="courier new, monospace">    we are not talking about MM state but linux kernel state inside of a</font></div>
<div><font face="courier new, monospace">    VM.</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">Digression: about the CloudStack implementation</font></div><div>
<font face="courier new, monospace">-----------------------------------------------</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">See [1] for reference. CloudStack supports two types of crnnections:</font></div>
<div><font face="courier new, monospace">L2TP and site-to-site. L2TP is meant for single users, not gateways, and</font></div><div><font face="courier new, monospace">it tunnels l2tp packets make the user's machine be effectively in the</font></div>
<div><font face="courier new, monospace">chosen VPC L2 network segment. This mode does not concern us for now.</font></div><div><font face="courier new, monospace">Site-to-site VPNs in CloudStack appear to be old-fashioned policy based</font></div>
<div><font face="courier new, monospace">IPsec tunnels. The full list of remote subnets is needed to configure</font></div><div><font face="courier new, monospace">the connection and there's no mention of BGP.</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">However, CloudStack's site-to-site tunnels should still be compatible</font></div><div><font face="courier new, monospace">with Amazon, ...without failover. Amazon added support for statically-</font></div>
<div><font face="courier new, monospace">routed VPNs in September 2012 [2]. Seeing that Amazon extended their</font></div><div><font face="courier new, monospace">offering with this feature and that it's the only mode that CloudStack</font></div>
<div><font face="courier new, monospace">supports, it's probably worth considering supporting this mode too in</font></div><div><font face="courier new, monospace">Midonet.</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">Proposal for adding dynamically-routed IPsec to Midonet</font></div><div><font face="courier new, monospace">-------------------------------------------------------</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> - Configuration parameters. (REST API operations to be derived from</font></div><div><font face="courier new, monospace">   these). To setup a redundant IPsec VPN you need to provide:</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">    - Two public IPs to talk to the remote IPsec gateways.</font></div><div><font face="courier new, monospace">    - Public IPs for the gateways on the other side.</font></div>
<div><font face="courier new, monospace">    - Two private IPs to talk to a downstream virtual router.</font></div><div><font face="courier new, monospace">    - Two addresses in different /30 link-local subnets, for BGP.</font></div>
<div><font face="courier new, monospace">    - A virtual router. BGP will modify this router's routing table</font></div><div><font face="courier new, monospace">      and both IPsec gateways should be connected directly to this router.</font></div>
<div><font face="courier new, monospace">    - Local network ranges to advertise to the other side via BGP.</font></div><div><font face="courier new, monospace">    - IKE pre-shared key.</font></div><div><font face="courier new, monospace">    - IPsec connection parameters: PFS mode, hash function, encryption</font></div>
<div><font face="courier new, monospace">      function. Amazon is very strict on this, requiring exactly:</font></div><div><font face="courier new, monospace">      Group-2, SHA-1, AES-128. IMHO that's a correct philosophy,</font></div>
<div><font face="courier new, monospace">      sticking to the common minimum. If midonet is as strict as Amazon</font></div><div><font face="courier new, monospace">      the user doesn't need to supply this.</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> - The REST API would get the following new DTOs:</font></div><div><font face="courier new, monospace"><br></font></div><div>
<font face="courier new, monospace">    - IpsecGatewayDto (abstract)</font></div><div><font face="courier new, monospace">        - publicIp: IP address</font></div><div><font face="courier new, monospace">        - peerIp: IP address</font></div>
<div><font face="courier new, monospace">        - privateIp: IP address</font></div><div><font face="courier new, monospace">        - ikePsk: pre-shared-key for IKE exchange</font></div><div><font face="courier new, monospace">        - dhGroup: read-only or not present, always 2</font></div>
<div><font face="courier new, monospace">        - hashAlg: read-only or not present, always 'sha-1'</font></div><div><font face="courier new, monospace">        - cryptoAlg: read-only or not present, always aes128</font></div>
<div><font face="courier new, monospace">        - upPort: InteriorBridgePort, it's created automatically and</font></div><div><font face="courier new, monospace">          starts in unlinked state. DELETE is disallowed.</font></div>
<div><font face="courier new, monospace">        - downPort: InteriorBridgePort, it's created automatically and</font></div><div><font face="courier new, monospace">          starts in unlinked state. DELETE is disallowed.</font></div>
<div><font face="courier new, monospace">        - type (IpsecDynamic|IpsecStatic)</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">    - DynamicIpsecGatewayDto</font></div>
<div><font face="courier new, monospace">        - bgpLocalAsn</font></div><div><font face="courier new, monospace">        - bgpPeerAsn</font></div><div><font face="courier new, monospace">        - bgpLocalIp: link-local ip address</font></div>
<div><font face="courier new, monospace">        - bgpPeerIp:  localIp's /30 peer</font></div><div><font face="courier new, monospace">        - localSubnets: list of CIDR blocks to advertise</font></div><div><font face="courier new, monospace">        - virtualRouter: UUID of a virtual router</font></div>
<div><font face="courier new, monospace">        - type = IpsecDymamic</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">    - StaticIpsecGatewayDto (if/when midonet supports this)</font></div>
<div><font face="courier new, monospace">        - localSubnets: list of CIDR blocks</font></div><div><font face="courier new, monospace">        - remoteSubnets: list of CIDR blocks</font></div><div><font face="courier new, monospace">        - type = IpsecStatic</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> ...and one new top-level URL for the IpsecGatewayDto objects described</font></div><div><font face="courier new, monospace"> above (all other objects hang from it):</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">       - /ipsec_gateways?tenant_id=:tenantId - list a tenant's ipsec</font></div><div><font face="courier new, monospace">         gateways. ApplicationDto would get a new getIpsecGateways()</font></div>
<div><font face="courier new, monospace">         method.</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">       - /ipsec_gateways/:ipsec_id - URL for a IpsecGateway POST,DELETE,GET.</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> - The virtual topology would look like this to the user in a typical</font></div>
<div><font face="courier new, monospace">   setup. Note that the API would allow for the creation of just one</font></div><div><font face="courier new, monospace">   gateway or more than two for that matter. Also the up/down ports on</font></div>
<div><font face="courier new, monospace">   the IpsecGateway device can be connected anywhere in the virtual</font></div><div><font face="courier new, monospace">   topology:</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">                       ┌────────┐</font></div><div><font face="courier new, monospace">                       ╎  Prov. ├───────────┐</font></div><div><font face="courier new, monospace">                       ╎ Router ├──────────┐╎</font></div>
<div><font face="courier new, monospace">                       └────┬───┘          ╎╎ 2x IpsecGateway.upPort</font></div><div><font face="courier new, monospace">                            ╎       ┌──────┴────────────────┐       </font></div>
<div><font face="courier new, monospace">                            ╎       ╎ DynamicIpsecGateway** ╎┐ </font></div><div><font face="courier new, monospace">                            ╎       └┬─────┬────────────────┘╎ 2x</font></div>
<div><font face="courier new, monospace">                            ╎        └─────╎┬────────────────┘</font></div><div><font face="courier new, monospace">                            ╎              ╎╎ 2x IpsecGateway.downPort       </font></div>
<div><font face="courier new, monospace">                       ┌────┴───┐          ╎╎              </font></div><div><font face="courier new, monospace">   BGP injected ──────>╎ Tenant ├──────────┘╎</font></div><div><font face="courier new, monospace">       routes          ╎ Router ├───────────┘</font></div>
<div><font face="courier new, monospace">                       └──┬───┬─┘       </font></div><div><font face="courier new, monospace">                   ┌──────┘   └─────┐</font></div><div><font face="courier new, monospace">             ┌─────┴────┐     ┌─────┴────┐</font></div>
<div><font face="courier new, monospace">             ╎ Bridge-A ╎ ... ╎ Bridge-N ╎</font></div><div><font face="courier new, monospace">             └──────────┘     └──────────┘</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> ** each IPsec/BGP virtual device would expand to this:</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">                        DynamicIpsecGateway</font></div><div><font face="courier new, monospace">                      ┌------------------------------------------┐</font></div>
<div><font face="courier new, monospace">                      ╵                                          ╵</font></div><div><font face="courier new, monospace">               upPort ╵        ┌────────────┐                    ╵</font></div>
<div><font face="courier new, monospace"> (InteriorBridgePort) ╵        ╎  Upstream  ╎ ExteriorBridgePort ╵</font></div><div><font face="courier new, monospace">                ───────────────┤   Bridge   ├──────────┐         ╵</font></div>
<div><font face="courier new, monospace">                      ╵        └────────────┘          ╎         ╵</font></div><div><font face="courier new, monospace">                      ╵                                ╎publicIp ╵</font></div>
<div><font face="courier new, monospace">                      ╵                         ┌──────┴──────┐  ╵</font></div><div><font face="courier new, monospace">                      ╵                         ╎  IPsec/BGP  ╎  ╵</font></div>
<div><font face="courier new, monospace">                      ╵                         ╎ VM instance ╎  ╵</font></div><div><font face="courier new, monospace">                      ╵                         └──────┬──────┘  ╵</font></div>
<div><font face="courier new, monospace">             downPort ╵        ┌────────────┐          ╎privateIp╵</font></div><div><font face="courier new, monospace"> (InteriorBridgePort) ╵        ╎ Downstream ╎          ╎         ╵</font></div>
<div><font face="courier new, monospace">                ───────────────┤   Bridge   ├──────────┘         ╵</font></div><div><font face="courier new, monospace">                      ╵        └────────────┘ ExteriorBridgePort ╵</font></div>
<div><font face="courier new, monospace">                      ╵                                          ╵</font></div><div><font face="courier new, monospace">                      └------------------------------------------┘</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">Thus, this design proposes that several virtual devices would be</font></div><div><font face="courier new, monospace">aggregated to offer a single new virtual 'super-device'. In this case</font></div>
<div><font face="courier new, monospace">the sub-devices that make up this super-device should not be modifiable</font></div><div><font face="courier new, monospace">via API calls. A new property for virtual devices 'superDevice' (its</font></div>
<div><font face="courier new, monospace">value being the UUID of the parent super-device) could serve to mark</font></div><div><font face="courier new, monospace">which devices are read-only to the REST API.</font></div><div>
<font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">A second problem of this design is that an IpsecGateway offers two</font></div><div><font face="courier new, monospace">InteriorBridgePorts to the outside world. This is clearly a limitation</font></div>
<div><font face="courier new, monospace">for two reasons:</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">    a) they are interior (the anticipated scenario for an IPsec</font></div>
<div><font face="courier new, monospace">    gateway). This could be overcome but letting the API create the</font></div><div><font face="courier new, monospace">    upPort & downPort objects by POSTing a BridgePort of the desired</font></div>
<div><font face="courier new, monospace">    type.</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">    b) bridge ports cannot be connected to bridges. In the topology</font></div>
<div><font face="courier new, monospace">    shown above, it would make sense (for simplicity in the l3 setup)</font></div><div><font face="courier new, monospace">    to connect the downPorts of both IPsecGateways to a bridge and that</font></div>
<div><font face="courier new, monospace">    bridge to the tenant router. This is not possible with the proposed</font></div><div><font face="courier new, monospace">    IpsecGateway device.</font></div><div><font face="courier new, monospace">    One solution might be the substitution of the two bridges inside the</font></div>
<div><font face="courier new, monospace">    IPsecGateway for two new devices of a new kind, whose mission would</font></div><div><font face="courier new, monospace">    be act as dumb two-port bridge with an exterior port on one side and</font></div>
<div><font face="courier new, monospace">    an interior port (linkable to a bridge) on the other side.</font></div><div><font face="courier new, monospace">    A second solution would be to just offer to physical vif names that</font></div>
<div><font face="courier new, monospace">    could be bound to arbitrary exterior ports through API calls, as</font></div><div><font face="courier new, monospace">    opposed to offering the proposed upPort and downPort.</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">Links</font></div><div><font face="courier new, monospace">-----</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">[0] <a href="http://docs.aws.amazon.com/AmazonVPC/latest/NetworkAdminGuide/Introduction.html">http://docs.aws.amazon.com/AmazonVPC/latest/NetworkAdminGuide/Introduction.html</a></font></div>
<div><font face="courier new, monospace">[1] <a href="http://incubator.apache.org/cloudstack/docs/en-US/Apache_CloudStack/4.0.0-incubating/html/Admin_Guide/vpn.html#site-to-site-vpn">http://incubator.apache.org/cloudstack/docs/en-US/Apache_CloudStack/4.0.0-incubating/html/Admin_Guide/vpn.html#site-to-site-vpn</a></font></div>
<div><font face="courier new, monospace">[2] <a href="http://aws.typepad.com/aws/2012/09/amazon-vpc-additional-vpn-features.html">http://aws.typepad.com/aws/2012/09/amazon-vpc-additional-vpn-features.html</a></font></div>
<div><br></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Feb 13, 2013 at 12:22 PM, Guillermo Ontañón <span dir="ltr"><<a href="mailto:guillermo@midokura.jp" target="_blank">guillermo@midokura.jp</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Dan,<div><br></div><div>Good questions, my comments below...<br><div class="gmail_extra"><br><br><div class="gmail_quote">
<div class="im">On Wed, Feb 13, 2013 at 6:43 AM, Dan Mihai Dumitriu <span dir="ltr"><<a href="mailto:dan@midokura.com" target="_blank">dan@midokura.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Guillermo,<div><br></div><div>I was just about to send a message with a similar proposal, and you just beat me to it! :) This looks great.</div>

<div><br></div><div>There are a couple of points I want to raise.</div><div>

<br></div><div>- since one of our objectives is to connect a private cloud to an AWS VPC, is it correct that our IPSec VPN will have to run in client mode as well?  Actually, I don't know how this stuff is supposed to work.  Is one side a server and the other a client?  Or is the configuration of such a VPN symmetric?</div>

</blockquote><div><br></div></div><div>The configuration is symmetric, there's no server and client. Once set up, both IPsec gateways should try to contact the other (UDP port 500).</div><div class="im"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div>- for managing the IPSec instances, do we want to leverage the VMs of the cloud stack on top of which we're running?  We talked about running them in containers before.  I think I might be coming back around to thinking that VMs are the way to go. :) If the performance is good enough, something which has to be measured.  (CloudStack runs all services in VMs.)</div>

</blockquote><div><br></div></div><div>That's the biggest question we have, I was just discussing this with Abel. I don't have a final opinion yet, before I do want to do a real test with Amazon. Some thoughts:</div>

<div><br></div><div>  * Containers will not be possible if the IPsec SPDB is not per-container too. I haven't tried but have been unable to find anyone who has gotten it to work.</div><div>  * The downside of using a VM is maintaining the image with updates, etc.</div>

<div>  * A second downside of the VM is that we'd be redoing some of the work in the current BGP feature.</div><div>  * The upside of using a VM is very attractive to me: you have this black box with two ports that you can plug anywhere into the virtual topology. In this case we'd put BGP and IPsec in the VM, plugged to a tenant router on one side and to the provider router (or even a second port of the tenant router) on the other.</div>

<div>  * Unless we do a clever trick (connection through the datapath?) BGP and IPsec have to run in the same container/vm/whatever. Because when BGP sends packets out of its link-local-address the destination address is on the same ip subnet and on other side of the tunnel, so they have to be fed into the networking stack that has the IPsec SPDB. I mention this because Abel and I have been discussing ways of making the BGP and IPsec instances independent, reusing our current BGP setup.</div>
<div class="im">
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>- CloudStack already has an IPSec VPN in the router VM.  We just spoke yesterday about leveraging that to support the feature when running together with MN.  In order to add a BGP option, we have to extend the CS API itself.  To make this fault tolerant, we should probably prepare another image.</div>



<div><br></div><div>- On the OpenStack side, in order to consider this a complete feature, we also need to add APIs to quantum.  Does anyone know if there is any ongoing blueprint for a VPC feature?  In addition, we need to prepare a VM with the ipsec code and some agent that we can control from MN.  For the control connection between the MN agent and the agent in the VM, one way to go is to do as CloudStack does, that is to create another interface that is bridged to the host with a link local address. </div>

</blockquote><div><br></div></div><div>Sounds like we could create a VM base image with an extensible agent and VM-Midonet port that 3rd parties could build on.</div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


<div><br></div><div>Thoughts?</div><div><br></div><div>Cheers,</div><div>Dan</div><div><div><div><br></div><div><br><div class="gmail_quote">On Wed, Feb 13, 2013 at 2:41 AM, Guillermo Ontañón <span dir="ltr"><<a href="mailto:guillermo@midokura.jp" target="_blank">guillermo@midokura.jp</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr"><font face="courier new, monospace">Hello devs,<br><br>I'm including below my initial discussion about adding IPsec<br>support for midonet. It's still a bit rough but enough to<br>spark discussion. Some details (implementation related mostly)<br>




are still blurry, I'm going to discuss the BGP part with Abel<br>tomorrow and create a test setup connecting to Amazon to get<br>those details right.<br><br>Feature description<br>-------------------<br><br>IPSec VPN setup compatible with AWS's VPC private gateway.<br>




<br>The setup should include redundancy/failover.<br><br>Amazon VPC connectivity (See [0])<br>---------------------------------<br><br>Since want fail-over, we need Amazon's 'dynamically-routed' flavour of<br>




IPsec. This is what a fully redundant setup looks like:<br><br>                        ~~~~~~~~~~~~~~~~~~<br>                        Amazon VPC Subnets<br>                        ~~~~~~~~┬~~~~~~~~~<br>                                │<br>




                           ┌────┴────┐<br>                           ╎  GW-1   ╎<br>                           └─┬─────┬─┘<br>       link-local-address-A  ╎     ╎ link-local-address-B<br>             BGP-instance-A  ╎     ╎ BGP-instance-B<br>




                             ╎     ╎ <br>                         ┌───┘     └────┐<br>                         ╎              ╎<br>                    ┌────┴────┐    ┌────┴────┐<br>                    ╎ IPsec-A ╎    ╎ IPsec-B ╎<br>




                    └────┬────┘    └────┬────┘<br>        Public-Address-A ╎              ╎ Public-Address-B<br>                         ╎              ╎<br>                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>                             Internet<br>




                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>                         ╎              ╎<br>        Public-Address-C ╎              ╎ Public-Address-D<br>                    ┌────┴────┐    ┌────┴────┐<br>                    ╎ IPsec-C ╎    ╎ IPsec-D ╎<br>




                    └────┬────┘    └────┬────┘<br>                         ╎              ╎<br>                         └───┐     ┌────┘<br>                             ╎     ╎ <br>             BGP-instance-C  ╎     ╎ BGP-instance-D<br>




       link-local-address-C  ╎     ╎ link-local-address-D<br>                           ┌─┴─────┴─┐<br>                           ╎  GW-2   ╎<br>                           └────┬────┘<br>                                ╎<br>




                        ~~~~~~~~┴~~~~~~~~~~<br>                        Other cloud subnets<br>                        ~~~~~~~~~~~~~~~~~~~<br><br>It works like this:<br><br>  - Two IPsec connections are established: IPsec-A - IPsec C, and<br>




    IPsec B - IPsec D respectively.<br>  - For each IPsec connection pair (A-C, B-D) /30 network of link-local<br>    addresses is reserved. These addresses (LLA-A,B,C and D) are locally<br>    bound by each gateway behind the IPsec tunnels.<br>




  - At this point, with the tunnels established, GW-1's traffic<br>    addressed to LLA-C will always take source address LLA-A and go<br>    through the A-C tunnel. Both gateways can now run two BGP instances<br>    each on the link-local-addresses, and packets between the subnets<br>




    behind each gateway can start to flow through either IPsec tunnel.<br><br>(implementation note below - skip to next section if not interested)<br><br>Note that on this setup IPsec instances need to accept and encrypt<br>




traffic from/to any network on either side, and they do not know that<br>when they establish the tunnel. Because the Linux kernel ipsec<br>implementation is policy based (you need Security Associations between<br>each pair of subnets that may communicate through the tunnel) this poses<br>




a problem. It may be solved in two different ways (needs testing):<br><br>  - Statically add SA's localnet-0.0.0.0/0. Meaning that anytime the<br>    IPsec instance sees a packet coming from one of the known local<br>




    networks the tuple of that network with <a href="http://0.0.0.0/0" target="_blank">0.0.0.0/0</a> will match and let<br>    the traffic through. This may be just fine, as we will be fully in<br>    control of what traffic makes it to the IPsec instance.<br>




  - Have the BGP instance notify the IPsec instance to add the SA's<br>    dynamically. This is obviously more complicated, specially because<br>    we are not talking about MM state but linux kernel state inside of a<br>




    VM.<br><br>Digression: about the CloudStack implementation<br>-----------------------------------------------<br><br>See [1] for reference. CloudStack supports two types of crnnections:<br>L2TP and site-to-site. L2TP is meant for single users, not gateways, and<br>




it tunnels l2tp packets make the user's machine be effectively in the<br>chosen VPC L2 network segment. This mode does not concern us for now.<br>Site-to-site VPNs in CloudStack appear to be old-fashioned policy based<br>




IPsec tunnels. The full list of remote subnets is needed to configure<br>the connection and there's no mention of BGP.<br><br>However, CloudStack's site-to-site tunnels should still be compatible<br>with Amazon, ...without failover. Amazon added support for statically-<br>




routed VPNs in September 2012 [2]. Seeing that Amazon extended their<br>offering with this feature and that it's the only mode that CloudStack<br>supports, it's probably worth considering supporting this mode too in<br>




Midonet.<br><br>Proposal for adding dynamically-routed IPsec to Midonet<br>-------------------------------------------------------<br><br> - Configuration parameters. (REST API operations to be derived from<br>   these). To setup a redundant IPsec VPN you need to provide:<br>




<br>    - Two public IPs<br>    - Two addresses in different /30 link-local subnets, for BGP.<br>    - A virtual router. BGP will modify this router's routing table<br>      and both IPsec gateways will be connected directly to this router.<br>




      User-visible parameters related to this connection to the virtual<br>      router should be kept to a minimum. It's not yet clear how the<br>      ipsec instances and bgp will be plugged to the vrouter.<br>    - Public IPs for the gateways on the other side.<br>




    - Local network ranges to advertise to the other side via BGP.<br>    - IKE pre-shared key.<br>    - IPsec connection parameters: PFS mode, hash function, encryption<br>      function. Amazon is very strict on this, requiring exactly:<br>




      Group-2, SHA-1, AES-128. IMHO that's a correct philosophy,<br>      sticking to the common minimum. If midonet is as strict as Amazon<br>      the user doesn't need to supply this.<br><br> - This a sketch of what new REST API DTOs there would be:<br>




    - IpsecPairingDto. With fields:<br>        - publicIp<br>        - peerIp<br>        - dhGroup (read-only if only 2 is allowed)<br>        - hashAlg (read-only if only sha-1 is allowed)<br>        - cryptoAlg (read-only if only aes128 is allowed)<br>




    - BgpIpsecPairingDto. Fields:<br>        - localAsn<br>        - remoteAsn<br>        - localIp (must be link-local)<br>        - peerIp (must be in the same /30 network as localIp, it could<br>          be inferred from it)<br>




    - DynamicVpnDto<br>        - virtualRouter<br>        - ipsecPairingA<br>        - ipsecPairingB<br>        - bgpPairingA<br>        - bgpPairingB<br>        - localSubnets<br>    - StaticVpnDto (when/if midonet supports this type of connection)<br>




        - ipsecPairing<br>        - localSubnets<br>        - remoteSubnets<br><br> - The virtual topology would look like this to the user:<br><br>                                          ╎ Public IP (interior vport)                           <br>




                                    ┌─────┴────┐ <br>                            ╵       ╎ IPsec VM ╎ X 2<br>                            ╵       ╎ instance ╎<br>                            ╵       └─────┬────┘<br>                       ┌────┴───┐         ╎<br>




   BGP injected ──────>╎ Tenant ╎         ╎<br>       routes          ╎ Router ├─────────┘<br>                       └──┬───┬─┘<br>                   ┌──────┘   └─────┐<br>             ┌─────┴────┐     ┌─────┴────┐<br>




             ╎ Bridge-A ╎ ... ╎ Bridge-N ╎<br>             └──────────┘     └──────────┘<br><br><br>Links<br>-----<br><br>[0] <a href="http://docs.aws.amazon.com/AmazonVPC/latest/NetworkAdminGuide/Introduction.html" target="_blank">http://docs.aws.amazon.com/AmazonVPC/latest/NetworkAdminGuide/Introduction.html</a><br>




[1] <a href="http://incubator.apache.org/cloudstack/docs/en-US/Apache_CloudStack/4.0.0-incubating/html/Admin_Guide/vpn.html#site-to-site-vpn" target="_blank">http://incubator.apache.org/cloudstack/docs/en-US/Apache_CloudStack/4.0.0-incubating/html/Admin_Guide/vpn.html#site-to-site-vpn</a><br>




[2] <a href="http://aws.typepad.com/aws/2012/09/amazon-vpc-additional-vpn-features.html" target="_blank">http://aws.typepad.com/aws/2012/09/amazon-vpc-additional-vpn-features.html</a><br><br><br><br>Regards,<br><br>-- Guillermo Ontañón</font><br>




</div>
</blockquote></div><br></div>
</div></div></blockquote></div></div></div><span class="HOEnZb"><font color="#888888"><br><br clear="all"><div><br></div>-- <br><div dir="ltr">-- Guillermo Ontañón</div>
</font></span></div></div></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div dir="ltr">-- Guillermo Ontañón</div>
</div>