Setup OpenVPN Server In EC2 For Secure AWS Access

Setup OpenVPN Server In EC2 For Secure AWS Access

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

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.

Prerequisites

  1. Private subnets with NAT attached
  2. Public subnets for the OpenVPN server
  3. OpenVPN client in the local machine

OpenVPN Server Workflow

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.

The private subnet has to be attached to the NAT Gateway to get the outbound internet access.

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

Create a Private EC2 Instance to Deploy Prometheus

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

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

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

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.

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.

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

Setup Prometheus Inside the Private Server

We are installing Prometheus on a private server to demonstrate access from a local machine. You can follow this blog for the installation.

Connect to OpenVPN from Local Machine

Step 1: Generate a client key on the OpenVPN Server

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.

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,

but you also need to provide the passphrase that

is already configured on the CA.

the signing output of the client certificate

Copy the following certificates and keys to your local machine.

Use cat command to manually copy and paste or use scp to directly copy from the OpenVPN server to the local machine via SSH.

  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

Step 2: 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
redirect-gateway def1
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.

redirect-gateway def1 --> Routes all traffic through the VPN

route 10.0.4.0 255.255.255.0 --> Specific route for the internal network access.

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

Step 3: Install OpenVPN Client

We need to install the OpenVPN client

On the local machine. You can follow this official link to download it for any 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

If the connection is successful, you can see the green mark in the button.

the openvpn client successful connection indication

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.