DD-WRT: OpenVPN Server Using Certificates

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

  1. 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.
  2. Edit the file vars. I’m showing the variables that you might want to change. Take note of the KEY_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"
  3. Import the variables into the current shell:
    $ source vars
  4. Clean existing keys if any (WARNING: This deletes all existing certificates and keys)
    $ ./clean-all
  5. 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 and ca.crt
    $ ./build-ca
  6. Generate Diffie Hellman parameters
    • This will produce the file: dh{n}.pem where {n} is the key size specified in the vars file.
    $ ./build-dh
  7. 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
  8. 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

  1. For the server we’re going to need 4 files:
    • ca.crt
    • server.key
    • server.crt
    • dh{n}.pem
  2. 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
  3. 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

  1. 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
  2. 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.
  3. 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
  4. 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):

Good luck!

0 Shares