Setup OpenVPN Server on AWS EC2

Setup OpenVPN Server on AWS EC2

In this blog, you will learn to Setup OpenVPN Server in EC2 instance.

By the end of this guide, you will:

  • Have a fully working OpenVPN server
  • Validate the connection from your workstation to the OpenVPN server
  • Set up split tunneling to separate internet traffic from AWS access
  • Test application access to private subnets using SSH and HTTP connections
💡
Enterprise usually have Site to Site VPN configured for this use case. AWS also offers other client to site VPN solutions like AWS Client VPN but it becomes expensive with more users. checkout AWS Private Subnet section in VPC design blog to know more.

So if you are looking for a simple poor mans solution, a custom client to server VPN solution like OpenVPN can help.

OpenVPN Server Types

There are two types of OpenVPN implemention.

  1. OpenVPN Community Edition (CE): This is the free, open-source version of OpenVPN. It requires manual setup and configuration using command-line tools. Also, it does not have a UI for configuration. However, there is a open source project that provides UI for community edition.
  2. Self-hosted Access Server(AS): This is a commercial product from OpenVPN, that is built upon the open source version.
    1. It offers only two free users and you can use it free forever. For more users, you can checkout the pricing here.
    2. It provides user-friendly web-based GUI for easier management and configuration.
    3. It also supports multiple authentication methods such as LDAP, SAML etc.
  3. OpenVPN CloudConnexa: This is the cloud offering of the OpenVPN.
    1. It provides a user friendly approach for the configuration with the networks and applications.
    2. It has integrated security features like contentent filtering and IDS/IPS (Intrusion Detection Systetem and Intrusion Prevention System) to protect from the cyber attacks.
    3. Highly scalable approach for growing projects, for more information, refer to this offical documentation.

In short, the Community Edition is ideal for someone looking for a free VPN setup that supports multiple users.

Access Server is for organizations looking for an easier setup process and additional management features.

📌
Important Note: This blog is based on the OpenVPN Community Edition setup.

Setup Prerequisites

  1. Public subnets for the OpenVPN server
  2. Private subnets with NAT attached - Only for testing the workloads via VPN (Optional)
  3. OpenVPN client in the local machine to establish the authentication between the client and the VPN server

Architecture & OpenVPN Workflow

The OpenVPN server will help to access the other AWS private resources securely.

The OpenVPN server will create a secure HTTP tunnel over the Internet between the AWS network and our local machine so we can securely access the private AWS resources from the local machine.

The below is the workflow of the OpenVPN server and the access to the private AWS resource.

the workflow diagram of the openvpn server in the ec2 instance
  1. The OpenVPN server will generate the client certificate and key for the authentication.
  2. Once the user gets the credentials and the OpenVPN client configuration file, that user can authenticate with the OpenVPN server with the help of the OpenVPN client application (Client app should be available on the local machine).
  3. After authentication, a secure encrypted tunnel will be created between the client machine and the OpenVPN server.
  4. During this process, the VPN server will assign a virtual IP to the user's machine for the remote communication and traffic will reach the VPN server over the 1194 port.
  5. The VPN server will route the traffic from the user to the AWS VPC (Private subnets).
  6. VPC will route the traffic to a particular destination based on the security group's rules.

How to Setup OpenVPN Server in EC2?

The steps below explain the OpenVPN server setup on an EC2 instance.

Step 1: Create a Virtual Private Network

We need at least one private and a public subnet in the VPC to demonstrate this setup.

The public subnet should be attached to the Internet Gateway for the inbound and outbound communication ( This is for the VPN Server).

The private subnet has to be attached to the NAT Gateway to get the outbound internet access ( This is not mandatory, only for the testing purposes).

I already have a VPC setup. If you want to see the creation of the VPC, you can refer to this blog.

The vpc creation resource map of the VPC dashboard

Step 2: Create an EC2 instance for the OpenVPN

To create an OpenVPN server, we need to use the public subnet, because it needs inbound and outbound internet access.

