You are not logged in.

#1 2016-11-11 10:57:20

bubbajack
Member
Registered: 2016-10-21
Posts: 8

OpenVPN server/client basic and lighthearted Tutorial

G'day, fellow Bunsen users.

I extensively use OpenVPN for the noble purpose of gaming and find it to be much more valuable, flexible and secure than server-based solutions of the kind of Logmeinside (do you think I used too recognizable a name?).

I had some difficulties in configuring a server for the fist time, and while there are solutions like PiVPN that are extremely simple, they tend to only work on Raspberry Pi.
I have one and love it, but I prefer universally applicable information, so thought of writing down how I set up my openVPN server on debian (bunsenlabs, actually) to help users not too familiar with the technology to set up their own, and to share my informations, of course.
The shown setup won't tunnel the clients' connection through the vpn.

ENVIRONMENT PREPPING----------------------------------------------
First things first: install the relevant packages

        ~# apt-get install openvpn easy-rsa

Make an easy-rsa directory:

	~# cd /etc/openvpn
	~# mkdir easy-rsa
	~# make-cadir easy-rsa

The last command will copy all the template files from the easy-rsa installation into the easy-rsa directory we just created.
#-----------------------------------------------------------------



CERTIFICATE CREATION----------------------------------------------
Change into the easy-rsa directory

	~# cd easy-rsa

Edit the easy-rsa config file

	~# nano vars

NB I use nano because I don’t feel like I’m in need to show other people that I’m pro. You can use whatever text editing sw you like (avoiding M$’s notepad, it would screw up all the formatting).
Don’t worry, I won’t tell your geek friends you didn’t use vi to get the job done wink .

Inside this file there’s a variable, EASY-RSA. We need to change it to the directory we created half a page ago, so we need to take it from this

	export EASY_RSA="`pwd`" 

to this

	export EASY_RSA="/etc/openvpn/easy-rsa"

A little bit farther, there’s a line for setting the Diffie Hellman  exchange key size. I usually set it to 2048. If you’re working for Al-Quaheda or are planning to use the in potentia VPN to chat with your Delilah and don’t want your gf to crack your pc to set off a civil war that would pull Cap. America outta his socks, you can use a 4096 sized key. Be aware, though, that such a key will slow down exchanges during logins and, most notably, will take forever to create. I strongly advice you against using such a key with a Raspberry Pi sized server or, worse, with a netbook.

	export KEY_SIZE=2048

Then, scrolling down, you will find a bunch of yadda yadda that looks something like this:

	# These are the default values for fields
	# which will be placed in the certificate.
	# Don't leave any of these fields blank.
	export KEY_COUNTRY="US"
	export KEY_PROVINCE="CA"
	export KEY_CITY="SanFrancisco"
	export KEY_ORG="Fort-Funston"
	export KEY_EMAIL="me@myhost.mydomain"
	export KEY_OU="MyOrganizationalUnit"

I don’t know why there’s people caring about them (and for what I just said I see gigabytes of SenseOfHumor-free devs’ e-mails coming through my mailbox blowin it up to smithereens). Ok actually I know why people changes them, but they're of no use for us gamers.

Now we're gonna create the actual certificates.
First, source the vars file. This is like telling easy-rsa “ok now that I modded your parameters to my liking I want you to aknowledge that”.
Enter this command:

	~# source ./vars

He should almost immediately say something like “NOTE: if you run ./clean-all, I will be doing a rm -f on /yadda/yadda”, so it should everything be fine.
If instead he makes you alert that you should edit the vars file to your needs, check the EASY_RSA variable directory you entered earier, maybe there's a typo. Beware of typos: in cryptography every small typo gets multiplied and nothing is gonna work afterwards. So, please, double check everything you type in.

	~# ./clean-all
	~# ./build-all

The last command will ask you to interactively change the values I talked about earlier. You can safely just keep on hittin return, Window$ $tyle.

Type the following:

	~# build-key-server server

Note that I called the server “server” so its certificates will be named “server.xxx”. I dunno why on Earth would you want to call your server with a different name, by if you're willing to do so, go on with Crom's blessing.
        DO NOT ENTER A CHALLENGE PASSWORD! LEAVE IT BLANK!
#-----------------------------------------------------------------



