OpenVPN example 0
From Telecomix Crypto Munitions Bureau
From this example, we will create a server that accepts connections from multiple clients. All clients that connect will be put inside a virtual network (172.16.1.0/24) and be able to talk to each other. The OpenVPN server works as a switch for the network, all traffic goes through it. The clients will be assigned their IPv4 addresses enumerating from 172.16.1.2 to 172.16.1.254. The first client that connects will be named 172.16.1.2, the second client that connects will be named 172.16.1.3, and so on. This is good if you want to connect lots of people to your darknet without having to care about who is who. (You will need to use another network than 172.16.1.0/24 if you want to allow for more than 253 users at the same time.)
Plz consider squatting IPv4 addresses from military organizations you dislike.
If you are going to peer with another operator/ISP, then consider using separate tunnels just for them. See OpenVPN example 1 for an example on how to do just that. It will be somewhat difficult to route your traffic between peers that constantly change their IP-numbers.
Only people that has received crypto keys from you are able to log in. You need to create a new pair of client keys for each user that wants in.
Also, consider using IPv6 instead. Please experiment with IPv6 + OpenVPN and write a tutorial! :)
 Everything in this article: Really, really quick
- cd to /usr/share/doc/openvpn/examples/easy-rsa/2.0 (or wherever you have these files installed.)
- Copy everything in this directory (step 1) to some safe place. Make sure that you will not loose any of the files you create in the following steps:
- Edit the vars file so that it looks something like this.
- "source ./vars" or ". ./vars"
- "./build-ca", and just keep hitting enter for every question
- "./build-dh" and compile yourself a cup of tea
- "./build-key-server servername", and just keep hitting enter for every question
- "./build-key clientname", and just keep hitting enter for every question
- Distribute the files that the client and the server wants. You will find the files in ./keys/
- The server needs: ca.crt, servername.crt, servername.key, dh2048.pem
- The client needs: ca.crt, clientname.crt, clientname.key
- Write the config files (see below for examples)
- Consider setting up firewalls and having the OpenVPN-daemons start at bootup
- See OpenVPN example 0 - iptables rules, and see below for automatic bootup scripts.
- Start the server and the client, verify that it works. Have a look at the log-files ("tail -f ./logfile")
If you want to let more clients connect to the server, repeat step 9 and distribute the new files to the person that is about to connect to you. Or just do the following:
- "./build-key new_clientname", and just keep hitting enter for every question
- Send the new user these files: ca.crt, new_clientname.crt, new_clientname.key
- Tell your friend to write a config file (see below), or write it yourself and include it with the other files.
- Try to convince your friend to set up some good firewall. See OpenVPN example 0 - linux client iptables for an example script.
These steps are described in more detail below. The green text shows what part is being described. Do not forget that the .key-files are secret. A key-file (private key) should never ever be shown to anyone else but the guy that needs it.
 Setting up the PKI
- If you have installed OpenVPN, there will be some sample config files and scripts for generating a Public Key Infrastructure in: /usr/share/doc/openvpn/examples/easy-rsa/2.0 or something similiar. The path depends on your operating system.
- cd this location. Make a copy of everything and place it somewhere safe. Use the copy instead of the original files, it would be rather tiresome if you destroyed them. For example, you could copy the files to your home directory. Make sure that the files are readable only by you.
- Edit the vars file inside your copy. The only things you really need to change is the organizational stuff at the bottom of the file, but it might also feel a bit more secure to change export KEY_SIZE=1024 to something else. Using 2048- or 4096-bit RSA might be better for you. The vars-file originally looks like this, but you need to change it so it looks something like this.
- Source the vars-file. You could either type "source ./vars" or ". ./vars".
- Type ./clean-all to remove the examples in the ./keys-directory. You are just about to replace them with your own, real keys.
- Type ./build-ca. A lot of text will swoosh through your terminal and then you will be asked to accept the information you just entered into the vars-file. It could look a bit like this.
- After you have built you own Certificate Authority (build-ca), there will be some files in the ./keys-directory. ca.crt is your certificate, a file that everyone that should trust you needs to have. Distribute it to as many people you like. The file ca.key on the other hand is your most valuable secret now, it is your CAs private key. Do never, ever, let anyone see this file. Your security depends on it. The file serial seems to be used to keep track of how many certificates you have signed. Save everything in the keys-directory to some secure location.
- You also need to create some parameters for the Diffie-Hellman key exchange. Just type ./build-dh. It will look something like this on your console, and result in one file named dh2048.pem inside ./keys. This file is not secret.
You are now done with building you CA. Secure the files and think about saving them on some location where nobody will ever look.
The next step is to create and sign keys for the infrastructure you want to build. We will create one key for a server, and one key for a client. You can create as many server-keys and client-keys as you want. Just repeat the steps below as many times you want :)
 Creating a key for a server, using your CA