I am choosing an Amazon Linux 2 AMI, t2-micro instance for this.

Note: Currently we are using the Amazon Linux 2, so the installation steps might differ in other distros.

Navigate to the EC2 console and click Launch instances button.

ec2 instance creation page and the ec2 dashboard

Give a name for the instance and select Amazon Linux as well as the AMI.

giving name and selection os and type for the instance creation

Select an instance type. I am choosing t2.micro, but you can choose any. If you already have a key pair, select it or create a new one.

choosing instance type and keypair for the ec2 instance

Select the VPC you have created, select the public subnet, enable public IP to access the server, and select the default security group, or you can create a new one for the OpenVPN server.

network settings section to select the vpc, subnet and security groups configuration

For now, I am using the default configuration for the rest of the settings, but you can modify it if you want.

lauching instance after all the configuration provided

Step 3: Update Security Group Rules

We have attached the default security group to this server, but need to know what protocols need to be enabled for the incoming traffic.

Navigate to the attached security group.

selecting the default security group of the ec2 instance to modifiy the rules

Clicking the security group will open a new page, there you need to click the Edit inbound rules button to add or remove rules.

the security group page to modify the inbound rules to the server

I will add a rule for SSH, then we can access this EC2 instance, and add a custom UDP port for the OpenVPN, which is 1194.

I am adding one more port, which is 9090, to demonstrate a private AWS resource access, so that is optional.

the added rules list inthe security group

Once the security group rules are properly added, we can access the instance.

Step 4: Access the OpenVPN EC2 Instance

The instance will take a few minutes to prepare. Once the health checks are completed and the state is running, we can log in to the shell.

the status of the openvpn ec2 server

If you click the instance ID, you can see the option to connect and note down the server's public IP for the upcoming configuration.

the server connection methods

You can use the EC2 Instance Connect method to connect the server, or can use the SSH method with the key from the local machine.

To access from the local machine, use the following command.

ssh -i <KEY> ec2-user@<PUBLIC_IP>

Setting up OpenVPN in Amazon Linux EC2 Instance

Follow the below steps to install the OpenVPN server on an EC2 instance.

Step 1: Install OpenVPN and EasyRSA

Enable the EPEL repository for the additional software packages.

sudo amazon-linux-extras enable epel

Install EPEL release package, OpenVPN and Easy-RSA

sudo yum install -y epel-release
sudo yum install -y openvpn easy-rsa

Step 2: Configure OpenVPN

Initialize the Easy-RSA and generate certificates

Easy-RSA is a tool for creating certificates for various use cases. It provides a framework with necessary components for generating certificates.

cd /etc/openvpn
sudo mkdir easy-rsa
cd easy-rsa

Download the Easy-RSA package from the GitHub and extract it

sudo wget -O easy-rsa.tar.gz https://github.com/OpenVPN/easy-rsa/releases/download/v3.2.2/EasyRSA-3.2.2.tgz
sudo tar -xvf easy-rsa.tar.gz
cd EasyRSA-3.2.2

Initialize the Public Key Infrastructure (PKI)

sudo ./easyrsa init-pki
the initialization of the easy-rsa public key infrastructure

Create a Certificate Authority (CA)

The Certificate Authority is a trusted entity that is capable of issuing and managing certificates.

sudo ./easyrsa build-ca

You will be prompted to give the passphrase, which is actually a password, and also will be asked to provide a common name; you can give any name.

setting up passphrase for the ca and common name

Create a request for a server key

sudo ./easyrsa gen-req server nopass

Will prompt to provide a common name, you can just press enter or provide a hostname like dev.techiescamp.com

requesting server key and providing host name

To sign the server certificate request, use the following command.

sudo ./easyrsa sign-req server server

Will prompt for yes and needs to provide the CA passphrase

the singing information and the validity of the server certificates

The output will give the validity and other related information.

Generate the Diffie-Hellman (DH) key exchange file

The Diffie-Hellman protocol secures communication protocols such as SSL/TLS, SSH, and IPsec.

