Skip to main content

Building a VPN server in AWS


There are many VPN solutions and many ways to deploy such a system. In this tutorial we’ll focus on implementing OpenVPN Access Server on a CentOS 7 EC2 instance. In order to follow along, you will need an active AWS account, a domain name and some familiarity with AWS concepts.

Starting the CentOS host

In the AWS console, select the region where you want that VPN to live in, then launch a new instance. You can find the latest CentOS 7 AMI in the marketplace, use one of the smaller instance sizes, and you should only need 10 GB of disk space for it.

For the security group, you will need the following rules:

  • SSH available from your IP address
  • TCP port 943 available from everywhere
  • TCP port 1194 available from everywhere
  • UDP port 1194 available from everywhere

Once started, go under the Elastic IP section and assign a new IP for the host, since we want a consistent IP to always be available. If you own a domain name, it’s also useful to assign a hostname to that IP, to make it easier to configure your VPN clients.

Configuring the host

Once you SSH into your new host, there are many things you can do for configuration, but these are the commands I run as root:

export NAME=vpn

echo "$NAME" > /etc/hostname
chattr +i /etc/hostname
echo "search $DOMAIN" > /etc/resolv.conf
echo "domain $DOMAIN" >> /etc/resolv.conf
echo "nameserver" >> /etc/resolv.conf
chattr +i /etc/resolv.conf
echo "preserve_hostname: true" >> /etc/cloud/cloud.cfg
systemctl restart network

yum -y install wget
rpm --import
wget -O /tmp/epel.rpm
rpm -ivh /tmp/epel.rpm
rm -f /tmp/epel.rpm
rpm --import
rpm -Uvh
wget -O /etc/nanorc
yum -y install nano scl-utils python34 python34-devel psmisc bind-utils python-pip python-devel libtool rpm-build ntp redhat-rpm-config lynx
curl | python3
rm -f /usr/bin/pip
ln -s /usr/bin/pip2.7 /usr/bin/pip
pip install awscli
pip3 install boto3 connix
systemctl disable firewalld
systemctl start ntpd

yum -y update
yum -y install yum-cron

Your mileage may vary, but these changes will put the necessary packages for doing most things on that host.

Installing OpenVPN Access Server

We could use the basic OpenVPN package available in the CentOS repository, but I find it far more useful for both maintenance and anyone who will need to use the VPN service to have the full access server. The downside is that if you go with the free version, it is only licensed to 2 simultaneous devices. So you will need to buy a license if you want many users to connect at the same time.

Go to the website from your VPN host and download the RPM file for CentOS 7:


Or you can also download it on your desktop and transfer the file over. Once you have the package, install it, and make sure you change the password of the admin account:

rpm -i openvpn-as-2.0.25-CentOS7.x86_64.rpm
passwd openvpn

Configuring OpenVPN

Your OpenVPN server should now be ready for use. You can connect at replacing the hostname for the one you used. Login with the openvpn user and the password you set above. Click on the Admin button to access the configuration interface. There, some of the things you should change include:

Under Server Network Settings:

  • Set your hostname
  • Set the server to listen on all interface
  • Set the protocol to both TCP and UDP

Under VPN Settings:

  • Set a primary and secondary DNS servers

Under Advanced VPN:

  • Remove the ability for multiple sessions per user

Under Authentication General:

  • Set users to be local

Under User Permissions:

  • Create any new user you need to have access to your VPN server, and set passwords for them

Using the VPN

Now that the server is configured, any user you added can now log into and download their locked profiles after installing the OpenVPN app, available from the same page or from any popular store (Windows, Linux, iOS, Android). This profile should automatically configure their client to connect successfully.

To see the logs, you can SSH into the VPN host and look at the /var/log/openvpnas.log file. The configuration files are stored in /usr/local/openvpn_as, with most of the useful scripts in the scripts folder, like sacli to configure the server from the command line, and openvpnas to start or stop the server.

OpenVPN comes with a command line configuration utility that has a few more options than what is available in the web interface. The command is called sacli and can be used the following way to list configuration options and change the session expiry value:

sacli ConfigQuery
sacli --key vpn.server.session_expire --value 28800 ConfigPut
sacli start

The profiles that users download contain everything that the OpenVPN client needs to connect. It’s a text file which can be further customized. For example, if you want to prevent routing information from being used, so that your Internet traffic doesn’t go through the VPN, you can add the route-noexec command to that file.