Virtual private networks

VPN as a Service is an OpenStack networking extension that provides VPN services for your project. Currently this service is restricted to IPsec based VPNs.

A worked example

In the following examples we will construct a VPN between the Hamilton region (nz-hlz-1) and the Porirua region (nz-por-1) of our project. We will assume that in both regions we have an identical network setup that looks like:

  • A network called private-net.

  • A subnet called private-subnet.

  • A router to the internet called border-router.

The only differences between the two setups will be the external IP address on the router and the CIDR of the private subnets.

We will illustrate how to create the the VPN using the following approaches:

  • Using the Openstack command line tools.

  • With a bash script.

  • From the cloud dashboard

Requirements

In order to set up a VPN, we need to identify some key information:

  • Router name

  • Router IP address

  • Subnet name

  • Subnet CIDR range

  • Remote peer router IP

  • Remote peer subnet CIDR range

  • A secret pre shared key

While we will be using the names of the router and subnet it is important to note that these are not required to be unique so if your creating multiple VPN connections it may be more appropriate to use the UUID values for these elements in order to avoid ambiguity when running commands.

Note

IPSec relies on symmetrical encryption where both sides use the same private key. This key is known as a Pre Shared Key (PSK). You should ensure that you manage this key appropriately, so for example be sure that it is not committed to your configuration management system source control in plain text.

Warning

The Pre Shared Key should be between 20 to 40 characters long and consist of alphanumeric characters only. The Pre Shared Key must not contain the ‘&’ character.

The first thing we need to do prior to creating our VPN is to gather the relevant information, as mentioned above, for our existing network elements. We will create the first half of our VPN in the Hamilton region.

To get the subnet’s CIDR run the following command.

$ echo $OS_REGION_NAME
nz-hlz-1

$ openstack subnet list --name private-subnet -c Name -f value -c Subnet -f value -c ID -f value  -f table
+--------------------------------------+----------------+-------------+
| ID                                   | Name           | Subnet      |
+--------------------------------------+----------------+-------------+
| 1d701353-f120-413d-b33f-xxxxxxxxxxxx | private-subnet | 10.0.0.0/24 |
+--------------------------------------+----------------+-------------+

Next let’s find the required router information.

$ openstack router show border-router -c id -f value -c external_gateway_info -f value -f json
{
  "external_gateway_info": {
    "network_id": "993e826c-74c2-4b44-ad6f-xxxxxxxxxxxx",
    "enable_snat": true,
    "external_fixed_ips": [
      {
        "subnet_id": "f44f9716-a08c-4972-909d-xxxxxxxxxxxx",
        "ip_address": "10.10.8.3"
      },
      {
        "subnet_id": "7cae5aac-2d01-4cba-a171-xxxxxxxxxxxx",
        "ip_address": "2404:130:4040:8::16"
      }
    ]
  },
  "id": "ddd82b49-8bae-4a25-ae94-xxxxxxxxxxxx"
}

From the JSON data, the router IP address is the IPv4 value associated with the ip_address key within the external_gateway_info.

As we are creating a VPN that connects our Catalyst Cloud project across two regions, the remote peer router IP and remote peer subnet CIDR range will be the values associated with the subnet and router in the other region.

In this case we need to find the router IP and the subnet CIDR from the network located in the Porirua region. You can determine these in the same way as shown above while connected to the other region.

$ echo $OS_REGION_NAME
nz-por-1

$ openstack subnet list --name private-subnet -c Name -f value -c Subnet -f value -f table
+----------------+---------------+
| Name           | Subnet        |
+----------------+---------------+
| private-subnet | 10.20.30.0/24 |
+----------------+---------------+


$ openstack router show border-router -c external_gateway_info -f value -c interfaces_info -f value -f json
{
  "external_gateway_info": {
    "network_id": "849ab1e9-7ac5-4618-8801-xxxxxxxxxxxx",
    "enable_snat": true,
    "external_fixed_ips": [
      {
        "subnet_id": "aef23c7c-6c53-4157-8350-xxxxxxxxxxxx",
        "ip_address": "150.242.40.137"
      },
      {
        "subnet_id": "e8064b07-ac94-4172-91a1-xxxxxxxxxxxx",
        "ip_address": "2404:130:4020:8000::7637"
      }
    ]
  }
}

The values we need from the above output are:

  • remote peer router IP : 150.242.40.137

  • remote peer subnet CIDR : 10.20.30.0/24