sudo ./easyrsa gen-dh
diffie Hellman exchange key creation output

Step 3: Configure OpenVPN Server

Create a configuration file for the OpenVPN server

sudo vim /etc/openvpn/server.conf

Add the following configurations

port 1194
proto udp
dev tun
ca /etc/openvpn/easy-rsa/EasyRSA-3.2.2/pki/ca.crt
cert /etc/openvpn/easy-rsa/EasyRSA-3.2.2/pki/issued/server.crt
key /etc/openvpn/easy-rsa/EasyRSA-3.2.2/pki/private/server.key
dh /etc/openvpn/easy-rsa/EasyRSA-3.2.2/pki/dh.pem
server 10.8.0.0 255.255.255.0
keepalive 10 120
persist-key
persist-tun
status /var/log/openvpn-status.log
verb 3
push "route 10.0.4.0 255.255.255.0"  

Port 1194, is the default listening port of the OpenVPN and UDP is the protocol, which is faster than the TCP protocol.

dev tun --> Indicating that the OpenVPN to use tunnel device, (Layer 3 IP based tunneling)

ca /etc/openvpn/easy-rsa/EasyRSA-3.2.2/pki/ca.crt --> Certificate Authority certificate

cert /etc/openvpn/easy-rsa/EasyRSA-3.2.2/pki/issued/server.crt --> Server's SSL certificate

key /etc/openvpn/easy-rsa/EasyRSA-3.2.2/pki/private/server.key --> The private key of the server certificate

dh /etc/openvpn/easy-rsa/EasyRSA-3.2.2/pki/dh.pem --> Diffie-Hellman exchange key

server 10.8.0.0 255.255.255.0 --> Virtual IP for the VPN clients

keepalive 10 120 --> Sends ping request for each 10 seconds to ensure that connection is active and if there is no response in 120 seconds, it will restart the server.

persist-key --> This will avoid reloading the private key each time the OpenVPN server restarts.

persist-tun --> Keep the tunnel persistently.

status /var/log/openvpn-status.log --> Stores the OpenVPN logs in the specific path.

verb 3 --> The verbosity level for the logs.

push "route 10.0.4.0 255.255.255.0" --> Route to connect the VPN clients and 10.0.4.0 is the private network the clients can securely access.

Enable and start the OpenVPN service

sudo systemctl enable openvpn@server
sudo systemctl start openvpn@server

To check the OpenVPN service status.

sudo systemctl status openvpn@server
the openvpn service status output

Step 4: Enable Split Tunnel (NAT) for Internet Access

Now, if you establish the VPN connection from the local machine, you can only access the particular AWS private network.

This is quite secure because all the traffic will go through the secured VPN tunnel, which is called the full-tunnel method.

But the problem is that we can't access anything besides the AWS private network, even Google.

So, we need only the secure connection for the AWS network, but we also need to use the other networks. This method is called split tunnel.

For that we need to enable NAT.

To allow the clients to access the internet,

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

To make the configuration persistent

echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo iptables-save | sudo tee /etc/iptables/rules.v4

Restart the OpenVPN service.

sudo systemctl restart openvpn@server

The OpenVPN Server setup is completed.

Generate a client key

Next step is to create the client key for a user. This is required to authenticate from the VPN client with the sever for a specific user.

Navigate to the EasyRSA-3.2.2 directory.

/etc/openvpn/easy-rsa/EasyRSA-3.2.2

Generate a client key without password.

sudo ./easyrsa gen-req client nopass

This will prompt you to give a client name. It will create the client.req and client.key files.

output of generating the client key for the openvpn access

Sign the client certificate request using the OpenVPN CA.

sudo ./easyrsa sign-req client client

This will prompt you to type yes. Also you need to provide a passphrase. It will create the client certificates.

the signing output of the client certificate

Move Certificates to Local Workstation

Now that we have the certificates generated, we need to copy it to our local workstation for validation.

