How to make your own free VPN with Amazon Web Services

Internet users are spoiled for choice when it comes to VPN services, but they either require a monthly subscription, aren’t secure, or are just plain slow. Thankfully, alternatives do exist. They require a bit more technical know-how, but if you want something done right, you have to do it yourself.

To learn how to make your own VPN, you can watch the video or read the article. Note that the article contains some useful commands and configuration text that you can copy and paste for your convenience. Update: the video uses an old version of easy-rsa that is no longer available. When you get to the 8-minute mark, please refer to this article for easy-rsa 3 configuration.

Getting started

Amazon Web Services offers one year of free virtual server space, provided you use less than predetermined amounts of bandwidth, time, and space. Even if you go over that limit, the cost of running a server image on Amazon’s Elastic Compute Cloud is probably less than you would pay for a VPN subscription.

Here we’ll explain two different ways to use Amazon’s Elastic Cloud service, also called EC2, to divert your connection through a private location of your choice: SSH Tunneling and OpenVPN. Each has advantages and disadvantages, so use the one you find more suited to your needs. No matter which you choose, you’ll require the following:

An Amazon Web Services account. This requires a credit card, but you’ll only be charged for what you use, which will likely be nothing if you’re prudent about what you’re doing.

PuTTy, if you’re on Windows. OpenSSH via Cygwin is another option, but I found it to be a pain. Linux and Mac computers already have SSH prompts built into their boxes and terminals. You’ll also need PuTTy’s sister key generation program, PuttyGen.

WinSCP, or an equivalent FTP client to move files between your local computer and your EC2 instance.

A basic working knowledge of Unix commands and how servers work with clients will be massively helpful in troubleshooting should something not go exactly as planned.

OpenVPN GUI, installed in the default location and with the default settings on your PC

Log into your Amazon Web Service account and head to the EC2 dashboard.

On the top right, you can choose the location where we’ll be setting up your VPN. Click Launch Instance.

Choose whatever Linux AMI is listed as “free tier eligible.” At the time of writing this article, that’s the Amazon Linux AMI. Go on to the next step.

On the next page, you should get a warning message asking you to edit your security groups. Click Edit Security Groups.You’ll need edit the security group to only allow traffic from your computer to access the VPN or proxy. You should have one rule already in place for connecting to your server via SSH, which we’ll use later. We’ll need to add another to allow OpenVPN connections, which use port 1194 by default. For simplicity’s sake, under the Inbound tab, click the Add rule button. Set the Type to Custom UDP, the Port Range to 1194, and the Source to Anywhere.

Hit Save.

Click “review and launch,” then “launch” on the next page.

Now you’ll want to create a key pair, which sort of works like a password that you’ll use to connect to the virtual server you’re creating. Select “create a new key pair” from the dropdown menu and name it whatever you like. Click the button to download the key pair. Store it somewhere safe.

The next page should alert you that the instance is launching. Scroll to the bottom and hit “View instances.” Here you’ll see a list of any instances you’ve launched, which if this is your first time using EC2 will just be one.

We can connect to our EC2 instance with PuTTy, but first we’ll need a proper key file to get connected. When you installed PuTTy, you should have also installed PuTTygen. Go ahead and run it now.

PuTTy and PuTTygen both run right out of the box as .exe files with no need to install. Open PuTTygen, click Load. Navigate to the .pem key pair file you downloaded before and load it into Puttygen. You’ll have to select the option to show all file types for the .pem key to show up. Hit “Save Private Key.” The file name must be identical to the .pem key. You can create a passphrase for the private key if you want.

Now close out of PuTTygen and open PuTTy. Copy your instance’s public IP from the EC2 console into PuTTy. Type in a name for your session and hit save.

In the left pane, navigate to “Auth” under SSH. Click the browse button at the bottom and navigate to the private key you just generated.

Back on the main Session page, name and save your session profile so you can quickly connect the next time you use PuTTy. Then Click Open. A prompt will appear asking you for a username. This differs based on what type of server you set up at the beginning. For the Amazon Linux AMI, it’s “ec2-user”.

SSH Tunneling (optional)

To begin with, we’re just going to reroute web traffic through the instance we created using SSH tunneling and a proxy. This is a quick and dirty way to get around a firewall or geographic lockout. It’s not quite a VPN–it’s best for light web traffic and won’t work with everything–but it’s much more simple to set up. However, setting up SSH tunneling is entirely optional, so feel free to skip to the next section.

Open PuTTy and navigate to Tunnels in the left pain. Add port 8080 with Auto and Dynamic selected. Go back to the Session page and hit Save again so you don’t have to do all this over again. Then click Open.

Now you’re connected to your server, but you still need to route your web browser’s traffic through it. If you use Firefox, this can be done in your browser settings. If you use Chrome, download the Proxy Switchy extension. If you prefer to create a fully functioning VPN rather than just a proxy for your browser, skip to the next section now.

Set SOCKS Host as 127.0.0.1 and the port as 8080 (or whatever you set the tunnel port to on PuTTy).

Click OK to save

In Chrome Proxy Switchy

A setup page should appear as soon as you install the extension, or click the icon in the top right of Chrome and click Options.

