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.
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
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.
The Catalyst Cloud team have created a bash script that simplifies the procedure for creating a VPN. In order to run the script you will need to know the following information for each region you will be creating a VPN endpoint for. Details on how to obtain this information can be found in the Command Line example.
router name
router external IP address
subnet name
subnet CIDR range
This script will require no modification when setting up region to region VPNs. If you are using it to connect a Catalyst Cloud router to a non Catalyst Cloud router, you may need to change some configuration options.
This script currently only supports single CIDR ranges. If you are wanting to tunnel multiple ranges then it will require some modification.
You can download the latest version of this script using the following command:
$ wget https://raw.githubusercontent.com/catalyst-cloud/catalystcloud-docs/master/source/network/_scripts/create-vpn.sh Below is an example of the script being used to create a region to region VPN on Catalyst Cloud: ./create-vpn.sh ---------------------------------------------------------- This script will setup a VPN in your project. You can select either: a single region that will connect to an external site or a site-to-site vpn between 2 regions for the same project ---------------------------------------------------------- 1) single 2) site-to-site Select the VPN option you require or type 'q' to quit: 2 ------------------------------------------------------- Select the regions for your site-to-site VPN endpoints ------------------------------------------------------- 1) Hamilton 2) Porirua 3) Wellington Select region 1 for the site-to-site VPN or type 'q' to quit: 1 1) Hamilton 2) Porirua 3) Wellington Select region 2 for the site-to-site VPN or type 'q' to quit: 2 Please enter the name of your Hamilton router: border-router Please enter the name of your Hamilton subnet: private-subnet nz-por-1 Please enter the name of your Porirua router: border-router Please enter the name of your Porirua subnet: private-subnet Please enter your pre shared key: supersecretkey Please enter the Hamilton router ip address 103.197.61.206 Please enter the Hamilton CIDR range 192.168.3.0/24 Please enter the Porirua router ip address 150.242.41.251 Please enter the Porirua CIDR range 192.168.2.0/24 -------------------------------------------------------- Proceeding to create VPN with the following credentials: Region name = Hamilton region_1_router_name = border-router region_1_subnet_name = private-subnet region_1_router_ip = 103.197.61.206 region_1_subnet = 192.168.3.0/24 region_1_peer_router_ip = 150.242.41.251 region_1_peer_subnet = 192.168.2.0/24 Region name = Porirua region_2_router_name = border-router region_2_subnet_name = private-subnet region_2_router_ip = 150.242.41.251 region_2_subnet = 192.168.2.0/24 region_2_peer_router_ip = 103.197.61.206 region_2_peer_subnet = 192.168.3.0/24 pre_shared_key = supersecretkey -------------------------------------------------------- creating endpoint for Hamilton +----------------+--------------------------------------+ | Field | Value | +----------------+--------------------------------------+ | Description | | | ID | 4c5faf25-dada-44c7-a7d4-xxxxxxxxxxxx | | Name | vpn_service | | Project | 83100bf293c94607xxxxxxa959ac0218 | | Router | 34ea00e7-74bc-4f9f-b270-xxxxxxxxxxxx | | State | True | | Status | PENDING_CREATE | | Subnet | 5ea2199a-1a1e-40c5-a4cd-xxxxxxxxxxxx | | external_v4_ip | 103.197.61.206 | | external_v6_ip | 2404:130:8020:8000::2:ce58 | +----------------+--------------------------------------+ +-------------------------------+--------------------------------------+ | Field | Value | +-------------------------------+--------------------------------------+ | Authentication Algorithm | sha1 | | Description | | | Encryption Algorithm | aes-256 | | ID | ceebee2c-f5ac-44fa-a838-xxxxxxxxxxxx | | IKE Version | v1 | | Lifetime | {'units': 'seconds', 'value': 14400} | | Name | ike_policy | | Perfect Forward Secrecy (PFS) | group14 | | Phase1 Negotiation Mode | main | | Project | 83100bf293c94607xxxxxxa959ac0218 | +-------------------------------+--------------------------------------+ +-------------------------------+--------------------------------------+ | Field | Value | +-------------------------------+--------------------------------------+ | Authentication Algorithm | sha1 | | Description | | | Encapsulation Mode | tunnel | | Encryption Algorithm | aes-256 | | ID | 77c66397-43e9-45db-b0cd-xxxxxxxxxxxx | | Lifetime | {'units': 'seconds', 'value': 3600} | | Name | ipsec_policy | | Perfect Forward Secrecy (PFS) | group14 | | Project | 83100bf293c94607xxxxxxa959ac0218 | | Transform Protocol | esp | +-------------------------------+--------------------------------------+ +----------------+--------------------------------------+ | Field | Value | +----------------+--------------------------------------+ | Description | | | ID | 84303467-9c62-47c7-91c9-xxxxxxxxxxxx | | Name | vpn_service | | Project | 83100bf293c94607xxxxxxa959ac0218 | | Router | d570c9c8-bde2-4f39-8fa9-xxxxxxxxxxxx | | State | True | | Status | PENDING_CREATE | | Subnet | 55c57cd5-1b94-4098-9cf6-xxxxxxxxxxxx | | external_v4_ip | 150.242.41.251 | | external_v6_ip | 2404:130:4020:8000::1:9c3a | +----------------+--------------------------------------+ +-------------------------------+--------------------------------------+ | Field | Value | +-------------------------------+--------------------------------------+ | Authentication Algorithm | sha1 | | Description | | | Encryption Algorithm | aes-256 | | ID | a184e4c4-856f-4136-9ef1-xxxxxxxxxxxx | | IKE Version | v1 | | Lifetime | {'units': 'seconds', 'value': 14400} | | Name | ike_policy | | Perfect Forward Secrecy (PFS) | group14 | | Phase1 Negotiation Mode | main | | Project | 83100bf293c94607xxxxxxa959ac0218 | +-------------------------------+--------------------------------------+ +-------------------------------+--------------------------------------+ | Field | Value | +-------------------------------+--------------------------------------+ | Authentication Algorithm | sha1 | | Description | | | Encapsulation Mode | tunnel | | Encryption Algorithm | aes-256 | | ID | 9b41de10-194d-4e1d-9f2a-xxxxxxxxxxxx | | Lifetime | {'units': 'seconds', 'value': 3600} | | Name | ipsec_policy | | Perfect Forward Secrecy (PFS) | group14 | | Project | 83100bf293c94607xxxxxxa959ac0218 | | Transform Protocol | esp | +-------------------------------+--------------------------------------+ +--------------------------+-------------------------------------------------------+ | Field | Value | +--------------------------+-------------------------------------------------------+ | Authentication Algorithm | psk | | Description | | | ID | 1521242f-7d63-43b7-aa62-xxxxxxxxxxxx | | IKE Policy | a184e4c4-856f-4136-9ef1-xxxxxxxxxxxx | | IPSec Policy | 9b41de10-194d-4e1d-9f2a-xxxxxxxxxxxx | | Initiator | bi-directional | | MTU | 1500 | | Name | vpn_site_connection | | Peer Address | 103.197.61.206 | | Peer CIDRs | 192.168.3.0/24 | | Peer ID | 103.197.61.206 | | Pre-shared Key | pre_shared_key | | Project | 83100bf293c94607xxxxxxa959ac0218 | | Route Mode | static | | State | True | | Status | PENDING_CREATE | | VPN Service | 84303467-9c62-47c7-91c9-xxxxxxxxxxxx | | dpd | {'action': 'restart', 'interval': 15, 'timeout': 150} | +--------------------------+-------------------------------------------------------+ Your VPN has been created, note that you will need to create appropriate security group rules.
The script source is included below for reference:
#!/bin/bash #------------------------------------------------------------------------------ # Parameters #------------------------------------------------------------------------------ # set the default VPN creation mode DEFAULT_MENU_PROMPT="Select the option you require or type 'q' to quit: " ARR_REGIONS=(Hamilton Porirua) VPN_MODE="" REGION_1="" REGION_2="" # colour data for message prompt GREEN="\033[92m" # for success output YELLOW="\033[93m" # for debug output RED="\033[91m" # for error output NC='\033[0m' # remove colour from output #------------------------------------------------------------------------------ # Functions #------------------------------------------------------------------------------ usage() { echo cat <<USAGE_DOC Usage: ./$(basename $0) [-h] This script will assist in the creation of a VPN endpoint or endpoints on Catalyst Cloud. The default behaviour is to create a single VPN endpoint using the selected region. -h Print this usage guide USAGE_DOC } parse_args(){ while getopts mh OPTION; do case "$OPTION" in # m) # # build a VPN between two regions of a cloud project # MODE="multi" # ;; h) usage exit 0 ;; ?) usage exit 1 ;; esac done } handle_interruptions() { exit 130 } check_credentials() { # Look for $OS_* environment variables. If not defined, prompt the user to source # their OpenRC file if [[ ${OS_PROJECT_ID} && ${OS_TOKEN} ]] || [[ ${OS_USERNAME} && ${OS_PASSWORD} && ${OS_PROJECT_ID} ]]; then OPENRC="True" else MSG="No cloud credentials found in the current shell session, please source your openrc file." echo -e "${RED}${MSG}${NC}" exit 1 fi } create_menu() { MENU_PROMPT="${1}" shift arrsize=$1 shift arr=$1 ret_val="" PS3="${MENU_PROMPT}" select option in "${@}" do if [ "$REPLY" == "q" ] || [ "$REPLY" == "Q" ] then echo "Exiting..." break; elif [ 1 -le "$REPLY" ] && [ "$REPLY" -le $((arrsize)) ] then # echo "You have selected : $option" echo ret_val=$option break; else echo "Incorrect Input: Select a number 1-$arrsize" fi done } get_vpn_choice() { echo "----------------------------------------------------------" echo " This script will setup a VPN in your project." echo " You can select either:" echo " a single region that will connect to an external site" echo " or" echo " a site-to-site vpn between 2 regions for the same project" echo "----------------------------------------------------------" echo myarray=(single site-to-site) MENU_PROMPT="Select the VPN option you require or type 'q' to quit: " create_menu "${MENU_PROMPT}" ${#myarray[@]} ${myarray[@]} VPN_MODE=$ret_val } get_vpn_region() { if [ $VPN_MODE == "single" ] then echo "----------------------------------------" echo " Select the region for your VPN endpoint" echo "----------------------------------------" echo MENU_PROMPT="Select the VPN option you require or type 'q' to quit: " create_menu "${MENU_PROMPT}" ${#ARR_REGIONS[@]} ${ARR_REGIONS[@]} REGION_1=$ret_val elif [ $VPN_MODE == "site-to-site" ] then echo "-------------------------------------------------------" echo " Select the regions for your site-to-site VPN endpoints" echo "-------------------------------------------------------" echo EXIT="false" while [ $EXIT == "false" ] do for i in 1 2 do MENU_PROMPT="Select region $i for the site-to-site VPN or type 'q' to quit: " create_menu "${MENU_PROMPT}" ${#ARR_REGIONS[@]} ${ARR_REGIONS[@]} eval REGION_${i}=$ret_val if [ $REGION_2 ] then if [ $REGION_1 != $REGION_2 ] then EXIT="true" else echo "error can't use the same region for both endpoints" fi fi done done else echo "ERROR: The VPN mode was not set correctly!" exit 1 fi } lookup_region_name() { case $1 in Hamilton) ret_val="nz-hlz-1" ;; Porirua) ret_val="nz-por-1" ;; esac } check_openstack() { hash openstack 2>/dev/null || { echo "openstack command line client is not available, please install it before proceeding"; exit 1; } # check if openstack command works with current credentials export TOKENID=$(openstack token issue -c id -f value) if [ -z $TOKENID ]; then echo "Unable to get openstack token please checkl that you have sourced your openrc file" exit 1 fi } build_vpn() { if [ $REGION_1 ] then # define single region or region_1 endpoint lookup_region_name $REGION_1 OS_REGION_NAME=$ret_val echo "Please enter the name of your $REGION_1 router:" read -r region_1_router_name; if openstack router show "$region_1_router_name" 2>&1 | grep -q "No Router found for" then MSG="Unable to find router with name $region_1_router_name" echo -e "${RED}${MSG}${NC}" echo please ensure you have created the required routers before running this script exit; fi echo "Please enter the name of your $REGION_1 subnet:"; read -r region_1_subnet_name; if openstack subnet show "$region_1_subnet_name" 2>&1 /dev/null | grep -q 'Unable to find subnet with name' then MSG="No Subnet found for $region_1_subnet_name" echo -e "${RED}${MSG}${NC}" echo please ensure you have created the required subnets before running this script exit; fi fi if [ $REGION_2 ] then lookup_region_name $REGION_2 OS_REGION_NAME=$ret_val echo $OS_REGION_NAME echo "Please enter the name of your $REGION_2 router:"; read -r region_2_router_name; if openstack router show "$region_2_router_name" 2>&1 /dev/null | grep -q 'Unable to find router with name' then echo "Unable to find router with name $region_2_router_name" echo please ensure you have created the required routers before running this script exit; fi echo "Please enter the name of your $REGION_2 subnet:"; read -r region_2_subnet_name; if openstack subnet show "$region_2_subnet_name" 2>&1 /dev/null | grep -q 'Unable to find subnet with name' then echo "Unable to find subnet with name $region_2_subnet_name" echo please ensure you have created the required subnets before running this script exit; fi fi echo "Please enter your pre shared key:"; read -r pre_shared_key; if [[ $REGION_1 && $REGION_2 ]] # This is a site-to-site VPN across regions then echo "Please enter the $REGION_1 router ip address"; read -r region_1_router_ip; echo "Please enter the $REGION_1 CIDR range"; read -r region_1_subnet; echo echo "Please enter the $REGION_2 router ip address"; read -r region_2_router_ip; echo "Please enter the $REGION_2 CIDR range"; read -r region_2_subnet; region_1_peer_router_ip=$region_2_router_ip region_1_peer_subnet=$region_2_subnet region_2_peer_router_ip=$region_1_router_ip region_2_peer_subnet=$region_1_subnet elif [ -z $REGION_2 ] # This ss a single endpoint VPN to a remote site then echo "Please enter the remote peer router ip address"; read -r remote_peer_router_ip; echo "Please enter the remote peer CIDR range"; read -r remote_peer_subnet; region_1_peer_router_ip=$remote_peer_router_ip region_1_peer_subnet=$remote_peer_subnet fi echo echo -------------------------------------------------------- MSG="Proceeding to create VPN with the following credentials:" echo -e "${GREEN}${MSG}${NC}" if [ $REGION_1 ] then echo "Region name = $REGION_1" echo "region_1_router_name = $region_1_router_name" echo "region_1_subnet_name = $region_1_subnet_name" echo "region_1_router_ip = $region_1_router_ip" echo "region_1_subnet = $region_1_subnet" echo "region_1_peer_router_ip = $region_1_peer_router_ip" echo "region_1_peer_subnet = $region_1_peer_subnet" echo fi if [ $REGION_2 ] then echo "Region name = $REGION_2" echo "region_2_router_name = $region_2_router_name" echo "region_2_subnet_name = $region_2_subnet_name" echo "region_2_router_ip = $region_2_router_ip" echo "region_2_subnet = $region_2_subnet" echo "region_2_peer_router_ip = $region_2_peer_router_ip" echo "region_2_peer_subnet = $region_2_peer_subnet" echo fi # echo "tenant_id = $tenant_id" echo "pre_shared_key = $pre_shared_key" echo -------------------------------------------------------- echo # build the first endpoint if [ $REGION_1 ] then MSG="creating endpoint for $REGION_1" echo -e "${YELLOW}${MSG}${NC}" lookup_region_name $REGION_1 OS_REGION_NAME=$ret_val openstack vpn service create \ --subnet $region_1_subnet_name \ --router $region_1_router_name \ vpn_service 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 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 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 $region_1_peer_router_ip \ --peer-id $region_1_peer_router_ip \ --peer-cidr $region_1_peer_subnet \ --psk pre_shared_key \ vpn_site_connection fi # build the second endpoint if creating an inter-region VPN if [ $REGION_2 ] then MSG="creating endpoint for $REGION_2" echo -e "${YELLOW}${MSG}${NC}" lookup_region_name $REGION_2 OS_REGION_NAME=$ret_val openstack vpn service create \ --subnet $region_2_subnet_name \ --router $region_2_router_name \ vpn_service 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 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 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 $region_2_peer_router_ip \ --peer-id $region_2_peer_router_ip \ --peer-cidr $region_2_peer_subnet \ --psk pre_shared_key \ vpn_site_connection fi MSG="Your VPN has been created, note that you will need to create appropriate security group rules." echo echo -e "${GREEN}${MSG}${NC}" echo } #------------------------------------------------------------------------------ # Main #------------------------------------------------------------------------------ # Handle ctrl-c (SIGINT) trap handle_interruptions INT parse_args "$@" check_credentials check_openstack get_vpn_choice get_vpn_region build_vpn In this example we are going to set up a VPN connection in the Hamilton region to a remote router in the Porirua region with a public IP 150.242.40.137 that has the private subnet 10.20.30.0/24 connected to it.
In the Hamilton region we already have defined a router named border-router that is connected to the public network and has a subnet called private subnet with a CIDR of 10.0.0.0/24 connected to one of it’s interfaces. The steps to create these resources are covered in Adding a network
To create the VPN connection we are going to use the VPN screen which is accessed by clicking on the VPN item underneath the Network group on the left hand menu of the console:
Using the VPN screen we are going perform the following steps:
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
Create a VPN Service
First we select the VPN Service tab and click on the + Add VPN Service button to create a VPN service.
In the Add VPN Service dialog we do the following:
name the VPN Service “vpn service”
select “border-router” as the router for this VPN service.
Note
We do not select the subnet for the service as this will be done later using the endpoint groups.
Click the Add button and the VPN service will be in the Pending Create state, it will become Active when we have completed the IPSec connection.
Create IKE Policy
Next we create the IKE policy for the VPN connection by selecting the IKE Policies tab and clicking on the + Add IKE Policy button. In the dialog we named the policy “ike policy” we enter the following:
Name: ike policy
Encryption algorithm: change to “aes-256”
Lifetime value for IKE key: change to 14400
Perfect Forward Secrecy: change to “group14”.
Create IPsec Policy
Next we are going to create the IPSec policy by selecting the IPsec Policies tab and clicking on the + Add IPsec Policy button. In the Add IPsec Policy dialog we are going to enter the following:
Name: ipsec policy
Encryption algorithm: aes-256
Perfect Forward Secrecy: group14
The other fields we leave as the defaults. Click the Add button and the policy is created.
Create Endpoint Groups
Next we are going to add to Endpoint Group one for the local subnet and the other for the remote subnet. Recall that the local subnet called private subnet has a CIDR of 10.0.0.0/24 and the remote subnet has a CIDR of 10.20.30.0/24. Select the Endpoint Groups tab and click on the + Add Endpoint Group button. In the Add Endpoint Group dialog we are going to enter the following:
Name: local endpoint group
Type: Subnet (for local systems)
Local System Subnets: tick the box next to “10.0.0.0/24”
Click the Add button to create the endpoint group.
Click the + Add Endpoint Group button again and enter the following:
Name: peer endpoint group
Type: CIDR (for external systems)
External System CIDRs: 10.20.30.0/24
Click the Add button to create the endpoint group.
You should now have two endpoint groups:
Create an IPsec Site Connection
Finally we are able to create the connection by selecting the IPsec Site Connections tab and clicking the + Add IPsec Site Connection button.
In the Add IPsec Site Connection dialog we are entering the following values:
Name: vpn site connection
VPN service associated with this connection: vpn service
Endpoint group for local subnet(s): local endpoint group
IKE policy associated with this connection: ike policy
IPsec policy associated with this connection: ipsec policy
Peer gateway public IPv4/IPv6 Address or FQDN: 150.242.40.137
Peer router identity for authentication (Peer ID): 150.242.40.137
Endpoint group for remote peer CIDR(s): peer endpoint group
Pre-Shared Key (PSK) string: supersecretpsk
Recall that 150.242.40.137 is the public IP address of the remote router.
Note
Leave the Remote peer subnet(s) field blank this is an old method of defining the peer CIDRs which has been replaced by the Endpoint Groups.
Then click Optional Parameters and change the following:
Dead peer detection actions: restart
Dead peer detection interval: 15
Dead peer detection timeout: 150
Click the Add button and the IPsec Site Connection will be created:
Once the IPsec site connection is created the VPN service will become active:
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.
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.
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.
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