(step 8) Essentially, you only need to type one single thing on your terminal. Everything else is done automatically. You need to have the CA-files (ca.crt and ca.key) in your ./keys directory before you issue this command. This is because you are just about to sign the servers keys with your CA. Without a CA, there is nothing to sign the keys with. Anyways, the only thing you need to type is:
And then just press enter on every single question that you are asked. The only time you need to press something else than enter is at the very end, when you are asked if you want to commit the changed. At that point, press y, as in Yes.
The whole thing will look like this, when viewed on the console.
There will now be some new files in the ./keys-directory. The only ones that you need to care about are pool-is-closed.crt, pool-is-closed.csr and pool-is-closed.key. The file pool-is-closed.key is the private key for the server, and should never ever be exposed to anyone else but you and the server owner (which will often be you?)
 Creating a key for a client, using your CA
(step 9) This is equally easy as creating a server-key. Just type the following on the console:
And hit enter on every single question, except the last two, where you press y. It might look something like this.
There will now be some more files in the ./keys directory. client0.crt, client0.csr and client0.key. Only the file named client0.key is secret. Give it to the person that is about to connect to your VPN server :)
 Distributing the files you created in ./keys
(step 10) Now, you have created one certificate authority and two pairs of keys. One pair of keys for the OpenVPN-server, and one pair of keys for the client that is going to connect to the server.
- All parties needs to have the ca.crt file, if they should be able to evaluate if the keys have been signed by your certificate authority or not. It does not matter who has access to this file, you could put it on a public web server if you want.
- All servers needs to have a dh2048.pem file. This file is used for the diffie-hellman key exchange, so if you want the servers and clients to be able to exchange encryption keys with each other, they need this file. dh2048.pem is not secret. In fact, the vast majority of security protocols use a publicly known prime for the exchange, but OpenVPN lets us generate our own prime. Why not.
- Distribute all .crt-files (certificates) to all parties, or at least to the ones that needs them. The certificates are not secret, they are just pieces of information that verifies that the client or server is trusted by the certificate authority.
- Distribute all .key-files (private keys) to the people that need them. The private keys are secret. No one but the owner of the file should possess these files. Consider erasing (or shred'ing) them after giving them away. pool-is-closed.key should be put inside the server, and client0.key should be given to the user that is going to connect to the server.
- Even though the certificate files are not secret per se, you might consider limiting the amount of information you spread about yourself to an absolute minimum. A digital certificate is a file that says that someone is trusting someone else, which obviously is interesting to outsiders that wants to map a social network. Or whatever. Use your brain.
Mkay. Distribute the files to the servers/people that needs them.
For example, the server needs the following files: ca.crt, pool-is-closed.crt, pool-is-closed.key and dh2048.pem. The client0 needs ca.crt, client0.crt and client0.key. They can trust each others keys because they are signed by the certificate authority. This is nice, as this denies others the possibilities to perform MITM-attacks. The dh2048.pem-file that the server(s) need to have can be just about any prime of 2048-bit length, but you should use the file you created for yourself.
Now, you need to write yourself some config files :)
 Config files
(the rest of the article covers steps 11-13) Each server and each client needs their own config file. Below are two config files that you can use if you want the server to be able to have multiple clients connecting to it simultaneously.
The scripts below has these properties:
- The server will listen to the public IPv4-address 220.127.116.11, port 23999, protocol UDP.
- The clients connect to the server (this is always the case)
- When a client connects to the server, it will dynamically receive an IPv4 address in a virtual network named 172.16.1.0/24. The servers tap-pool interface will have the address 172.16.1.1. The first client that connects will receive the address 172.16.1.2, the second client that connects will receive the address 172.16.1.3, and so on. This is OK if you do not care about who is who, and just want to allow people to connect to you. If you on the other hand want to peer with someone to route traffic through their connections, consider using some other setup. (See OpenVPN Example 1, for example.)
 Server setup