CLIENT CERTIFICATES-----------------------------------------------

Now we will be creating certificates for all of our clients (smartphones, laptops etc).
We created our own CA (certificate authority) so we’ll be able to add more certificates later, if this need arises.

	~# ./build-key-pass User1 

Where “User1” is the name of the client. You can name it whatever you want.
Please note that this command is gonna create a certificate that will require a password to be typed every time the client wants to connect to the VPN. If you want to make a client certificate that does not require to enter a password, use the following command instead:

	~# ./build-key User1

Now, if we choose to protect the certificate with a pass phrase, the script is gonna ask for it:

	Enter PEM pass phrase:

This is the password I was talking about. Type it in after you wrote it down somewhere else.
As usual, leave blank the challenge password field.
Now, let’s change the certificate encryption scheme to a newer model called des3. It’s mandatory for some modern OpenVPN clients:

	~# cd keys
	~# openssl rsa -in User1.key -des3 -out User1.3des.key 

Remember to check whether you used “User1” as the client’s name or something else.
The script will ask some questions:

	Enter pass phrase for User1.key

Enter the pass phrase we specified earlier.

	Enter PEM pass phrase

Enter it again.
Now let’s go to /etc/openvpn/easy-rsa/:

	~# cd ..

Now, to build the Diffie-Hellman keys to let server and client exchange keys:

	~# ./build-dh

Using 2048bit encryption, this could take some time. If you chose 4096, well, you’re free to hang out with your favorite bunch of friends, having some beer.
Now, add DDoS-attack protection to your server. It’s built in OpenVPN, so just launch this command:

	~# openvpn --genkey --secret keys/ta.key

#-----------------------------------------------------------------




CONFIGURING OpenVPN-----------------------------------------------

This is the final step in server configuration, and usually it is not the worst part.

	~# nano /etc/openvpn/server.conf 

You’ll find a huge text file. Let’s see the most important bits (with the lines we’re about to check you can build from a totally blank file a working OpenVPN server. So, if for some reason you cannot find a conf file template, just read on):

1.	local 192.168.x.x

Swap 192.168.x.x with your server’s static IP.

2.	dev tun

Now, some people may want to use dev tap, instead. It depends on the final target of your server. AFAIK, a tap interface, in conjunction with bridging, is more suited for heavy data trasfers and videogames. I, however, use this server for a variaty of purposes including: a Privoxy proxy server, file server, game server (minetest, ArmA 2).
I never experienced issues due to some alleged bottleneck effect.

3.	proto udp

Again, it’s about choices. The udp protocol is well suited for most purposes and reasonably fast. A tcp protocol, while more robust (?) would be slower.

4.	port 1194 

Your free choice. I used all kinds of ports with OpenVPN. Just be sure to use one that is not gonna conflict with some other service. And be sure to forward this port on your router (and on your server’s firewall).

5.	ca /etc/openvpn/easy-rsa/keys/ca.crt 

Directory of your Certificate Authority certificate.

6.	cert /etc/openvpn/easy-rsa/keys/server.crt

MY SERVER CERTIFICATE IS CALLED server. IF YOU USED ANOTHER NAME DURING ITS CREATION, PLEASE CORRECT THIS LINE ACCORDINGLY.

7.	key /etc/openvpn/easy-rsa/keys/server.key

Idem.

8.	dh /etc/openvpn/easy-rsa/keys/dh2048.pem

Directory the the Diffie-Hellman key exchange file.

9.	server 10.8.0.0 255.255.255.0

You can leave this mask as it is. Specifying this server line, you’ll have a 10.8.0.x subnet in your VPN. Should be fine for most of the dudes.

10.	ifconfig 10.8.0.1 10.8.0.2

Server and remote endpoints. All clients will be able to reach the server at the address 10.8.0.1.

11.	push "route 10.8.0.1 255.255.255.255"
12.	push "route 10.8.0.0 255.255.255.0"

Those two lines route the vpn subnet and server to the client.

13.	push "route 192.168.x.x 255.255.255.255"

This is a dangerous line. If you’re not really at ease in working with subnets it’s better to comment this one out. If you enter your server’s address in place of 192.168.x.x, you can push the server subnet to the clients, allowing them to reach a computer connected to the same LAN as the server, without running openvpn on it.
Fact is, if server subnet and client subnet are of the same kind, a conflict will arise, with the net result of a non working VPN.

