GUI confuses me sometimes, so I prefer to make configurations in text files. For DD-WRT, OpenVPN server is available in OpenVPN, OpenVPN Small, Big, Mega, and Giga builds: K2.6 Build Features. Since I have never used any router with USB storage capabilities, I can’t be sure but I think OpenVPN can be installed using ipkg as well.
For this post I am going to assume you’re an OS X user, but Windows procedures shouldn’t be too different.
1. Generating certificates and keys
- Get Easy-RSA. You can either clone the git repository or download the package as zip. Navigate to the folder where you downloaded/cloned Easy-RSA and get into the directory
easy-rsa/2.0
. - Edit the file
vars
. I’m showing the variables that you might want to change. Take note of theKEY_SIZE
variable. If you’re paranoid like me, leave it at 2048. It takes longer to generate DH parms but not that long.# Increase this to 2048 if you # are paranoid. This will slow # down TLS negotiation performance # as well as the one-time DH parms # generation process. export KEY_SIZE=2048 # In how many days should the root CA key expire? export CA_EXPIRE=3650 # In how many days should certificates expire? export KEY_EXPIRE=3650 # 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="MY" export KEY_PROVINCE="SELANGOR" export KEY_CITY="Puchong" export KEY_ORG="AdyRomantika" export KEY_EMAIL="[email protected]" export KEY_OU="RomantikaName" # X509 Subject Field export KEY_NAME="MYKEY1"
- Import the variables into the current shell:
$ source vars
- Clean existing keys if any (WARNING: This deletes all existing certificates and keys)
$ ./clean-all
- Generate server certificates. The script will still ask for parameters you entered in
vars
so just press ENTER if you’re satisfied- This will produce 2 files:
ca.key
andca.crt
$ ./build-ca
- This will produce 2 files:
- Generate Diffie Hellman parameters
- This will produce the file:
dh{n}.pem
where{n}
is the key size specified in thevars
file.
$ ./build-dh
- This will produce the file:
- Generate key for the server.
- When asked for a password, just press ENTER otherwise the key password will be asked each time service is being brought up.
- When asked whether to sign the certificate, say Yes.
- This will produce 3 files:
server.crt
,server.csr
,server.key
$ ./build-key-server server1
- Generate key for the clients. This step can be repeated in the future for more clients as needed.
- When asked for a password, you can enter a password so that when connecting to the service, the key password will be asked. I recommend this to make it more secure.
- When asked whether to sign the certificate, say Yes.
- This will produce 3 files:
client1.crt
,client1.csr
,client1.key
$ ./build-key client1
2. Preparing the server
- For the server we’re going to need 4 files:
ca.crt
server.key
server.crt
dh{n}.pem
- We are going to have to write a script that generates the configuration in DD-WRT so that they survive a restart. DD-WRT » Administration » Commands is the location where you save a startup script into the nvram. If you already have something, you can simply append and click “Save Startup”
- One line 25, 26, 27, and 28 enter the content of the files generated above in between the “”
- Line 10 is where you put in the dedicated IP address for connecting clients. Modify the address and mask as you see fit. Try to avoid IPs that are currently being used. For this configuration I am only allowing 6 maximum clients (10.11.11.0/29) = 10.11.11.1 to 10.11.11.6
- Line 11 instructs OpenVPN to reuse a persistent pool but since the file is sitting in a volatile memory it’ll be gone after a router restart.
- Line 12 is where you push your LAN network route to the client
- What this will do is the next time the router is rebooted it will create all the necessary files and bring up the tap network interface to be used by OpenVPN. It will also immediately start the OpenVPN service. (If you’re feeling brave you can also execute
/tmp/.rc_startup
via SSH) - My choice of port 443 (line 7) via TCP (line 8) is simply because I want to make sure that I will be able to connect to the service from most places since port 443 is the standard HTTPS port. You might want that changed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
### START OPENVPN /bin/mkdir /tmp/openvpn /usr/sbin/openvpn --mktun --dev tap0 /usr/sbin/brctl addif br0 tap0 /sbin/ifconfig tap0 0.0.0.0 promisc up echo "port 443 proto tcp dev tap0 server 10.11.11.0 255.255.255.248 ifconfig-pool-persist /tmp/openvpn/ipp.txt push "route 192.168.168.0 255.255.255.224" client-to-client keepalive 10 120 comp-lzo persist-key persist-tun verb 3 daemon ca /tmp/openvpn/ca.crt dh /tmp/openvpn/dh2048.pem cert /tmp/openvpn/server.crt key /tmp/openvpn/server.key" > /tmp/openvpn/vpn.config echo "" > /tmp/openvpn/ca.crt echo "" > /tmp/openvpn/server.key echo "" > /tmp/openvpn/server.crt echo "" > /tmp/openvpn/dh2048.pem chmod 600 /tmp/openvpn/server.key sleep 5 /usr/sbin/openvpn --config /tmp/openvpn/vpn.config ### END OPENVPN
- The last thing you need to do in DD-WRT to make the firewall allow connections to OpenVPN service. Configuration screen is the same as above, DD-WRT » Administration » Commands but instead of “Save Startup” you now need to “Save Firewall”. (Change 443 to your chosen port number and change tcp to udp if you decide to use UDP). Note that you will briefly lose connectivity as the firewall reloads.
iptables -I INPUT -p tcp --dport 443 -j ACCEPT
3. Preparing the client
- For the client we’re going to need 3 files. For the rest of this section please replace
{n}
with the number you choose for your client:ca.crt
client{n}.key
client{n}.crt
- On OS X I am using Tunnelblick as OpenVPN client. However it uses standard OpenVPN configuration files too and can easily be ported to Windows.
-
Create a folder and the file
config.openvpn
:- Line 3 should match your protocol settings in the server
- Line 4 should be your hostname or IP and the port number
1 2 3 4 5 6 7 8 9 10 11 12 13
client dev tap proto tcp remote XXXXXXXX 443 resolv-retry infinite nobind persist-key persist-tun ca ca.crt cert client{n}.crt key client{n}.key comp-lzo verb 3
- Copy the 3 files mentioned above into the same folder, add the extension .tblk to the folder name and its icon will be changed and be associated to Tunnelblick. Double-clicking the folder will now invoke Tunnelblick for configuration import process
However, there is one thing that I am still unable to figure out: to make OS X request for DHCP from DD-WRT to get the LAN IP address. The “up” directive inside OpenVPN client configuration is not kicking in most probably because Tunnelblick has its own “up” directive as a command line parameter. Manually, we can run the command below.
sudo ipconfig set tap0 DHCP |
Reference(s):
- Setting up your own Certificate Authority (CA) and generating certificates and keys for an OpenVPN server and multiple clients
- OpenVPN-Site-To-Site-Bridged-German
- OpenVPN Manual Page – this is where you can find explanations on each directive in the configuration file
Good luck!