Using OpenVPN to connect on-premises Datacenter to AWS VPC

By | 9. December 2020

For a customer demo I needed a quick way to interconnect my on-premises environment with a AWS VPC without getting a AWS direct connect or the possibility to open the on-premises firewall for a NSX IPSEC tunnel. So I made it work with OpenVPN which just needs TCP Port 443 to be allowed on the on-premises firewall. The following pictures describes the environment I built.

I’ve also created Terraform scripts to create the infrastructure described in this post. Just clone my git repo, edit variables.tf and files in config_data.

AWS Setup

Create the follwing

AWS VPC, Name: AWS_VPC_DEMO , IPv4 CIDR 172.30.0.0/16

Subnet: Name: AWS_VPC_SN1, IPv4 CIDR 172.30.1.0/24

Security Group: Name: SG_OVPN Outbound Rules “All Traffic/Protocol/Port Destination 0.0.0.0/0” Inbound Rules:

TypeProtocolPortSource
SSHTCP22[ONPREM_EXT_IP]
HTTPSTCP443[ONPREM_EXT_IP]

Internet Gateway, Name: AWS_DEMO_IGW and attach it to AWS_VPC_DEMO

Select the Main Route Table of AWS_VPC_DEMO, Edit Routes and add Destination 0.0.0.0/0 with Target Internet Gateway AWS_DEMO_IGW

Launch a new EC2 Instance

  • Ubuntu Server 18.04 LTS, 64-bit (x86)
  • t2.nano
  • Network: AWS_VPC_DEMO
  • Subnet: AWS_VPC_SN1
  • Security Group: SG_OVPN
  • Tag: Name OPENVPN_SERVER

Allocate an Elastic IP and associate it with OPENVPN_SERVER Instance

By default AWS prevents Instances from receiving traffic not being the IP target. To allow this (for routing or NAT Instances) select your OPENVPN_SERVER instance, click Actions -> Networking -> Change source/destination check -> Select “STOP

Now edit the VPC Route table of AWS_VPC_DEMO and configure the following routes:

  • 172.16.0.0/16 Target: Instance OPENVPN_SERVER
  • 192.168.110.0/24 Target: Instance OPENVPN_SERVER

OPENVPN_SERVER Setup

Now you should be able to SSH into your OPENVPN_SERVER using “ubuntu@[ElasticIP]” and your AWS SSH keypair.

Enable IP forwarding by changing net.ipv4.ip_forward=1 in /etc/sysctl.conf

Check if all iptables are set to “ACCEPT”

ubuntu@ip-172-30-1-250:~$ sudo iptables -L

Install OpenVPN

ubuntu@ip-172-30-1-250:~$ sudo apt-get update
ubuntu@ip-172-30-1-250:~$ sudo apt-get install openvpn -y

Generate a static key for OpenVPN authentication:

ubuntu@ip-172-30-1-250:~$ sudo openvpn --genkey --secret /etc/openvpn/static.key

Create /etc/openvpn/server.conf and enter following values:

port 443
proto tcp-server
dev tun
secret /etc/openvpn/static.key
cipher AES-256-CBC
ifconfig 10.8.0.1 255.255.255.0
verb 3
topology subnet
route 172.16.0.0 255.255.0.0 10.8.0.2
route 192.168.110.0 255.255.255.0 10.8.0.2
keepalive 10 120
persist-key
persist-tun

Reboot Instance OPENVPN_SERVER and check if openvpn service automatically starts.

On-Premises Setup

Ensure your on-prem Firewall allows communication to the AWS ElasticIP using TCP port 443.

Your router should have a route for the AWS VPC CIDR (172.30.0.0/16) with the next-hop to the IP address of the OPENVPN_CLIENT.

My Demo environment is running a linux router also doing NAT so I just needed the following settings to be persistent (set the route and disable NAT for AWS_VPC CIDR).

route add -net 172.30.0.0/16 gw 192.168.110.2
iptables -t nat -I POSTROUTING -d 172.30.0.0/16 -j ACCEPT

I’m sure your environment will differ so check the necessary steps.

OPENVPN_CLIENT Setup

In your on-premises datacenter setup a Ubuntu 18.04 LTS VM and ensure its able to connect to the internet.

Enable IP forwarding by changing net.ipv4.ip_forward=1 in /etc/sysctl.conf

Check if all iptables are set to “ACCEPT”

vm@openvpn_client:~$ sudo iptables -L

Install OpenVPN

vm@openvpn_client:~$ sudo apt-get update
vm@openvpn_client:~$ sudo apt-get install openvpn -y

Copy static key from OPENVPN_SERVER (/etc/openvpn/static.key) to /etc/openvpn/static.key

Ensure right permissions are set to the key file:

vm@openvpn_client:~$ sudo chown root.root /etc/openvpn/static.key
vm@openvpn_client:~$
sudo chmod 600 /etc/openvpn/static.key

Create /etc/openvpn/client.conf and enter the following values:

port 443
proto tcp-client
dev tun
remote [Elastic IP of your OPENVPN_SERVER Instance]
secret /etc/openvpn/static.key
cipher AES-256-CBC
ifconfig 10.8.0.2 255.255.255.0
verb 3
topology subnet
route 172.30.0.0 255.255.0.0 10.8.0.1
keepalive 10 120
persist-key
persist-tun

Reboot OPENVPN_CLIENT and check if openvpn service automatically starts and connects to the OPENVPN_SERVER. You now should be able to sucessfully ping the OPENVPN_SERVER Tunnel Endpoint (IP 10.8.0.1)

Setup AWS_TEST Server

To test your setup first create a Security Group which only allows traffic from the on-premises environment to access.

Create a Security Group: Name: SG_TEST Outbound Rules “All Traffic/Protocol/Port Destination 0.0.0.0/0” Inbound Rules:

TypeProtocolPortSource
All ICMP – ICMPv4ICMPAll172.16.0.0/16
All ICMP – ICMPv4ICMPAll192.168.110.0/24
SSHTCP22172.16.0.0/16
SSHTCP22192.168.110.0/24

Launch a new EC2 Instance

  • Ubuntu Server 18.04 LTS, 64-bit (x86)
  • t2.nano
  • Network: AWS_VPC_DEMO
  • Subnet: AWS_VPC_SN1
  • Security Group: SG_TEST
  • Tag: Name AWS_TEST

After launching the AWS_TEST Instance you should be able to ping end-to-end from on-premises datacenter to AWS_TEST instance (in my example from ONPREM_MGMT to AWS_TEST).

print
Daniel Paul

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.