Name the profile whatever you like. Under Manual Configuration, set the SOCKS host to 127.0.0.1 and the port to 8080 (or whatever you set the tunnel port to in PuTTy. Leave everything else blank.

Hit Save, then click the icon again to select your proxy profile.

Voila! Your browser traffic is now being funneled through your EC2 instance. This will work fine for basic browsing, but some websites might run into problems and apps other than your web browser will still use the direct connection. To create a full-on VPN that reroutes all your internet traffic, read on.

Set up OpenVPN on the server and client

OpenVPN is a free open source tool that will let you run a full-on VPN through your Amazon EC2 instance. That means all your internet traffic goes through it, not just your web browser traffic like the proxy above. Desktop programs such as Steam or Spotify work better with this approach.

Connect to your EC2 instance using PuTTy according to the instructions above. You should have a command prompt in front of you that says Amazon Linux AMI. Run the following commands (type or copy/paste them and press enter):

Just a quick note here. You might have noticed in the screenshot that I incorrectly tried to download and install OpenVPN using the “apt-get” command instead of “yum”. Some other versions of Linux still use apt-get, so if yum doesn’t work for you, try this command instead:

sudo apt-get install -y openvpn

A bunch of text will flash on the command prompt while it installs OpenVPN. The other three commands set up IP forwarding, which is necessary for the VPN to work.

Method #1: Setting up PKI authentication with easy-rsa (recommended)

In the original version of this tutorial, we set up OpenVPN with static encryption and a .ovpn file. While that works, it only allows one device to be connected at a time, and the fact that you only ever use one key means it’s less secure. We now recommend readers use easy-rsa to set up authentication, which is more secure and allows for any number of devices to be simultaneously connected. However, if you want the old version with static encryption, skip to it by clicking here.

May 2018 update: This article has been updated for use with easy-rsa 3.

Easy-rsa is not available in the default yum package list, so we’ll need to enable the EPEL repo to install it. Type the following into the PuTTy terminal and hit Enter:

sudo yum install easy-rsa -y --enablerepo=epel

Ideally, you would generate all the keys and certificates you need on a separate device from the VPN server for maximum security. This can be quite tedious, however, so we’re just going to generate both client and server credentials on the server, then move the files where we need them from there.

Make an easy-rsa directory in your OpenVPN install directory. Copy the files from your easy-rsa installation (latest version is 3.0.3 as of time of writing) to the new directory:

This command can take awhile. It will generate a file called dh.pem. Once finished, we move on to the server credentials. For convenience, we won’t password protect these, but you’re certainly welcome to do so if you want even harder security.

sudo ./easyrsa gen-req server nopass

Hit Enter to leave the common name as server. Once the key pair is generated, sign the certificate:

sudo ./easyrsa sign-req server server

Type yes to confirm and enter your CA password if you set one earlier.

Now we’ll set up the client. Again, we won’t set a password on this but you are welcome to. Note that if you want to configure automated VPN startup, it’s best not to set a password.

./easyrsa gen-req client nopass

Hit Enter to leave the common name as client. Now sign it:

sudo ./easyrsa sign-req client client

Type yes to confirm and enter your CA password if you set one.

Next, we’ll generate a TLS key for perfect forward secrecy in OpenVPN, which ensures past session data cannot be decrypted even if an attacker gets hold of our private key.

cd /etc/openvpn
openvpn --genkey --secret pfs.key

We’ve now generated all of the credential files we need. Next, we’ll create an OpenVPN server configuration file. We’ve already got one written up for you below, so all you need to do is copy and paste if you’ve followed along from the beginning. Start by navigating to the OpenVPN directory and creating a new file:

cd /etc/openvpn
sudo nano server.conf

You are now in the nano text editor. Copy and paste the following config, then hit CTRL+O to save, Enter to confirm, and CTRL+X to exit. (Hint: you can paste text from your clipboard into PuTTy just by right-clicking)

The server is now configured. We just need to start up OpenVPN. We’ll start it as a service so that even after you close PuTTy, it will continue to run until the server is either shut down or you manually end the service.

sudo service openvpn start

Edit: Some readers have pointed out that their VPN servers stop working after a server reboot or maintenance. This happens occasionally with micro tier EC2 instances. To prevent this, we’ll use a command and bash script courtesy of Matt Doyle in the comments section. Start with this command:

sudo chkconfig openvpn on

While you’re still in etc/openvpn, use nano server.sh to create a new text file and paste the following into it:

The command will ensure OpenVPN starts when the server boots, and the script will ensure the necessary routes are set up in iptables to allow OpenVPN traffic.

Now that the server is configured, we need to set up the client. To do that, we’ll have to move the necessary certificate and key files from our server to our client device. With PuTTy still open and running as root, we first need to change the permissions on these files so that we can access them. We’ll also put them all in one place to make things a bit easier. To access some of these files, we’ll need to be root user. To do that, type:

sudo su

This will make you the root user and grant administrative privileges. Now enter the following commands:

The last command lowers the required permissions to access these files. It’s important to change them back when finished.

To get the files off of our server and onto our PC, we’ll use a free program called WinSCP. Just use the default installation options. Once that’s done, a window should pop up prompting you to import your server authentication details from PuTTy. Select the one we made above and continue.

Select myvpn (or whatever you named yours) and hit the Edit button. Type in ec2-user under user name. Click on Login.

If this isn’t your first time using WinSCP, you can set the .ppk file you used in PuTTy by clicking Edit and Advanced. Go to SSH > Authentication > Private key file and navigate to your PPK file. In the host name field on the main page, you can enter either the IP address or domain of your EC2 instance. Be sure to save your settings, then hit Login.

In the right pane, navigate to the directory containing your key files, in this case /etc/openvpn/keys

Highlight the six files you’ll need: client.crt, client.key, ca.crt, dh.pem, pfs.key, and ca.key (not shown due to article update). Hit the green Download button. It doesn’t really matter where they go on the left pane so long as you don’t need admin privileges to access it. We put the files on our desktop for simplicity’s sake. However, you’ll want to store the ca.key file somewhere safe, such as a USB drive.

The last loose end we need to do tie up is removing the ca.key file from the server. The CA, or certificate authority, is used to sign client certificates, and, if it is ever compromised, you can never trust certificates issued by that CA again. While this isn’t necessary for the VPN to work, we strongly recommend doing it, especially if you didn’t set up a password for the CA. Make sure you’ve all the keys and certificates for every device you want to connect before removing the file. If you want to add more at a later time, you will have to move the ca.key file back onto the server.

Once you have the CA key safely stored somewhere other than the server, go into PuTTy and remove both the original ca.key and the copy we made from the server:

Once the files have downloaded, we need to restore their stricter permissions on the server so not just anyone can access them. Back in PuTTy:

cd /etc/openvpn/keys
sudo chmod 600 *

On your PC, cut and paste those five files from wherever you downloaded them into your OpenVPN config folder. In this case that’s C://Program Files//OpenVPN//config.

Lastly, we need to create a client configuration file. Open your favorite plaintext editor (Notepad works fine) by right clicking and selecting Run as administrator and paste the following config, replacing YOUR.EC2.INSTANCE.IP with the IP address of your EC2 instance:

This is a Windows config file for the OpenVPN GUI, so we’ll save it as client.ovpn. Other OpenVPN clients might use the .conf extension instead. Whatever the case, make sure your text editor doesn’t add the .txt extension after saving. Save it into the same location as your key and certification files: C:\\Program Files\\OpenVPN\\config

Now run the OpenVPN GUI in administrator mode by right clicking it and selecting Run as administrator. Right click the icon in your system tray and connect with the client configuration we just set up. A status screen with loads of text will flash across the screen, and then the icon will turn green.

Congratulations! You are now connected to your homemade VPN.

Method #2: Static encryption (easier, but not recommended)

In this method, we’ll create a shared key for authentication. It’s sort of like a file that acts as a password. It’s easier to set up but only allows a single device to be connected to the VPN at any one time, and is less secure than the easy-rsa method above. In PuTTy Type in the following commands and hit enter:

cd /etc/openvpn
sudo openvpn --genkey --secret ovpn.key

Now we’re going to create a server config file for our VPN. Type the following command to create a blank text file in a very basic text editor inside the terminal:

sudo nano openvpn.conf

Type in the following configuration. You can find more options on the OpenVPN website if you want to play around with this later, but make sure you know what you’re doing first.

Now hit CTRL+O (that’s the letter ‘O’ not zero) and hit enter to save the file. Then hit CTRL+X to exit the text editor. Back at the command prompt, it’s time to fire up OpenVPN:

sudo service openvpn start

Next we need to get the shared key from the server to your local computer. First we need to change the permissions on that file so we can access it using the following command:

sudo chmod 777 ovpn.key

If at any point you accidentally close PuTTy or it just craps out, you can navigate back to your open VPN installation directory after reconnecting using this command:

cd /etc/openvpn

To make this as easy as possible, download and install this free application, WinSCP (Mac users will have to find another FTP client. Don’t worry, there are lots of them). Just use the default installation options. Once that’s done, a Window should pop up prompting you to import your server authentication details from PuTTy. Select the one we made above and continue.

Select myvpn (or whatever you named yours) and hit the Edit button. Type in “ec2-user” under user name. Click on Login.

Now you can move files between your EC2 instance server and your local computer. On the right hand panel, navigate up as far as you can, then go to etc/openvpn. Here you’ll find the ovpn.key file that we need. Click and drag it into the folder of your choice, but remember where you put it as we’ll want to move it later.

Now that you have the key, we need to re-apply the old permissions so not just anyone can grab it. Back in your PuTTy terminal, enter:

sudo chmod 600 ovpn.key

It’s time to download the OpenVPN client and GUI for your local computer. Go to the OpenVPN downloads page and choose the appropriate version for your operating system. Install it with the default settings. It should appear in your system tray as an icon once launched. Open up a file explorer and navigate to where you installed OpenVPN, probably in your Program Files folder. Move the opvn.key file we downloaded from the server to the config folder found here (C:/Program Files/OpenVPN/config … if you used the default installation directory on Windows).

Next, we need to create a config file for the local machine to match the one we made on our server. Open up Notepad and paste the following, replacing the IP address after “remote” with the IP of your EC2 instance (if you’ve forgotten it, find it in your AWS Console under EC2 Instances). Also, double check that the full file path pointing to your key is correct.

Save it as myconfig.ovpn (make sure your text editor doesn’t append it as myconfig.ovpn.txt by mistake) in the config folder of your OpenVPN installation, the same place as your opvn.key file.

Right click on the OpenVPN icon in your system tray and click Exit to quit. Now start it up again–either from the desktop shortcut or from the Program Files folder–but this time use right click and hit “Run as administrator”. If you don’t run OpenVPN as administrator on Windows, it probably won’t work.

Right click the system tray icon and click Connect. The OpenVPN GUI should pop up showing you the connection status. Assuming it worked, the system tray icon will turn green. Go to Google and type in “What’s my IP?”, and it should return the IP address of your Amazon EC2 Instance.

Congratulations, you just made your own VPN!

Additional notes

If you want to protect your VPN from deep packet inspection, a technique used by censorship regimes in places like China and Syria to block OpenVPN connections, check out our tutorial on setting up Obfsproxy. Note this tutorial was written as a sort of sequel to the older Method #2 in this article, so if you used easy-rsa, it will require some additional configuration.

Remember to keep your bandwidth within Amazon’s free tier limits. The easiest way to do this is to right click on your instance in the AWS Console and click on the “Add/Edit Alarms” link. You can set your server to stop or even terminate after a few hours of inactivity. The free tier allows for 750 hours per month (which covers the whole month), so you shouldn’t need to do this. Those users past their initial free year of service or doing more with their server, however, can prevent unnecessary charges for unused server time.

Somewhere in this tutorial, something will probably go wrong for you. If you really want a VPN but aren’t willing to do your fair share of troubleshooting, it’s probably best to opt for a paid VPN service. They also allow you to channel your internet traffic through multiple geographic locations, whereas an EC2 instance is limited to just one. Check out our VPN reviews here!

Hardcoding DNS servers into your VPN

If you need to set specific DNS servers to use with your VPN, there are a couple of options.

To “push” the DNS server to the client, add this line to the server config. This will affect all of the devices that connect to your VPN (quotes included):

push "dhcp-option DNS 45.56.117.118"

Alternatively, you can set the DNS in an individual client config using:

dhcp-option DNS 45.56.117.118

In these examples, I used an OpenNIC public DNS server with anonymous logging located in the US. You can find a OpenNIC server in the country of your choice and filter by features like anonymous logging and DNSCrypt here.

Special thanks to Dctr Watson’s blog, which I leaned on as a resource when writing this article.

Hi Paul!I have been waiting for this update for a while.. I followed your setup and successfully built a VPN last year, but I shut it down and terminated it . Now I am trying to build again. I have followed every step very carefully (several times) but get this error when trying to setup the certificate authority.[ec2-user@ip-172-31-15-88 easy-rsa]$ sudo ./easy-rsa init-pkisudo: ./easy-rsa: command not found

make sure you’re in the /etc/openvpn/easy-rsa directory when you run those commands. Also ensure that if you use “sudo” in the command that you are not already logged in as the root user (should be ec2-user).

Hi Paul. This is a tremendously helpful guide and I used it in the past with the static encryption but just spun up a new server with the EasyRSA but with it. I’m able to get the server up and running and connect with OpenVPN client, but can’t get to any web sites and can’t ping 8.8.8.8. I don’t see any failures in the log file. Where should I start troubleshooting?

Hi Andy,It sounds like the server firewall might be blocking outbound connections to the internet. Run the POSTROUTING commands again and see if it will let you ping Google. Sometimes when an EC2 server gets restarted, those routing tables get reset.

I am not sure Amazon would like their virtual servers going to illegal sites; I’m sure it’s not a use case they would like. A paid VPN non-logging service is probably better since they’re intention is to hide your usage.

if you picked a different distro, try “apt-get” instead of “yum”. If that doesn’t work, you may need to install a repo with OpenVPN in it or download directly. Remember to run an update on the whole server as well.

Well I have successfully managed to follow the tutorial including navigating the use of easy-rsa 3.0.3 and got the VPN up and running using the local open vpn client.

Now I would like to get the same service running on my DDWRT router using the built in Open VPN client, but I am failing. I have copy pasted into the Open VPN client in DDWRT the TLS auth key (pfs key), the CA certificate the unique client key and certificate, set all the settings to the same as in the text for the .ovpn file above and launched the client. On the Status Open VPN page, I see that is is trying to connect but the TLS Handshake fails after 60 seconds. I cannot see what I am doing wrong. The client certificate and key have no password. For info the DDWRT router is on a different subnet (192.168.2.x) to the PC that connected successfully (192.168.1.x) and this router has previously connected successfully to other commercial VPN providers using this integrated Open VPN client. I’m guessing somewhere along the line I have a setting issue or i’m missing some complementary commands in the client that are automatically handled in the installed client on the PC. Can anyone help?

A great article. One discrepancy I have noted is the `server.sh` file does not run when the openvpn service starts. The openvpn service starts when the machine boots, but Matt Doyle’s premise that the “init script will run a .sh file for each .conf file” is not correct (at least not anymore at the time of writing this!). I need to manually run the file (`/etc/openvpn/server.sh`).

Hi,This a great tutorial, thank you for posting. I am having some trouble with easy rsa 3.0. When I get to point 5 in the VPN – howto link you provided :./easyrsa import-req /path/to/received.req UNIQUE_SHORT_FILE_NAMEI use the path /pki/reqs/request.req… and I keep getting the following error message

The input file does not appear to be a certificate request. Aborting import.Offending file: /pki/reqs/request.req

FYI: If you decide to follow the instructions for “Method #2: Static encryption”, you’ll have to choose “Custom TCP” instead of “Custom UDP” when you add the rule in “Edit Security Groups” for your EC2 instance as your recipe instructs you to configure the OpenVPN server using “proto tcp-server” in /etc/openvpn/openvpn.conf.

Hi Doug, I ran into the same problem as you. Here is the tutorial page for the 3.0.3 version of easy-rsa, It won’t be a simple one to one translation of the tutorial, but the same functionality is possible.

Thanks for such a great tutorial! I am having a hard time to conclude it because I am a really newbie in Linux, but I am enjoying it because I am learning.Well, I’d like ask for your help or from someone’s here. When I try to start the service on server it fails. I looked into the log and the message I receive is:

Options error: –ca fails with ‘etc/openvpn/keys/ca.crt’: No such file or direc$Options error: Please correct these errors.Use –help for more information.

I’m having trouble getting this working on multiple machines. Once I go through the entire tutorial and get it working on one machine, then what do I have to do to get in working on another machine? Which steps do I have to implement? Which steps can I skip? Do I have to rename some things?

What is the purpose of the “sudo cp -via /usr/share/easy-rsa/2.0 CA” line above it, then? You’re telling the user to copy a bunch of files into a directory with a relative path, but not telling them what directory they should be in when running the command (so it could end up in a variety of locations, depending on what the user has done beforehand). And then this CA directory is never referenced again in any of the instructions.

Great tutorial. Very thorough and complete! I couldn’t get it to work using the static method unless I also added a custom TCP rule for port 1194 in the Security Group. I saw at least one other commenter found this necessary. Should this be of any concern? Thanks.

First of all great tutorial, it is really detailed and is incredibly easy to follow. I run into a problem when trying to connect through openvpn in my windows machine. I get some text on the console but it gets stuck and is unable to connect, I’m pasting the output if it helps.

Thanks for the super helpful article, Paul! I wanted to leave a few comments on things that tripped me up and/or would help others who run into the same issues.

1) When running `./build-key-server` and `./build-key`, either do not change the default common name or ensure they’re unique across all keys you create. I wasn’t sure what I was doing and I ended up overriding the defaults for both the server and client to have the common name; this resulted in an empty server.crt and obviously the openvpn server failed to start.

