Blog

Setting up a simple open source peer-to-peer VPN

Setting up a simple open source peer-to-peer VPN

VPN, or Virtual Private Network, allows you to create a secure connection to another network over the Internet which can be very beneficial for some use cases. VPNs can be used for many things, for example - access region-restricted websites, shield your browsing activity from bad guys on public Wi-Fi, connect and use local resources which are inaccessible from the outside world or simply create a secure network between your servers and isolate them.

So, what are the common steps for creating a VPN. You need to first connect to the public internet through the ISP (Internet Service Provider), then initiate a VPN using a client software. Sounds easy, right?

Well it depends on the software you choose, whereby most of the VPN solutions follow the client-server principle.
That means, all nodes connect to e central server which is the central point to all others. By such environment, the whole traffic passes through the central server creating a star topology, so this server needs lots of bandwidth. In case that the central server fails and it’s not able to handle the whole traffic, the VPN will go down and the other members will not be able to communicate. This is the main disadvantage by such setting.
So, if you don’t want to have that single point of failure, you can use a full mesh topology, where every participant talk to the others without having a central server. If one of them fails, the other members will not be affected. A good, simple and reliable peer-to-peer/full mesh solution is the PeerVPN.

Here is a short guide for installing and configuring of the PeerVPN software on RHEL:

1. Make sure that you can ping every server on its public IP.

2. Installing the necessary dependencies:
$ yum install gcc -y;
$ yum install openssl-devel -y;
$ yum install openssl -y;
3. Downloading the PeerVPN client:
$ curl -O http://peervpn.net/files/peervpn-0-044.tar.gz;
4. Unarchaving and compiling the software:
$ tar xzfv peervpn-0-044.tar.gz && cd peervpn-0-044 && make
5. Moving the binary:
$ cp peervpn /usr/sbin;
6. Create and edit the config file:
$ mkdir /etc/peervpn && nano /etc/peervpn/peervpn.conf
Sample content of the config file, with comments:

// This is the default UDP port which the PeerVPN uses. You can change it, but make sure that you have open in/outbound connection for this port (if you are server has iptables : iptables -S)
port 7000

// this is the network name which can be anything you want
networkname MyPeerVPN

// this is a generated 512 shared key for encrypting the traffic between the peers. If you want to use encryption, make sure that the key is the same on each host. Use this command to create one:
$ openssl rand -base64 382 | tr -d '\n' && echo
//IMPORTANT: don use the same key from my example below

Psk VqmWsJje18/qqIOEN2+pLHugDtAcN5So03J0TL9wIQomAkQwcNR23SzM+m7cuJyCeyXXuHDLoKbzVbk
176eDVLPS8wLNoWSiwPF2yQn57Q4vjRz3qjI51nhE3yEyKmHZgotQga4Uz0vyvTGjJRxtPJqZ/igDN0YmI2
5nwhsYsyi34c6pIcqPCOHYlILndCUh8AYk3hGNPc0lSnkxW/sY+Uo+5BU0K6nB1LYcMlXA9Ij0deU+eyRTfoVg
gKnpXdl5FikrELbAOyoo71F0PEjL73k5fmyGmsoEE1f4yvgUXOKOzsPUaf567SP4Hm+h/EpqkWMR7JGc5
jBDsOlY52LTp5XaZNn+l+VEInCsFQiKgTW3zvzSmUcrPB3GqQ1KXknwfHmtCJe4SRiRZLKtSeTiPdPvXC0HBM
k+KK9TNk45dDUi3/ougCIwavMPEedH7Gh5fvG5iNXjZ24tAAOTle2oBHVgO2Wq7llh2VwKkrzyYATuchus
VLbHa98D0YR2wA==

enabletunneling yes

// This is the name of the network interface ( like eth0 )
interface pvpn0

// this is the IP address range. Note that every peer should have a unique one in the same subnet, so simply increment the address for each new server. In my example I have the 10.1.1.1 , which will be the IP of the initialization peer.
ifconfig4 10.1.1.1/24

