Jack Moore

Email: jack(at)jmoore53.com
Project Updates

Client-To-Client OpenVPN Connection

01 Jun 2019 »

I wanted an OpenVPN server so I could create a public-private network where I could access my local development machine without having to fully expose it to the wide open internet and mess with my home network connection. This was the EC2 VPN solution I came up with.

When I say public-private network, I mean a private network only accessable by me, but accessable from anywhere.

OpenVPN Server Setup Instructions

SSH into any cloud or publically accessable server with OpenVPN and EasyRSA3 installed, and change to the root user of the machine using sudo -i.Why sudo -i you ask?

Easy RSA can be found on the server in /etc/openvpn/easy-rsa/3.0.3 or /usr/share/easyrsa/3.0.3 after being installed. This location is important based on where you run the ./easyrsa commands.

For easyrsa3, commands start with ./easyrsa. I was looking at easyrsa2 documentation and easyrsa2 had a directory with all the commands which threw me off. EasyRSA3 commands start with the ./easyrsa and the arguments are subcommands and options.

For this easy and simple setup, I didn’t configure a dedicated CA server, so I used the OpenVPN Server tools provided for setting up a CA and public key infrastructure (pki). These were the commands I used for an insecure test ca & vpn server. Please note this is in no way a production server and was only used in a demo.

# Creates a pki folder in the current directory
/easyrsa init-pki

# Builds the Certificate Authority
./easyrsa build-ca nopass

# Generates a Diffie-Helllman Key
./easyrsa gen-dh

# Generates the Server Keys
./easyrsa build-server-full ovpntest0 nopass

# Generates a client's keys
./easyrsa build-client-full client1 nopass

# Moving all the files to their locations for easier access for the OpenVPN Server
cp pki/ca.crt /etc/openvpn/ca.crt
cp pki/dh.pem /etc/openvpn/dh.pem
cp pki/issued/vpn-server.crt /etc/openvpn/server.crt
cp pki/private/vpn-server.key /etc/openvpn/server.key
cp pki/ta.key /etc/openvpn/ta.key
cp pki/crl.pem /etc/openvpn/crl.pem

Of note in this set of commands, I did not generate a revokation list and the server is pretty barebones. The dh.pem and ca.crt files end up in the root of the ./pki directory, and the public issued *.crt files are in the ./pki/issued folder and the private keys *.key are in the ./pki/private folder. When these files are generated, usually an output location is provided (I just made sure the keys were created, I didn’t look where they went).

Configuration Files

Change the necessary openvpn configuration files to match the locations of the public and private keys.

Server Configuration


proto tcp
port 1194
dev tun

ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh /etc/openvpn/dh.pem

keepalive 10 60

push "route"
topology subnet

user nobody
group nobody

sudo openvpn --config example-client-config.conf will get you up and running from the server machine.

For security reasons, the OpenVPN process switches to user and group nobody after running the root commands and finishing them. Even if a remote attacker was able to compromise the OpenVPN process, the security breach would be contained to the user nobody instead of the user root.1

Running export OVPN_ADDR=$(curl will get you the public IP of the cloud instance, and this ip will be used in the client configuration. Note what is being run is native to most cloud platforms and is a tool that will provide information about the machine. In this case it is grabbing the public ipv4, but I am only putting the IP for the blog post to prevent abuse and spam of the IP address. In my prod server I replaced the script with the hardcoded ipv4 address.

I also decided tcp because I would be SSH’ing into machines and needed the extra ACK packet.. If this VPN were for streaming or torrenting, I would have used UDP. Google and the mailing list do a decent job explaining the differences between tcp and udp…, but I also plan to read this book on TCP

With systemd on the aws-linux, I ran sudo mv ~/example-server-config.conf /etc/openvpn/server.conf and then ran sudo systemctl start openvpn@server moving the config to the openvpn folder, and then OpenVPN ran as it’s own systemd service with the server.conf configurations. I made sure it was running with sudo systemctl status openvpn@server, and this checked everything was up.1

Client Configuration

scp down the ca.crt, client1.crt and client1.key files into a location where you can easily find them. I used mkdir -p ~/Documents/ovpn/test and sercure copied everything down to that folder. The SCP command looked like:

scp -i ~/loc/ssh/key.pem nobody@ ~/Documents/ovpn/test

Obviously I have changed some of the values, but this was the gist of the command.

Enable Client Forwarding with sudo sysctl -w net.inet.ip.forwarding=1 on mac and sudo systctl -w net.ipv4.ip_forward=1 on ubuntu to allow them to connect to one another. It is unreccommended to forward ports except from a router as port forwarding essentially turns a computer into a router.


proto tcp
remote $OVPN_ADDR
port 1194
dev tun

ca /home/jack/Documents/ovpn/test/ca.crt 
cert /home/jack/Documents/ovpn/test/client1.crt
key /home/jack/Documents/ovpn/test/client1.key

Note $OVPN_ADDR in the remote line won’t read from the environment so you will need to hardcode the IP address in to the client config file. You will also need to change the ca, cert and key lines to point at the correct files.

sudo openvpn --config example-client-config.conf will get you up and running from a client machine.

Testing Speed

Using iperf I was able to test the network speed over the VPN. For this I installed iperf on my mac with brew install iperf and on ubuntu with sudo apt install iperf. I then ran the server with iperf -s on the machine with the ip of and iperf -c from the machine with the IP of This then gave the speed test.1


Everything else I am doing or would like to do.


In the future I would like to get a Site-to-Site configuration set up, as well as routing from something like pfsense to the internal VPN network for services.

I know pfsense offers an openvpn extension and I looked into this as the first solution, but AWS does some weird NAT to the internal network VPC address and I was looking for more a basic Proof of Concept with this setup, not a behemoth ultracuztomized router-VPN setup. I will look into something like this when I move to a hybrid cloud.


I want the non-vpn “server” to automatically connect to the vpn server and I also need to daemonize the vpn application.. This will amount to better availability.

© Jack Moore