A demo project for the setup of VPN tunnels on Linux platform
The server and client programs will create host-to-host tunnels using TUN/TAP. The payload of UDP packets transmitted in the channel are protected via anthenticated encrytion with associated data (AEAD). In this project, plaintext is first encrypted with AES256-CBC and then a MAC is generated by hash function from ciphertext. To convey the initial vectors of encryption algorithm and the session key of HMAC, two tunnel points first establish SSL connection and exchange information, which requires a trusted certificate authority (CA).
(Optional) Create a self-signed certificate authority (CA)
$ openssl req -new -x509 -keyout ca.key -out ca.crt -config openssl.cnf
For the server and each client, create a key pair and generate a certificate signing request (CSR). Then ask the self-signed CA or a third-party trusted CA to generate a certificate for server/client.
$ openssl genrsa -des3 -out server.key 1024
$ openssl req -new -key server.key -out server.csr -config openssl.cnf
$ openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key -config openssl.cnf
Set the paths for the keys and certificates of CA (ca_pem
), server(server_crt
, server_key
), clients(client_crt
, client_key
) in VPN_server.c and VPN_client.c files.
The default maximum client number MAX_CLIENT
is 30. It can be changed in VPN_server.c file.
$ gcc -Wall -o VPN_server VPN_server.c -lssl -lcrypto
$ gcc -Wall -o VPN_client VPN_client.c -lssl -lcrypto
Assume we setup VPN tunnels in tun0
interface. The server program runs on the server machine with IP address of 192.168.15.12.
On server machine
$ sudo ./multiVPN_server -i tun0 -s -d -p 5556
where
-i
(required) specify interface name
-s
(required) indicate this is a server program
-p
(optional) specify UDP port (default 55555)
-d
(optional) enable debug mode
Similarly, on each client machine
$ sudo ./VPN_client -i tun0 -c 192.168.15.12 -d -p 5556
where
-i
(required) specify interface name
-c
(required) indicate this is a server program and specify server IP address
-p
(optional) specify UDP port (default 55555)
-d
(optional) enable debug mode
On each machine, open another terminal and configure tun0
interface, for example
$ sudo ip addr add 10.0.1.1/24 dev tun0
$ sudo ifconfig tun0 up
Then set up the routing paths between the server and clients. Assume the ip address of the tunnel point A (server) is 10.0.1.1/24 and that of the tunnel point B (client 1) is 10.0.2.1/24.
On server machine,
$ sudo route add -net 10.0.2.0 netmask 255.255.255.0 dev tun0
On client 1 machine,
$ sudo route add -net 10.0.1.0 netmask 255.255.255.0 dev tun0
Now you can use the UDP tunnel, for example, on client 1 machine, try ping and ssh commands:
$ ping 10.0.1.1
$ ssh 10.0.1.1
The server program needs to release resource for SSL when a client program is terminated. Enter exitVPN
on client terminal when you quit the program.
To increase security of authenticated encryption, the program offer the functions to change session key for HMAC and initial vector for AES256-CBC. Simply enter resetKEY
or resetIV
on client terminal and the new session key or initial vector will be sent to server via SSL connection.