14.	push "dhcp-option DNS 8.8.8.8"
15.	push "dhcp-option DNS 8.8.4.4"

Set your primary domain name server address for clients. In this case, we’re using Google’s DNS.

16.	push "redirect-gateway def1"

Override the Client default gateway by using 0.0.0.0/1 and 128.0.0.0/1 rather than 0.0.0.0/0. This has the benefit of overriding but not wiping out the original default gateway. At least, that's what the Bible says about it.
Just leave it as it is, da?

17. client-to-client

This allows clients to see each other. It’s useful for running a server on a cheap raspberry pi AND running a heavy videogame server on a client pc, allowing other clients to reach it through its OpenVPN address.

18.	duplicate-cn

I don’t like this option. It allows multiple clients to connect at the same time with the same certificate. If you’re using this, I don’t know how to quantify your indolence.
If you feel a considerate hard-worker, comment this option.

19.	keepalive 10 120

Self-explanatory. Ping every 10 seconds. After a 120 timeout, the client’s down.

20.	tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0

This is the famous DoS attack protection. The argument is 0 on the server and 1 on the client. We’re gonna create an HMAC firewall rule to enforce this service.

21.	cipher AES-128-CBC

This is a modern, quite secure yet not cumbersome cipher.

22.	comp-lzo

Sounds compressive.

23.	user nobody
24.	group nogroup

Grants limited privileges to the clients’ users.

25.	persist-key
26.	persist-tun

These two lines are for robustness. They prevent the access to resources that may not be available on startup. Well, at least that’s what the say on the Bible.

27.	status /var/log/openvpn-status.log 20

This line writes a log in the designated file, truncated and rewritten every 20 seconds.

28.	log /var/log/openvpn.log
29.	verb 6

Another log (yup, OVPN has two logs). While most people will find a level 6 verbosity to be overkill, if you go seek help on OpenVPN forums, they’ll require a high level of detail in the logs. So, less work in case of trouble.
#-----------------------------------------------------------------



SERVER NETWORK CONFIG---------------------------------------------

It’s simple. Do you remember the “server static IP address”? Good.
Set your network manager to keep a static IP with that address.

Then, we need to allow network forwarding.

	~# nano /etc/sysctl.conf 

Scrolling down the file we’ll se a line looking like that:

	# Uncomment the next line to enable packet forwarding for 	IPv4
	#net.ipv4.ip_forward=1

Just do what he suggests. Uncomment the line.

	~# sysctl -p  

Will apply the changes.
Now, the OS is enabled to forward requests, so that clients can see each other IN ABSENCE OF A FIREWALL. If you’re using UFW, there are two ways to allow forwarding.
The simple way: always allow forwarding. If you’re not an NSA analyst trying to smuggle sensible information, you might be fine with the following.
Edit /etc/default/ufw and set  DEFAULT_FORWARD_POLICY to ACCEPT:

	DEFAULT_FORWARD_POLICY="ACCEPT"

The convoluted way: selective forwarding.
Create a new file:

	~# nano /etc/firewall-openvpn-rules.sh 

And paste inside it the following:

	#!/bin/sh
	iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to-source  192.168.X.X

Be careful to replace eth0 with your actual interface and 192.168.x.x with your server address.
Now change the file permissions:

	~# chmod 700 /etc/firewall-openvpn-rules.sh 
	~# chown root /etc/firewall-openvpn-rules.sh

Now that the file’s ready, let’s make its presence noticed by the system:

	~# nano /etc/network/interfaces

Find the line that is either iface eth0 (or your interface) inet dhcp or iface eth0 inet manual and enter this line below it:

	pre-up /etc/firewall-openvpn-rules.sh

Just keep it indented, so that it looks like this:

iface eth0 inet manual  
        pre-up /etc/firewall-openvpn-rules.sh

Now, reboot the server: you’re done! We only have to work for the clients’ side.

#-----------------------------------------------------------------



                    CLIENTS CONFIGURATION