Put all the files you need in the directory /etc/openvpn/pool-is-closed/. The files you need are: ca.crt, pool-is-closed.crt, pool-is-closed.key and dh2048.pem. Then put the script below in the directory, name it whatever you want. For simplicity, I am assuming that you named it meh.conf.
dev tap-pool-is-closed # if you are using OpenBSD, comment out the line just above and uncomment the following: # dev tun0 # dev-type tap local 18.104.22.168 port 32999 proto udp keepalive 3 20 mode server server 172.16.1.0 255.255.255.0 ca /etc/openvpn/pool-is-closed/ca.crt cert /etc/openvpn/pool-is-closed/pool-is-closed.crt key /etc/openvpn/pool-is-closed/pool-is-closed.key dh /etc/openvpn/pool-is-closed/dh2048.pem # client-to-client allow clients to talk directly with each other without having to go through your firewall settings. # Your OpenVPN server will behave like a switch for all packets that are sent through it. client-to-client # use nice encryption and compress all traffic cipher AES-256-CBC comp-lzo # The following will result in OpenVPN going to a chroot jail and dropping its privileges, which is good if you do not # trust the software to be bug-free. user nobody group nogroup # exchange with "nobody" if you are using OpenBSD # If the OpenVPN daemon does not run as root, because it is running as user nobody, group nobody and need to reload its # files it will not be allowed to do so. The following will make OpenVPN not forget the contents (or file handles) of the # files if it ever needs to reload or restart the connections. Unless you keep the two lines below, it will just hang. persist-key persist-tun # write nice logs and stuff to some defined files status /etc/openvpn/pool-is-closed/status log /etc/openvpn/pool-is-closed/log verb 3 # verbosity 3 mute 3 # do not log more than three identical messages after each other (saves some disc space)
You can run it by typing:
openvpn --config /etc/openvpn/pool-is-closed/meh.conf --daemon
This will create a tap interface named tap-pool-is-closed. You can see it if you type ifconfig. If something goes wrong, which it will most likely do the first time you are doing this, you can see what caused it by typing cat /etc/openvpn/pool-is-closed/log. To see the log in real time as it grows, type tail -f /etc/openvpn/pool-is-closed/log.
Do not forget to setup firewall rules for this interface. See the article OpenVPN example 0 - iptables rules for an example of how to do just exactly this. For a generic tutorial on linux firewalls, see iptables.
You will most likely want to have this OpenVPN daemon start automatically when your computer starts. If you are using debian or ubuntu, you can put the script below inside /etc/rc2.d/. Name the script something like S99OpenVPN-pool-is-closed, to have it start last in the boot sequence. (If you want to create firewall rules that automatically include your OpenVPN-servers tunnel interface you will have to name your script something else, such as S98OpenVPN-pool-is-closed, and have your firewall script named S99firewall, or something. I do not think the firewall can handle interfaces that does not yet exist, so the firewall needs to be started after the OpenVPN-server.)
script to automatically have the OpenVPN server start at bootup:
#!/bin/sh openvpn --config /etc/openvpn/pool-is-closed/meh.conf --daemon
 Client setup
The person that runs the client should be given the following files: ca.crt, client0.crt and client0.key. Put all of the files in /etc/openvpn/client0/ (or just about anywhere you want.) I am assuming for simplicity that the client config file is named meh.conf. To start the OpenVPN connection, type:
openvpn --config /etc/openvpn/client0/meh.conf --daemon
This will create a new interface named tap0 on your computer, which you will need to write firewall rules for, unless you are a daredevil. See iptables for a tutorial on linux firewalls.
dev tap0 # if you are using OpenBSD, comment out the line just above and uncomment the following: # dev tun0 # dev-type tap remote 22.214.171.124 32999 # needs to be the same as the servers listening port nobind proto udp keepalive 5 30 client cert /etc/openvpn/client0/client0.crt # YOU NEED TO CHANGE THE PATH TO THESE FILES :) key /etc/openvpn/client0/client0.key ca /etc/openvpn/client0/ca.crt remote-cert-tls server # use nice encryption and compress all traffic (this needs to be the same as the server!) cipher AES-256-CBC comp-lzo # The following will result in OpenVPN going to a chroot jail and dropping its privileges, which is good if you do not # trust the software to be bug-free. user nobody group nogroup # nobody if you are using OpenBSD # If the OpenVPN daemon does not run as root, because it is running as user nobody, group nobody and need to reload its # files it will not be allowed to do so. The following will make OpenVPN not forget the contents (or file handles) of the # files if it ever needs to reload or restart the connections. Unless you keep the two lines below, it will just hang. persist-key persist-tun # write nice logs and stuff to some defined files writepid /etc/openvpn/client0/pid # CHANGE PATH AND NAMES HERE TOO :P status /etc/openvpn/client0/status log-append /etc/openvpn/client0/log verb 3 # verbosity 3 mute 3 # do not print out more than tree identical messages to the log.
If you want to route everything through the client VPN-tunnel, type ip route del default; ip route add default 172.16.1.1. I strongly suggest that you write yourself some good firewall script. See OpenVPN example 0 - linux client iptables for an example of how to do just exactly this.