You can find the certs and key in the following locations.

  1. /etc/openvpn/easy-rsa/EasyRSA-3.2.2/pki/ca.crt
  2. /etc/openvpn/easy-rsa/EasyRSA-3.2.2/pki/issued/client.crt
  3. /etc/openvpn/easy-rsa/EasyRSA-3.2.2/pki/private/client.key

Use cat command to manually copy and paste.

Or you use scp to directly copy from the OpenVPN server to the local machine via SSH.

Once you have the files copied, move on to the next step.

Generate a VPN Client Configuration File

Once the above files are present in the local machine, we need to create a OpenVPN Client configuration file.

Make sure all files are in the same directory.

vim client.ovpn

Add the following configurations in the file.

client
dev tun
proto udp
remote 34.209.222.65 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
route 10.0.4.0 255.255.255.0

Here 34.209.222.65 is the OpenVPN Server's public IP so replace it with yours.

Add redirect-gateway def1 to route all traffic through the VPN, this might affect the regular internet access.

Now you should have the following files in your local workstation.

the openvpn client files such as ca, client certificate and key and copenvpn configuration file

Install & Configure OpenVPN Client

Now that we have the necessary certs and config files for client authentication, we can configure the OpenVPN client application.

First, need to install the OpenVPN client.

You can follow this official downloads page to download the client based on your platform.

After the installation, if you open the client, you can see a + button to add a configuration.

OpenVPN client dashboard

On the next step, you need to upload the .ovpn file that we have configured earlier.

openvpn client dashboard to update the openvpn configuration file

Once you uploaded the OpenVPN Configuration file, you can see a connect button to establish the connection

the connection of the openvpn client

Once the connection is successfully established, we can see the green mark on the radio button.

the openvpn client successful connection indication

VPN Validation Using Private ec2 Instance

Now, we need to check whether we can access the private AWS resources.

For that, I am creating an EC2 instance within private subnet and deploying a Prometheus application inside it.

I am choosing Amazon Linux as AMI.

creating an ec2 instance for the prometheus server

Select the keypair and choose the VPC and private Subnet.

selecting the keypair and vpc as well as the subnets.

Wait until the state and status are ready and note down the private IP of the server.

checking the status of the private server and noting down the private ip address

Now, I am getting in the private server through SSH from the VPN Server, because the VPN server is public and on the same network as the private server.

We can also SSH to the private server from the local machine as well because the VPN connection is established between local workstation and the VPC network.

the public key to ssh the private server

Copy the keypair to the VPN server and change the permission.

sudo chmod 400 techiescamp.pem

To SSH to the private server, use the following command.

sudo ssh -i techiescamp.pem ec2-user@<PRIVATE_SERVER_IP>
the successful authentication of the private server
💡
Important Note: If we enable AWS SSM, we can connect to the server without using SSH, otherwise, we can access the shell only from another public server of the same network with the key pair.

Deploy Application in Private ec2 Instance

We are installing Prometheus on a private server to demonstrate access from a local machine but you can try with any application even a simpe nginx server also enough for the testing.

You can follow this blog for the Prometheus installation.

Now, we can try to access the Prometheus dashboard from our local machine with its private IP securely.

the access output of the prometheus dashboard

Conclusion

This blog mainly covers setting up the OpenVPN server on the EC2 instance and accessing private AWS resources.

There is a managed service available in AWS, AWS Client VPN Endpoint. We don't need a server to deploy for the OpenVPN, and it will automatically scale based on the user connection.

If you want to see the AWS Client VPN Endpoint setup, refer to this blog.

The next blog will cover access to the AWS EKS private cluster resources.

About the author
Arun Lal

Arun Lal

Arun Lal is a DevOps Engineer & AWS Community Builder, also an Expert in AWS infrastructure, Terraform automation, and GitLab CI/CD pipelines.

Great! You’ve successfully signed up.

Welcome back! You've successfully signed in.

You've successfully subscribed to DevOpsCube – Easy DevOps, SRE Guides & Reviews.

Success! Check your email for magic link to sign-in.

Success! Your billing info has been updated.

Your billing was not updated.