//the initpeers is the initial host (its public IP/hostname + port) which has to be connected in order to discover the other hosts from the private network. This directive should be included only in the config files of the second, third... hosts
initpeers 165.165.165.165 7000

So here are two sample config files, the left is for the initialization peer and the right is for the other hosts:

port 7000
networkname MyPeerVPN
psk VqmWsJje18/qqIOEN2+pLHugDtAcN5So03J0TL9wIQomAkQwcNR23SzM
+m7cuJyCeyXXuHDLoKbzVbk176eDVLPS8wLNoWSiwPF2yQn57Q4vjRz3qjI51
nhE3yEyKmHZgotQga4Uz0vyvTGjJRxtPJqZ/igDN0YmI25nwhsYsyi34c6pIcqPC
OHYlILndCUh8AYk3hGNPc0lSnkxW/sY+Uo+5BU0K6nB1LYcMlXA9Ij0deU+ey
RTfoVggKnpXdl5FikrELbAOyoo71F0PEjL73k5fmyGmsoEE1f4yvgUXOKOzsPU
af567SP4Hm+h/EpqkWMR7JGc5jBDsOlY52LTp5XaZNn+l+VEInCsFQiKgTW3z
vzSmUcrPB3GqQ1KXknwfHmtCJe4SRiRZLKtSeTiPdPvXC0HBMk+KK9TNk45d
DUi3/ougCIwavMPEedH7Gh5fvG5iNXjZ24tAAOTle2oBHVgO2Wq7llh2VwKkr
zyYATuchusVLbHa98D0YR2wA==
enabletunneling yes 
interface pvpn0 
ifconfig4 10.1.1.1/24 

port 7000
networkname MyPeerVPN
psk VqmWsJje18/qqIOEN2+pLHugDtAcN5So03J0TL9wIQomAkQwcNR23SzM
+m7cuJyCeyXXuHDLoKbzVbk176eDVLPS8wLNoWSiwPF2yQn57Q4vjRz3qjI51
nhE3yEyKmHZgotQga4Uz0vyvTGjJRxtPJqZ/igDN0YmI25nwhsYsyi34c6pIcqPC
OHYlILndCUh8AYk3hGNPc0lSnkxW/sY+Uo+5BU0K6nB1LYcMlXA9Ij0deU+ey
RTfoVggKnpXdl5FikrELbAOyoo71F0PEjL73k5fmyGmsoEE1f4yvgUXOKOzsPU
af567SP4Hm+h/EpqkWMR7JGc5jBDsOlY52LTp5XaZNn+l+VEInCsFQiKgTW3z
vzSmUcrPB3GqQ1KXknwfHmtCJe4SRiRZLKtSeTiPdPvXC0HBMk+KK9TNk45d
DUi3/ougCIwavMPEedH7Gh5fvG5iNXjZ24tAAOTle2oBHVgO2Wq7llh2VwKkr
zyYATuchusVLbHa98D0YR2wA==
enabletunneling yes
interface pvpn0
ifconfig4 10.1.1.1/24 
initpeers 165.165.165.165 7000

In order to add one more host, simply copy the right configuration and set the next possible IP(ifconfig4) from the range

7. Create a system unit file in order to start the network on boot:
$ nano /usr/lib/systemd/system/peervpn.service
[Unit]
Description=PeerVPN network service
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/sbin/peervpn /etc/peervpn/peervpn.conf
[Install]
WantedBy=multi-user.target

8. Start and enable the PeerVPN:
$ systemctl start peervpn.service
$ systemctl enable peervpn.service
9. Check the service for listening:
$ netstat -tupanl | grep peervpn
The output should look like this (if IPv6 is enabled):

udp 0 0 0.0.0.0:7000 0.0.0.0:* 5766/peervpn
udp6 0 0 :::7000 :::* 5766/peervpn

10. Ping each host using the VPN IP address