2) It’s in your server.conf, but I want to explicitly point out that the OpenVPN log is at /etc/openvpn/openvpn.log. This was crucial to realizing I had an empty server.crt.

3) `systemctl` is not available as part of the Amazon Linux AMI (at least not in the current version, amzn-ami-hvm-2017.09.0.20170930-x86_64-gp2). To ensure openvpn started up when the server rebooted (I don’t keep it on all the time) I used chkconfig and the pre-installed openvpn script: “sudo chkconfig openvpn on”

That command will start openvpn on boot but we still need to set up the port forwarding stuff. Instead of modifying that script (/etc/init.d/openvpn) or saving iptables, I created a bash script and put it in the openvpn directory on the server. That init script will run a .sh file for each .conf file, so since our conf is `server.conf` I put the following in `/etc/openvpn/server.sh`:

I did not need to change file permissions to make the file executable. After rebooting the server I was able to connect as usual and it worked just fine. For those without systemctl it would be worth mentioning the chkconfig route.

4) I use Tunnelblick on my Mac and OpenVPN connect on my phone(s). For simplicity I prefer to have to only move a single file to my phone instead of all the crt and key files (I do create different keys for each device, though). If anyone else is interested I figured it’s worth mentioning that you can combine all these into the single .ovpn file. Instead of each line specifying the crt or key file you can just add the certificate or key inline as follows:

