Why Your Own VPN Server
Setting up my own VPN server? That sounds rather complicated and unnecessary, considering a decent VPN, like Hidemyass costs less than $6/month. So, why would I bother setting up my own VPN server?
There are many commercial VPN services you can choose from (Hidemyass and TorGuard); most are inexpensive and easy to use. But running your own VPN gives you benefits most commercial VPN services can’t offer. First, when using any commercial VPN service, you share the server’s resources with other users (i.e. CPU, RAM); as more users connect to a VPN server, the slower it gets. With your own VPN server you don’t share, so you get maximum performance. Next, with any commercial VPN you’ll always wonder whether the VPN provider is spying on you. But that’s never a concern when you use your own VPN. Finally, streaming services like Netflix block IP addresses of commercial VPNs. Running your own VPN server makes it easier to circumvent the block.
Here I will show you how to set up your own VPN server and how to connect to it. This how-to gets a bit technical so make sure you follow carefully.
Step by Step Instructions
Choose Your Cloud Server (VPS)
The first thing you need is a Virtual Private Server (VPS). When choosing a VPS avoid the free offers; instead, select a low cost and reliable service like CloudSigma or DigitalOcean, where $5 monthly gets you a VPS with 512MB RAM, 20GB SSD and 1TB bandwidth – enough resources to stream videos or play online games.
Configure Your OpenVPN Server
- First, update your system to the latest version.
sudo apt-get update && sudo apt-get update -y
yum install http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
- Next, install OpenVPN and Easy-RSA. OpenVPN is a robust and highly flexible VPN software that uses all of the encryption, authentication, and certification features of the OpenSSL library to implement virtual private network (VPN) techniques. Easy-RSA is a small RSA key management package based on the openssl command line tool. We’ll use it to generate certificates and manage (private) keys.
sudo apt-get install openvpn easy-rsa -y
yum install openvpn easy-rsa -y
- We’ll now copy all VPN configuration files to “/etc/openvpn/”.
# Copy the sample configuration files of OpenVPN and easy-rsa to "/etc/openvpn"
cp -r /usr/share/easy-rsa/ /etc/openvpn
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/ && sudo gzip -d /etc/openvpn/server.conf.gz
# Copy the sample configuration files of OpenVPN to "/etc/openvpn" cp /usr/share/doc/openvpn-2.3.2/sample/sample-config-files/server.conf /etc/openvpn # Copy the sample configuration files of easy-rsa to "/etc/openvpn" cp -R /usr/share/easy-rsa /etc/openvpn
- OpenVPN uses PKI (Public Key Infrastructure) for authentication. The client must authenticate the server certificate and the server must authenticate the client certificate before a connection can be established. In the following steps we’ll create 3 pairs of certificates and their associated keys. The first pair is for the server and the second pair is for the client. The last pair is the root certificate (also known as CA, or Certificate Authority), and its private key, which will be used to sign server and client certificates. You create the key-pairs using Easy-RSA:
cd /etc/openvpn/easy-rsa/ # At the command prompt, enter the following command su root # Notice the space between . and vars. . vars # Remove all certificates created previously. ./clean-all # Build the certificate authority (CA) certificate and key. # Pick a unique name as "Common Name". Other fields can be left blank. # To leave a field blank, enter "." ./build-ca # Generate a certificate and private key for the server. # Pick a unique "Common Name" such as "server". # Enter "." when prompted for a challenge password. ./build-key-server server # Build Diffie-Hellman parameters for the server. ./build-dh # create a certificate for the client: 97228. # Pick a unique "Common Name" such as "97228". # Enter "." when prompted for a challenge password. ./build-key 97228 # Repeat the above command should you need to add more clients.
cd /etc/openvpn/easy-rsa/2.0 # Edit the vars script to use the correct path. vi vars # Change line: export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA` to export KEY_CONFIG=/etc/openvpn/easy-rsa/2.0/openssl-1.0.0.cnf # Back at the command prompt, use the following command to reflect the changes. # Notice the space between . and vars. . vars # Remove all certificates created previously. ./clean-all # Build the certificate authority (CA) certificate and key. # Pick a unique name as "Common Name". Other fields are optional. ./build-ca # Generate a certificate and private key for the server. # Pick a unique "Common Name" such as "server". # Enter "." when prompted for a challenge password. ./build-key-server server # Build Diffie-Hellman parameters for the server. # This operation may take a while to complete. ./build-dh # create a certificate for the client: RobbC. # Pick a unique "Common Name" such as "RobbC". # Enter "." when prompted for a challenge password. ./build-key RobbC # Repeat the above command should you need to add more clients.
- Now we’ll transfer 3 files: ca.crt, 97228.crt, and 97228.key from the “/etc/openvpn/easy-rsa/keys/” directory on the server to the client. Create 3 text files on the client with the same names. On the server, use the “cat” command to display the contents of each file. Copy & paste the contents of each file to the corresponding file on the client.
- We’ll now edit the OpenVPN server configuration file located in: “/etc/openvpn/server.conf”.
# Edit the server configuration file. sudo vim /etc/openvpn/server.conf # Include the followings settings. # Which TCP/UDP port should OpenVPN listen on? port 1194 # TCP or UDP server? proto udp # Create a routed IP tunnel dev tun # Point to our ca, cert, key, and dh files. ca /etc/openvpn/easy-rsa/keys/ca.crt cert /etc/openvpn/easy-rsa/keys/server.crt key /etc/openvpn/easy-rsa/keys/server.key # This file should be kept secret dh /etc/openvpn/easy-rsa/keys/dh2048.pem # Supply a VPN subnet for the server and clients server 10.8.0.0 255.255.255.0 # Assign the previously used IP address ifconfig-pool-persist ipp.txt # Redirect all IP traffic through the VPN push "redirect-gateway def1 bypass-dhcp" # The addresses below refer to the DNS servers from # Comodo DNS. Change to Google DNS should you prefer. push "dhcp-option DNS 184.108.40.206" push "dhcp-option DNS 220.127.116.11" # Allow multiple clients to share the same certificate/key files. duplicate-cn keepalive 10 120 # Enable compression comp-lzo # reduce the OpenVPN daemon's privileges after initialization. user nobody group nobody # The persist options persist-key persist-tun # Logging options status openvpn-status.log log-append /var/log/openvpn.log verb 3 # Add an extra username/password authentication for clients plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so login
# Edit the server configuration file. cd /etc/openvpn vi server.config # Include the followings settings. # Which TCP/UDP port should OpenVPN listen on? port 1194 # TCP or UDP server? proto udp # Create a routed IP tunnel dev tun # Point to our ca, cert, key, and dh files. ca /etc/openvpn/easy-rsa/2.0/keys/ca.crt cert /etc/openvpn/easy-rsa/2.0/keys/server.crt key /etc/openvpn/easy-rsa/2.0/keys/server.key dh /etc/openvpn/easy-rsa/2.0/keys/dh2048.pem # Supply a VPN subnet for the server and clients server 10.8.0.0 255.255.255.0 # Assign the previously used IP address ifconfig-pool-persist ipp.txt # Redirect all IP traffic through the VPN push "redirect-gateway def1 bypass-dhcp" # The addresses below refer to the DNS servers from # Comodo DNS. Change to Google DNS should you prefer. push "dhcp-option DNS 18.104.22.168" push "dhcp-option DNS 22.214.171.124" # Allow multiple clients to share the same certificate/key files. duplicate-cn keepalive 10 120 # Enable compression comp-lzo # reduce the OpenVPN daemon's privileges after initialization. user nobody group nobody # The persist options persist-key persist-tun # Logging options status openvpn-status.log log-append /var/log/openvpn.log verb 3 # Add an extra username/password authentication for clients plugin /usr/lib/openvpn/plugin/lib/openvpn-auth-pam.so login
- Next, we’ll create a user account for each client so we can authenticate each VPN client by username and password.
# Create a user account with no home directory and shell access. sudo useradd 97228 -M -s /bin/false sudo passwd 97228
- Next, we’ll make a few changes to finalize the setup: enable IP forwarding, automatically start the VPN service when the system boots, adjust the firewall settings to allow VPN traffic.
# Enable IP forwarding sudo vim /etc/sysctl.conf # Uncomment the next line to enable packet forwarding for IPv4 net.ipv4.ip_forward=1 # Save and apply changes. sudo sysctl -p /etc/sysctl.conf # Save the firewall rules to a file sudo sh -c "iptables-save > /etc/iptables.rules" # Load the firewall rules before the eth0 interface is alive sudo vim /etc/network/interfaces # add the next line at the end of "iface eth0" section pre-up iptables-restore < /etc/iptables.rules
# Enable IP forwarding vi /etc/sysctl.conf # Change net.ipv4.ip_forward = 0 to: net.ipv4.ip_forward = 1 # Save and apply changes. sysctl -p # Start OpenVPN server at system startup. chkconfig openvpn on # Allow our VPN subnet in firewall iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE service iptables save
- (Optional) You can assign your VPN server a DigitalOcean floating IP. A floating IP is a static IP address you can re-map instantly to any VPS, or Droplet. This gives you two major benefits: redundancy, and an extra IP address which is useful when your original IP address is blocked by certain websites. Network traffic between a floating IP and a Droplet flows through the anchor IP that is aliased to a Droplet’s public network interface (
eth0). To make your VPN server accessible by its floating IP, make sure your VPN server is configured to listen on its anchor IP. To display your anchor IP, use the following command.
sudo ip addr show eth0
Next, update the VPN server configuration file to use the anchor IP. Adjust the firewall to allow traffic using the anchor IP.
sudo vim /etc/openvpn/server.conf # Add your anchor ip after 'local' like the following # Which local IP address should OpenVPN # listen on? (optional) local 10.10.0.5 # Adjust the firewall to make OpenVPN traffic go through the anchor IP. sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to 10.10.0.5 sudo sh -c "iptables-save > /etc/iptables.rules" # Restart the OpenVPN service sudo service openvpn restart # Check logging messeges sudo journalctl --identifier oven-server # Fix error: TCP/UDP: Socket bind failed on local address [AF_INET]x.x.x.x:1194: sudo vim /lib/systemd/system/openvpn.service
Configure Your OpenVPN Client
Your VPN server should now be fully functional and ready to connect with a client (device). To connect a client to the server, first install the OpenVPN software on the client. Next, configure the client to communicate with your VPN server. For a mobile client, install the OpenVPN Connect App; for a desktop computer, download the Tunnelblick App.
Now I will show you how to set up a VPN client on a desktop computer using Tunnelblick.
First, create a folder to contain the configuration files. You can name this folder anything you like as long as it ends with .tblk (so Tunnelblick can access the configuration files). I named my folder NY-97228.tblk to remind me the folder contains the configuration files for VPN user: 97228. The “NY” prefix indicates the VPN server is located in New York.
Next, select the 3 files you transferred from the server to the client in step 5 and copy the files to your .tblk folder. Right click here and save my sample VPN configuration file (config.txt) to your .tblk folder.
Now, open config.txt in a text editor and replace: MY-SERVER-IP, CA-CERTIFICATE.crt, CLIENT-CERTIFICATE.crt, and CLIENT-KEY.key with your own settings by following the comments (lines with a “#” prefix) above each setting. Once you’ve done editing your file, rename it config.conf.
Here is what the sample “config.txt” looks like.
# Sample client-side OpenVPN configuration # Edit this file by following the instructions here: # https://vpntips.com/how-to-setup-a-vpn-server/ # Lines starting with ‘#’ or ‘;’ are comments # Specify that this is a client. client # Specify the interface to use. Use the same interface the server uses. ;dev tap dev tun # Choose a protocol: TCP or UDP. Use the same protocol the server uses. ;proto tcp proto udp # Specify the IP address (or fully qualified domain name) # and port of the server. remote MY-SERVER-IP 1194 # Keep resolving the host name of the server indefinitely. resolv-retry infinite # No need to bind to a specific local port number. nobind # Downgrade privileges after initialization (non-Windows only) user nobody group nobody # Try to preserve some state across restarts. persist-key persist-tun # Specify the names of your CA certificate, client certificate, and client key. ca CA-CERTIFICATE.crt cert CLIENT-CERTIFICATE.crt key CLIENT-KEY.key # Protect against sMIM attack remote-cert-tls server # Authenticate client by username/password auth-user-pass # Enable compression on the VPN link. comp-lzo # Set log file verbosity. verb 3
Finally, you need to allow Tunnelblick to access the configuration files. To do this, drag your .tblk folder and drop it on the Tunnelblick icon in the menu bar, or on the list of configurations located in the Configurations tab of the VPN Details window.
That’s it! Now you’ve got your own VPN server. If you encounter any errors during the setup, please let me know in the comment section below.
Got a question? Post it in our forums. We’ll work it out.