This configuration has to be done on the server. Basically, we’re about to create on the server the certificates that will then be used on the clients. So be prepared, think of a way to securely copy those certificates on your clients. You can use whatever means you think to be the best. Most of the people will tell you the best way is SCP. Yeah ok, it may be right, but I’m old-fashioned: the more stuff in the way, the more stuff could break/go wrong. What if you don’t have a working ssh server on the client? What if you are not able to reach with a reasonable level of security your client’s IP? Personally, if I have access to the client machine (I like to think to have quite a degree of control on my laptop/smartphone) I prefer to use the USB thumb drive way.
Just be sure to shred away all traces of the certificate once you’re done. If you have to give a certificate to a friend in some ackward place… Well there you have a problem. First of all, if you’re about to send sensible information, remotely sending ANY kind of means of accessing such informations is ALWAYS a bad idea.
You need to have a total trust relationship between the two parts.
Even if you use a service like Hamachi or any other password based VPN service to establish a link to be used for secure certificate exchange, you would have to send a password in the first place.
Anyone can sniff the password and then jeopardize your future link.
Even if you compress the certificate and then encrypt it with gpg, you still had to send the password for the file. Moreover, you should be aware that sending via e-mail something that is encrypted is like putting your guitar in a safe mounted on a wheelbarrow and then driving it through the streets to you destination. Not a good way to go unnoticed.
If you really have to do so (and I had to do so to help a friend in China), I can only give you some advice:
- Divide your information in cross-dependent bits;
- Send the aforementioned bits on separate channels;
- ENIGMA Machines still work: use your imagination;
Ok, after this disclaimer section, let’s dive into the final part of our endeavor.

Let’s create a template file on you server. Run:

	~# nano /etc/openvpn/easy-rsa/keys/Default.txt 

Then, paste inside it the following code:

	client
	dev tun
	proto udp
	remote your.server.ip.or.domain.name yourPort
	resolv-retry infinite
	nobind
	persist-key
	persist-tun
	mute-replay-warnings
	ns-cert-type server
	key-direction 1
	cipher AES-128-CBC
	comp-lzo
	verb 6
	mute 20

This simply reflects our server config. Just be sure to replace your.server.ip.or.domain.name and yourPort with your server and port data (remember that the default port is 1194).
A word of advice: I had a fairly hard time making the dynamic dns system from the famous afraid.org to work. I found my peace of mind with duckdns.org that, while offering just 5 domains, is fast, painless, robust and, most notably, free. You can set it up in a few minutes following their installation guide.
If you don’t know what I’m talking about, please spend some time to read around for what are dynamic IPs, static Ips, DNSs etc. But I think the duckdns “why” page is sufficient to have an idea.

Good, now, we’re about to create a script that creates config files. Run:

	~# nano /etc/openvpn/easy-rsa/keys/MakeOVPN.sh

and paste in the following:

#!/bin/bash

# Default Variable Declarations
DEFAULT="Default.txt"
FILEEXT=".ovpn"
CRT=".crt"
KEY=".3des.key"
NODES_KEY=".key"
CA="ca.crt"
TA="ta.key"
NAME="${1}"

if [ -z "${NAME}" ]; then
  # Ask for a Client name
  echo "Please enter an existing Client Name:"
  read NAME
fi


#1st Verify that client's Public Key Exists
if [ ! -f $NAME$CRT ]; then
  echo "[ERROR]: Client Public Key Certificate not found: $NAME$CRT"
  exit
fi
echo "Client's cert found: $NAME$CR"


#Then, verify that there is a private key for that client
if [ ! -f $NAME$KEY ]; then
  echo "[INFO]: Client 3des Private Key not found: $NAME$KEY"
  KEY="${NODES_KEY}"
fi
if [ ! -f $NAME$KEY ]; then
  echo "[ERROR]: Client Private Key not found: $NAME$KEY"
  exit
fi
echo "Client's Private Key found: $NAME$KEY"

#Confirm the CA public key exists
if [ ! -f $CA ]; then
  echo "[ERROR]: CA Public Key not found: $CA"
  exit
fi
echo "CA public Key found: $CA"

#Confirm the tls-auth ta key file exists
if [ ! -f $TA ]; then
  echo "[ERROR]: tls-auth Key not found: $TA"
  exit
fi
echo "tls-auth Private Key found: $TA"

#Ready to make a new .opvn file - Start by populating with the default file
cat $DEFAULT > $NAME$FILEEXT