Instead of `ca ca.crt` You can do:

—–BEGIN CERTIFICATE—–copy and paste this whole blockincluding BEGIN and ENDfrom ca.crt, which you can openin any text editor—–END CERTIFICATE—–

You can do this for ca, cert, key and tls-auth and then you’ve only got one file to put onto a thumb drive or something.

Whether the cert & keys are in one file or all the same directory as the .ovpn file, loading the configuration into Tunnelblick is as easy as double-clicking the .ovpn file (or dragging and dropping it over the Tunnelblick icon).

Thank you so much for this post! Been struggling getting the “easy” solution to work for over a day losing all my sanity until I came across this comment and realized I needed to do some iptables trickery.

To anyone struggling with the problem when the OpenVPN server does not forward requests, those 3 lines from step 3) solved it for me.

Did you update this excellent tutorial with instructions on how to issue additional keys for separate clients?

When I tried ./build-key client2 I got the following:Please edit the vars script to reflect your configuration,then source it with “source ./vars”.Next, to start with a fresh PKI configuration and to delete anyprevious certificates and keys, run “./clean-all”.Finally, you can run this tool (pkitool) to build certificates/keys.

Though I’m doing this on my AWS account exactly as in your screenshots, when doing: “sudo systemctl start openvpn@server.service” I get error: systemctl: command not found. I skipped this step for now, but would like to know how to perform this in case a server reboot problem should occur.

