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
- Private subnets with NAT attached
- Public subnets for the OpenVPN server
- 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 OpenVPN server will generate the client certificate and key for the authentication.
- 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).
- After authentication, a secure encrypted tunnel will be created between the client machine and the OpenVPN server.
- 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.
- The VPN server will route the traffic from the user to the AWS VPC (Private subnets).
- 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.

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.

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

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.

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.

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

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.

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

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.

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.

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.

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

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.

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

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

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

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.

Select the keypair and choose the VPC and private Subnet.

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

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.

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>

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.

Sign the client certificate request using the OpenVPN CA.
sudo ./easyrsa sign-req client client
This will prompt you to type yes
,
is already configured on the CA.

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.
/etc/openvpn/easy-rsa/EasyRSA-3.2.2/pki/ca.crt
/etc/openvpn/easy-rsa/EasyRSA-3.2.2/pki/issued/client.crt
/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.

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 platformAfter the installation, if you open the client, you can see a +
button to add a configuration.

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

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

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

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

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.