If you are setting up a VPN to a different peer, then the remote peer router IP will be the publicly accessible IPv4 address of that router, while the remote peer subnet CIDR range will be the subnet behind that router whose traffic you wish to route via the VPN to access the local subnet.

Note

If you are connecting to a remote peer that is not a Catalyst Cloud router, you may need to modify some of the parameters used in the following steps.

By now you should have the required values so you can proceed to create a VPN.

There are four steps to creating a VPN:

  • Create a VPN Service

  • Create a VPN IKE Policy

  • Create a VPN IPSec Policy

  • Create a VPN Endpoint Group for the local subnet

  • Create a VPN Endpoint Group for the peer CIDR

  • Create a VPN IPSec Site Connection

This example will cover setting up one half of the VPN in the Hamilton region.

First let’s create a VPN Service called vpn_service.

$ openstack vpn service create \
--router border-router \
vpn_service
+----------------+--------------------------------------+
| Field          | Value                                |
+----------------+--------------------------------------+
| Description    |                                      |
| ID             | 99d8f06c-8cd8-44d6-9337-xxxxxxxxxxxx |
| Name           | vpn_service                          |
| Project        | 630116938c82479cxxxxxx3912c1d09c     |
| Router         | ddd82b49-8bae-4a25-ae94-xxxxxxxxxxxx |
| State          | True                                 |
| Status         | PENDING_CREATE                       |
| Subnet         | None                                 |
| external_v4_ip | 10.10.8.3                            |
| external_v6_ip | 2404:130:4040:8::16                  |
| project_id     | 630116938c82479cxxxxxx3912c1d09c     |
+----------------+--------------------------------------+

Then create a VPN IKE policy called ike_policy.

$ openstack vpn ike policy create \
--auth-algorithm sha1 \
--encryption-algorithm aes-256 \
--phase1-negotiation-mode main \
--pfs group14 \
--ike-version v1 \
--lifetime units=seconds,value=14400 \
ike_policy
+-------------------------------+--------------------------------------+
| Field                         | Value                                |
+-------------------------------+--------------------------------------+
| Authentication Algorithm      | sha1                                 |
| Description                   |                                      |
| Encryption Algorithm          | aes-256                              |
| ID                            | d64b4355-576f-4f68-989d-xxxxxxxxxxxx |
| IKE Version                   | v1                                   |
| Lifetime                      | {'units': 'seconds', 'value': 14400} |
| Name                          | ike_policy                           |
| Perfect Forward Secrecy (PFS) | group14                              |
| Phase1 Negotiation Mode       | main                                 |
| Project                       | 630116938c82479cxxxxxx3912c1d09c     |
| project_id                    | 630116938c82479cxxxxxx3912c1d09c     |
+-------------------------------+--------------------------------------+

Then create a VPN IPSec policy called ipsec_policy.

$ openstack vpn ipsec policy create \
--transform-protocol esp \
--auth-algorithm sha1 \
--encryption-algorithm aes-256 \
--encapsulation-mode tunnel \
--pfs group14 \
--lifetime units=seconds,value=3600 \
ipsec_policy
+-------------------------------+--------------------------------------+
| Field                         | Value                                |
+-------------------------------+--------------------------------------+
| Authentication Algorithm      | sha1                                 |
| Description                   |                                      |
| Encapsulation Mode            | tunnel                               |
| Encryption Algorithm          | aes-256                              |
| ID                            | 54367ef5-9e76-4827-888e-xxxxxxxxxxxx |
| Lifetime                      | {'units': 'seconds', 'value': 3600}  |
| Name                          | ipsec_policy                         |
| Perfect Forward Secrecy (PFS) | group14                              |
| Project                       | 630116938c82479cxxxxxx3912c1d09c     |
| Transform Protocol            | esp                                  |
| project_id                    | 630116938c82479cxxxxxx3912c1d09c     |
+-------------------------------+--------------------------------------+

Then create an Endpoint Group for the local subnet called local_endpoint_group.

 $ openstack vpn endpoint group create --type subnet --value private-subnet local_endpoint_group
 +-------------+------------------------------------------+
 | Field       | Value                                    |
 +-------------+------------------------------------------+
 | Description |                                          |
 | Endpoints   | ['1d701353-f120-413d-b33f-xxxxxxxxxxxx'] |
 | ID          | 5d972e8d-e7a0-45ea-8d91-xxxxxxxxxxxx     |
 | Name        | local_endpoint_group                     |
 | Project     | 630116938c82479cxxxxxx3912c1d09c         |
 | Type        | subnet                                   |
 | project_id  | 630116938c82479cxxxxxx3912c1d09c         |
 +-------------+------------------------------------------+