Secondly, and crucial, when getting to “for file in client.crt client.key ca.crt dh2048.pem pfs.key ca.key; do sudo chmod 777 $file; done”, the terminal tells me that the client.crt and client.key files are not there, and indeed they aren’t. I went through the tutorial again and again, but fail to see in which step these two files were supposed to be created? All other mentioned files are there.Thanks for any clarifications.

Glad to hear it! The chmod is just temporary so you can access the files from your PC. I wouldn’t suggest this for a business or professional, but for a first time home made VPN there’s relatively little risk if you switch back the permissions when you’re done. The alternative is to generate the key on your PC using the windows version of easyrsa, then moving those files onto your ec2 instance.

Check to make sure your server IP address or domain name didn’t change. When you restart the server, I think you are assigned a new IP address. If it’s changed, you may need to make changes as appropriate in your server config, client config, and/or AWS security groups, so check all those. You can get around this by getting an elastic IP address, but it may cost you a bit more.

You’ve pulled out a very detailed article here that will be helpful to your readers – it’s long (which I really understand) yet it was not boring. In the end, if implemented correctly, it will help any user to have their own custom VPN using Amazon. I remember myself documenting a related topic while I was in China for a one-year project. It was very hard to bypass the so-called Great Firewall of China. However, thanks to Amazon and with a little research I was able to build also a simple VPN to bypass Internet censorship using AWS and shadowsocks. Quite fulfilling. Again, more power!

This is exactly what I was looking for. I got it set up , but am getting“Connection reset by peer (WSAECONNRESET) (code=10054)” error. Googling for that led me down a rabbit hole. Any suggestions on how to troubleshoot this ?I tried :– disabling ufw– changing to TCP after changing the inbound rules– a bunch of other stuff

hello thank for your guide. It is very helpful. I have a problem, i follow the 2nd methode (Static encryption ), when i try to connect via openvpn gui(run as admin), this is the error code ”SIGUSR1[connection failed(soft),init_instance] received, process restarting”Any idea? thank you

