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 the 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 the 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