#Now, append the CA Public Cert
echo "<ca>" >> $NAME$FILEEXT
cat $CA >> $NAME$FILEEXT
echo "</ca>" >> $NAME$FILEEXT

#Next append the client Public Cert
echo "<cert>" >> $NAME$FILEEXT
cat $NAME$CRT | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >> $NAME$FILEEXT
echo "</cert>" >> $NAME$FILEEXT

#Then, append the client Private Key
echo "<key>" >> $NAME$FILEEXT
cat $NAME$KEY >> $NAME$FILEEXT
echo "</key>" >> $NAME$FILEEXT

#Finally, append the TA Private Key
echo "<tls-auth>" >> $NAME$FILEEXT
cat $TA >> $NAME$FILEEXT
echo "</tls-auth>" >> $NAME$FILEEXT

echo "Done! $NAME$FILEEXT Successfully Created."

#Script written by Eric Jodoin

(you may download it from here)

We need to make the script executable:

	~# cd /etc/openvpn/easy-rsa/keys
	~# chmod 700 MakeOVPN.sh

And then we run it.

	~# ./MakeOVPN.sh

He’ll ask for the names of the clients we created. I used User1 for my client, so I’ll only enter it.

	Done! User1.ovpn Successfully Created.

Ok we’re done! If you don’t see the message or the output file, check your files and entries for typos. They’re the most common source of errors with OpenVPN. I literally had to create, like, more than 15 servers before I had a working one. And that was all because of typos (hopefully you’ll be more skilled than me : D).

Repeat this process for all of your clients.

We’re finished!
Find a way to copy the User1.ovpn to your client. We talked about that.

Now, on windows, just install openvpn (here), go into the installation directory, create a folder named “config” (if it’s not already there), run the program as administrator, right click on the icon in the tray > connect. Done!

On linux it’s easier: cd to the User1.ovpn directory and run:

	sudo openvpn  --config User1.ovpn

Keep the terminal window open! If you close it, it’s gonna disconnect!

Android: install OpenVPN Connect from the google play store.
Click (yes. Click. Tap? Who do you believe you are, Van Halen?) on the top right corner’s three dots > import and browse for your User1.ovpn file. Done! (I play Minetest with it. It’s an open source, moddable minecraft that runs on nearly all platforms).

I don’t know how to use Macs or iOSs, not enough money (and willingness) to buy hardware that runs half windows applications at double a price (not to mention Debian’s price lol).
Regarding iOS: I don’t take into consideration smartphones sold for more than 200$. Don’t even know if it’s good or not, just know that instead of having a phone I could let it rip with a Strat for the same price.

WINDOWS DISCLAIMER: if you can ping the server from windows but the server cannot ping your windows client, you have to bang yo head on windows firewall.
Run cmd.exe, enter ipconfig and find out how windows calls your OpenVPN TAP adapter interface.
Now, go to windows firewall >    Advanced > Action > Properties > Customize Protected Network Connections and disable the firewall for your TAP interface altogether. Hate it. Well, BTW that interface SHOULD only see trusted connections.

On your Ubuntu/Debian box you can simply tell ufw to allow all traffic on 1194/udp (or whatever port you chose).

	sudo ufw allow 1194/udp

If you want to run a game, e.g. ArmA 2, on port 2302, you don’t have to forward it anywhere. The traffic is goin just through your 1194 port. “Whoa, slow!” you say. “Yup. But working.” I reply.
If you need more performance, check out the bridging and dev tap stuff I talked about during server configuration.

Cheers

P.S.: To the Admins: I tried to look for a tutorial section but didn't find it. Maybe because I crossed the eyes or whatever. If the post is in the wrong section, please, notice me about that. Lighthearted's a thing, chaotic's another and I don't wanna mess anything up.


Heavy Metal Rulez _\m/

Offline

#2 2016-11-11 19:00:32

Head_on_a_Stick
Member
From: London
Registered: 2015-09-29
Posts: 9,093
Website

Re: OpenVPN server/client basic and lighthearted Tutorial

Great guide bubbajack, thank you for taking the time to post this.

I have moved the thread to Scripts, Tutorials & Tips to make sure it gets the exposure it deserves.

Offline

Board footer

Powered by FluxBB