1.) Where the 10.8.0.0/24 subnet is referenced, it should be stated, explicitly, what this is for. After reading a few other notes that I found on the Web, I came to realize that this was for the “VPN network”, if you will, that is to be established between VPN clients and the new host. Not being clear on this, a person could easily place info for their client-local LAN in here, which would not be good, of course.

2.)In the “Setting up PKI authentication with easy-rsa (recommended)” section, you don’t say what the current directory should be, when the yum-install and cp commands are run. The screen shot that you posted makes it look like that folder is “/bin”.

You mention “/usr/share/easy-rsa/2.0”, at one point, then “/usr/etc/easy-rsa/2.0”. Frustrating.

3.) On the command-calls for dropping a “1” into /proc/sys/net/ipv4/ip_forward and for inserting the iptables entries, steps need to be included for making these persist, beyond server reboots. I may have missed this, but I don’t think it was covered and it isn’t covered, either, in any of the other notes that I found out in the wild.

I rebooted my new OpenVPN server, to burn an image of it, then, many hours later, fell into a long troubleshooting session: not sure of what had happened, but just finding that I suddenly couldn’t reach hosts other than my server, after connecting to it. It took me a while to realize that it was the instance stop/start that had caused the “failure”.

Very good tutorial, I was able to use it to get a simple server going. I just discovered that amazon is offering a simple VPS service called lightsail, a scaled back version of ec2. It’s only free for the 1st month, but $5.00 per month for their cheapest package, which includes 1tb of data. ec2 is free for the server but the cost per GB can add up quickly if you are using it as a vpn server. Cheers.

Hello, thank you very much for the guide, we are using it with no problems at all, just have one question, will it be possible to add a “dhcp pool” of address to auto-assign addresses ? We need like 6 or more concurrent users. Thank you

i’m not sure about a DHCP pool, but we are working on publishing a tutorial in the near future on how to set up easyrsa. That way you can assign certificates to multiple users instead of a single connection using the .ovpn key.

Excellent tutorial, I was wondering and have always kind of wondered, could implementing a process like this prevent your ISP from throttling your data or seeing how much data is being used? It seems that technically you are using Amazon’s data and that it would be kind of blocked behind Amazon, with the ISP only seeing the original connection. Am I interpreting this correctly? If not, is there anything I could do to get a setup that achieves this? Thanks a ton!

so long as you route your DNS requests thorugh the VPN, your ISP can only see that traffic is being transmitted, but not its destination or contents. there’s no way to avoid the ISP seeing how much data you’re using, as you’re still using their pipes and data centers to get traffic to Amazon.

Hi Paul,I am following the steps exactly as you mentioned. openvpn service is running under amazon linux. However I am getting “Missing External PKI” error when I try to connect to it. I know this is due to the key has been generated. is there any steps that I am missing here?

I am new to AWS and is trying to make below setup, Could you please let me know your view if it’s possible.

1. I have created Window Virtual Machine in AWS.2. I have an server installed on AWS EC2 which need to fetch some data from my laptop(Client) via SSH.3. As i am home user, is that a possibility that AWS Virtual Machine can ssh my home laptop. Which is connected to ISP router.

Thanks Paul,However, I made the mistake of “stopping” the instance once I was done. When I came back the next day and started it again VPN would no longer work. Obviously, I need also to Putty into it and tell it to start OpenVPN. OpenVPN thinks it’s working, but no web pages would load on my browser, so apparently a few more of the setup commands are needed. Not a problem while I’m in the free period, but I’ll want to be able to stop it when I won’t be using it for long periods. Can you point to how to easily put these all in a script that runs whenever the instance is started?

Also, is this a case where we should be using “elastic IPs”? When I restarted the assigned IP address is different, so had to modify the settings in the openvpn config file.

Yes the elastic IPs are helpful if you’re frequently starting/stopping. To make it work on startup, look into setting up OpenVPN Access Server. That will give you a web GUI to control things from and can be configured to run whenever the instance is running. A tutorial for this is in my queue but might be awhile before I get to it.

Well done, Paul, thank you so much. Was able to get it up and running relatively easily even though I’m a novice at this. I did have to add an entry to the security group for custom TCP to port 1194, but that was it. Now I’ll have to dig into RSA so I can get it working on multiple devices.