Then create an Endpoint Group for the remote peer CIDR called *peer_endppoint_group*.
$ openstack vpn endpoint group create --type cidr --value 10.20.30.0/24 peer_endpoint_group
+-------------+--------------------------------------+
| Field       | Value                                |
+-------------+--------------------------------------+
| Description |                                      |
| Endpoints   | ['10.20.30.0/24']                    |
| ID          | f34578dc-aae8-4c02-abeb-xxxxxxxxxxxx |
| Name        | peer_endpoint_group                  |
| Project     | 630116938c82479cxxxxxx3912c1d09c     |
| Type        | cidr                                 |
| project_id  | 630116938c82479cxxxxxx3912c1d09c     |
+-------------+--------------------------------------+

Note

You can provide multiple --value arguments if you want to tunnel more than one CIDR range.

Finally we create a VPN IPSec site connection called vpn_site_connection. This command makes use of the resources created in the last five steps.

$ openstack vpn ipsec site connection create \
--initiator bi-directional \
--vpnservice vpn_service \
--ikepolicy ike_policy \
--ipsecpolicy ipsec_policy \
--dpd action=restart,interval=15,timeout=150 \
--peer-address 150.242.40.137 \
--peer-id 150.242.40.137 \
--local-endpoint-group local_endpoint_group \
--peer-endpoint-group peer_endpoint_group \
--psk supersecretpsk \
vpn_site_connection
+--------------------------+-------------------------------------------------------+
| Field                    | Value                                                 |
+--------------------------+-------------------------------------------------------+
| Authentication Algorithm | psk                                                   |
| Description              |                                                       |
| ID                       | 8b47f318-d91a-4040-9156-xxxxxxxxxxxx                  |
| IKE Policy               | d64b4355-576f-4f68-989d-xxxxxxxxxxxx                  |
| IPSec Policy             | 54367ef5-9e76-4827-888e-xxxxxxxxxxxx                  |
| Initiator                | bi-directional                                        |
| Local Endpoint Group ID  | 5d972e8d-e7a0-45ea-8d91-xxxxxxxxxxxx                  |
| Local ID                 |                                                       |
| MTU                      | 1500                                                  |
| Name                     | vpn_site_connection                                   |
| Peer Address             | 150.242.40.137                                        |
| Peer CIDRs               |                                                       |
| Peer Endpoint Group ID   | f34578dc-aae8-4c02-abeb-xxxxxxxxxxxx                  |
| Peer ID                  | 150.242.40.137                                        |
| Pre-shared Key           | supersecretpsk                                        |
| Project                  | 630116938c82479cxxxxxx3912c1d09c                      |
| Route Mode               | static                                                |
| State                    | True                                                  |
| Status                   | PENDING_CREATE                                        |
| VPN Service              | 99d8f06c-8cd8-44d6-9337-xxxxxxxxxxxx                  |
| dpd                      | {'action': 'restart', 'interval': 15, 'timeout': 150} |
| project_id               | 630116938c82479cxxxxxx3912c1d09c                      |
+--------------------------+-------------------------------------------------------+

You have now stood up one end of the VPN. This process should be repeated at the other end using the same configuration options and PSK. Once both sides of the VPN are configured, the peers should automatically detect each other and bring up the VPN. When the VPN is up, the status will change to ACTIVE.

Creating multiple VPN connections

There are situations where you may need multiple VPNs to your Catalyst Cloud project, for example if you have offices in two locations and need VPNs from both to connect into your project.

To create another VPN to your Catalyst Cloud project you can create another IPsec Site Connection under the same VPN Service by following these steps:

  • Create a VPN IKE Policy (if your new VPN needs a different policy)

  • Create a VPN IPSec Policy (if required)

  • Create a VPN Endpoint Group for the peer CIDR

  • Create a VPN IPSec Site Connection that uses the existing VPN Service

You should now have two VPN Connections running on the same Router.

../_images/vpn-connection-multiple.png

Warning

A Router can only support one VPN Service. If you add additional VPN Services to the same router then the existing VPN Service will go down.

Troubleshooting a VPN connection

If your VPN connection fails to become active then we suggest using the following check list:

  • Check that the settings in the IKE Policy match at your local end and in Catalyst Cloud

  • Check that the settings in the IPSec Policy match at your local end and in Catalyst Cloud

  • Check that the pre-shared key matches at both ends

  • Check that the firewall at your end allows UDP traffic on ports 500 and 4500