Can you include instructions for configuring using UDP rather than TCP transport? Why? Because TCP encapsulated within TCP can have horrible interactions when the ecapsulated TCP suffers timeouts (see http://sites.inka.de/bigred/devel/tcp-tcp.html).

Thanks. This is the only article online that covers exactly what I need. But unfortunately it doesn’t work. It missed some command somewhere and anyone must have found a way to fix it but forget or didn’t find time to mention it somewhere on the internet.So here’s the problem:TCP: connect to [AF_INET]XX.XX.XX.XX:1194 failed, will try again in 5 seconds: Connection refusedI got UDP/TCP for 1194 from anywhere open on my aws ec2 security group open.I checked the security group is assigned to the EC2 instance.I can ssh to the server so server is up and running.What I understood is that when we start the service on the server, there is no way to tell the service where to look for the conf file. I put random characters in the conf file and service was able to restart successfully! I even removed the conf file from the server and server was still able to restart successfully. Status says it is active and green.I’m sure the port 1194 is open. Because if I remove rules on aws security group the error is connection timed out. If I add them the error is connection refused. So the rules work. There is no server on the port to listen to the input. There is no log file created with name server-tcp.log anywhere on storage of the server. It apparently ignores the config file. Any idea?Thanks in advance.

Hello paul,Am very grateful for the time taken to put the write up together..I followed the process as described but after the setup on my putty connect while the other things like browsers refused to connect…What might be the cause of that please.

I have two Win10 x64 Pro desktops behind my ISP NATing router/firewall. According to google they both have the same IP. I’ve setup identical OpenVPN client configs on each. They both can establish a connection to an ec2 OpenVPN server configured per your instructions, but not simultaneously (the second one just hangs establishing the connection). I’ve looked through the OpenVPN server config but nothing’s jumping out at me. Do I need to config the server to listen on as many ports as I’ll have simultaneous client connections and then config each client to connect to one of those different ports each? Some other secret sauce?

Followed your year old recipe and I think it worked like a champ (the ec2 gui changed a bit but it was easy enough to figure out). I say I think because when I check https://www.iplocation.net/find-ip-address before and after, the after shows the EC2 IPv4 address. But if I type “What’s My IP” into Google before and after, it’s the same IPv6 address.

Is it working??? It doesn’t seem right that it should be the same IPv6 address

Unfortunately, IPv6 leaks are a common issue with OpenVPN on Windows 10 (not sure about other Windows versions). Windows sends out DNS requests on both IPv4 and IPv6 and uses whichever comes back faster to improve page load times. What most commercial VPNs do to get around this is disable IPv6 altogether and just use IPv4. You can do this in your network settings.

BTW, I’m running the OpenVPN GUI without Admin priv under up-to-date Win10 x64 Pro and Home and it works Just Fine. It’ll be interesting to see once the free year runs out how much it costs to keep it running. Does it cost anything for the ec2 instance to run idle/unused?

If I leave an instance running but don’t use it, it usually adds a $5 or less onto my bill. I’m running a few other instances as well and haven’t looked at the exact breakdown for how much an idle one costs.

I’ve had mixed results. I think Netflix has banned a range of EC2 IPs but not all of them. Luckily, unless you have an elastic IP set up, you can just reboot the instance to get a new IP and try again. Make sure you change you config as necessary.

Thanks for this easy to follow guide. I’m able to setup the VPN and connect to it using my windows client. I require two more things:1) How to access the OpenVPN admin interface via browser2) How to connect using Linux Client

The admin interface is a separate installation called OpenVPN Access Server. It’s not included in this tutorial but I’ll look into a separate tutorial for that later. As for your Linux client, it should be more or less the same thing but with your Linux terminal instead of PuTTy. Make sure you allow your Linux device to connect in your AWS security groups.

Hi, thanks for the tutorial! I’ve been looking to get a VPN started because of the Snooper’s charter that came into play in the UK (which is something I heavily dislike) but paid vpns seem to have quite a bit of problems, running from sites blacklisting their ips to speed and privacy issues. As such, I want to ask how safe is it to use Amazon as a server provider considering it is a US company (5 eyes and whatnot)? Is it possible that Amazon could keep logs of what website I visit if I have a VPN set up with AWS? Alternatively, what VPNs would you recommend which have a good mix of privacy and speed and which aren’t blacklisted from tons of site?Thanks

I suppose it’s always possible that Amazon could be logging activity but I highly doubt it. Unless you’ve included some mechanism that logs traffic on your VPN, then there won’t be anything other than some metadata in the server logs for them to see. You can even minimize this by lowering the verbosity in your server config.

As for what VPNs to use that aren’t blacklisted, NordVPN has been pretty reliable for me lately, and ExpressVPN is also good. You have to contact customer service to ask which server can unblock which sites.

Im facing the exact same issue. I’m running an unbutu instance tho, not Amazon Linux. Everything works and service is up, also the security group was checked several times. I even tried opening everything to anywhere.Didn’t work. Any suggestion?

I can connect to the client and my IP is the same as ec2, open vpn is connected, but I still can not get on to the sites that are blocked in my location i.e. China. I am wondering where did I go wrong?

first and foremost – thanks so much! Very mich appreciated.I have a little problem though. I can connect to the server, but can’t connect from there to the outside world. I’m probably making an obvious mistake.

Great post. Have you tried to create a layer 3 site to site tunnel using OpenVPN. I have using the openvpn access server web portal. However, where the server can talk(ping) to the client and vice versa, I can’t figure out how the server can talk to any other computers on the clients subnet. You don’t happen to know do you? Or at least the AWS side? Another tutorial perhaps. OpenVPNSite to Site with AWS tutorial?

Hi Jeff,Haven’t tested this myself but I think you can add this to your server config to “push” the DNS server to the client:push "dhcp-option DNS 10.11.12.13"Alternatively, you can set them in the client config using:dhcp-option DNS 10.11.12.13

Great tutorial!!! Thank you, Paul. After following OpenVPN instructions above, my public IP address is now my EC2’s IP address. I’m primarily using this when I am traveling abroad. When I go to http://www.whatismyipaddress.com, the EC2’s IP address is indicated but it shows my current foreign location. Any settings I can tweak to have the IP detected as within the US? My EC2 instance is in “N. California”.

Excellent article Paul. Do you know if it is possible to have username and password authentication from the client in static key mode? I am trying to convert your config to add username/password as a secondary check.-Steve

Any chance you might consider doing a parallel article for setting up in Azure? I have come very close, but some of the networking defaults on an Azure Linux VM seem to be different that Amazon and I’m not getting the packets forwarded from Azure to the destination site.

Thanks for the tutorial however I have a Mac so what do I do once I get to SSH tunneling? Also is there a tutorial to configure the client to use DNS on my AWS instance to prevent lookups on my client environment?

Hi Justin,We don’t have tutorials for Mac or setting up DNS with OpenVPN at this time. Once you get to SSH tunneling, you can choose to use a simple port forward+SOCKS proxy or set up the full VPN. Because Macs have a proper Unix terminal, you should be able to connect directly to the server through that instead of something like PuTTy.Best,Paul

where 172.31.0.2 is the address i found in /etc/resolv.conf.I am not sure if that is the same for all ec2 instances.Maybe there is a way to tell openvpn to use whatever address it finds in /etc/resolv.conf?

Hi Will,We’re working on a tutorial that should be finished in the next week or two for Linux users. If you need something before then, Google is your best friend. You could also try the OpenVPN forums.Best,Paul

Hi,I am behind a fortiguard firewall, could this be the reason I am getting:TCP: connect to [AF_INET] (my ip) failed, will try again in 5 seconds: Connection timed out (WSAETIMEDOUT)while trying to connect through OpenVPN?

443 is often reserved for HTTPS web traffic, so it might not work with OpenVPN. Try 119, 563, 1080, 1194, and 8080. You may need to install a special program to see what TCP ports are open in the firewall if those don’t work.

It’s difficult to say without seeing the server logs. Since it was working and then not working, it might be that your computer was assigned a new IP address which isn’t allowed on the AWS security groups. You can change your AWS security settings to allow all traffic on whatever port you want from any IP to avoid this.

Hi Paul,Thanks for the replies!I tried different ports, none work.I realized that the port on the server aren’t accessible. I used http://www.yougetsignal.com/tools/open-ports/ to check if the ports are reachable, but the only open port is 22. How can I port forward another port?

Well, you could try port 22 but it probably won’t be very fast as it’s usually just for SSH to a server. Without being able to control the firewall, I’m not sure what else to suggest. You could try a UDP setup, which would give you access to more ports, but that will require a different configuration and I’m not sure if it would even solve your problem.

Hi Vincent,That’s a pretty vague error, so I can’t diagnose it without more details. Find the server log and see if it gives you any more details. It should either be in the same directory as the config file as server-tcp.log or in /var/log/syslog or /var/log/openvpn.log

You can just import the same config file that you use on your PC, along with the associated key file, to whatever OpenVPN client you are using on those devices. Make sure to allow the IP addresses for those devices through the firewall using AWS security groups or iptables. However, if you want to connect multiple devices at the same time, you’ll need to create certificates for each, which gets more complicated. I don’t have a tutorial for that yet, but you can look into easy-rsa for generating these certificates.

I’m running into an issue where OpenVPN isn’t giving my workstation a DNS address. I followed the guide and can’t see if I missed anything. Manually set the adapter to Google Dns and it works. Any ideas?

Paul,Thanks for your guide. Unfortunately, it seems like my ISP blocking everything except traffic via 80/443 ports. Is there any way to overcome this limitation? Even if I set up source port 80 or 8080 in Putty it does not allow me to connect (timed out).Thanks.

Thanks for your help. Actually, I’ve tested my setup using mobile internet from my phone – everything was working smoothly (if I tried to connect on 8080 port), but didn’t work with my regular ISP. So, I assumed that 8080 port is also blocked or filtered. However, OpenVPN refused to connect on 80/443 (I think these ports accept only specific traffic). So, do you have any idea how deal with this issue?PS: I could connect my work laptop to the corporate network using Cisco Any.. vie the same wifi, which I use for my personal laptop. I tried to use port 4500 (UDP, usually used by Cisco) in my OpenVPN setup but it did not play well.

Hi Paul, great tut.. Out of curiosity I’m looking to have amazon act as a backup VPN service in the event our corp connection dies. Using your defined method is it possible to allow multiple users to connect to the new VPN service and from said service connect to our various VPC’s? on amazon?

Hi Austin,Yes, it is possible, but ideally you would use tls-auth instead of the pre-shared private key (ovpn.key in this tutorial) for multiple simultaneous users. You’ll need to generate different authentication credentials for each simultaneous user and make sure the appropriate ports are opened up so they can connect from their respective IP addresses. You can look into installing easy-rsa to generate TLS certificates.Best,Paul

I followed the directions and was able to VPN to my AWS server. What I would like to do now is create an ssh tunnel from AWS server to a linux server at my home. I put a hole in the firewall and can create a tunnel, however I can’t seem to pass RDP traffic accross that. i created tunnel like this “ssh -N -f -L3389:localhost:3389 “. when i try to run “telnet localhost 3389” i get this error on the remote computer “error: connect_to localhost port 3389: failed.” On the server in my home i ran this rule “firewall-cmd –add-forward-port=port=3389:proto=tcp:toport=3389:toaddr=192.168.1.225”. however the trafic seems to die at the end of the tunnel.

A VPN doesn’t change the maximum download speed allocated by your ISP, which is probably much less than 750 Mbps. On top of that, the encryption and re-routing of internet traffic that takes place with a VPN will slow your download speed down, usually by about 10 percent.

This a great tutorial, thanks! The only thing I’m stuck on is trying to get the VPN service to start automatically every time I restart my EC2 instance. I’d like it to run without having to login through SSH and manually start the openvpn service. Any suggestions?

I’m glad the article was helpful. I’m not sure how to help you with your router, though, as I don’t have a similar one on hand. If you know what type of firmware your router uses–DD-WRT, Tomato, etc–then that should point in the right direction with a Google search.

Well I definitely don’t like the idea of having to watch my data usage on my PC like I do on my mobile… but… I suppose it might be worth it protecting your online privacy, and it’s awesome that getting a free VPN is even possible at all! It looks pretty complicated but this guide should make it pretty easy, even for those of us that aren’t so tech savvy.