Skip to content

Instantly share code, notes, and snippets.

@MartinSadovy
Last active January 4, 2017 16:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MartinSadovy/7ac133226677a8a5f2397f12c13782a7 to your computer and use it in GitHub Desktop.
Save MartinSadovy/7ac133226677a8a5f2397f12c13782a7 to your computer and use it in GitHub Desktop.
#!/bin/sh
# pacman -Sy easy-rsa
# EasyRSA 3.0 + http://www.stj.me/2016/02/17/openvpn-ddwrt.html
# run as ROOT!
echo "set_var EASYRSA_DN \"org\"" >> vars
CLIENT_OUT_DIR="/home/sodae/keys-openvpn/"
export EASYRSA_NS_SUPPORT="yes"
cd /etc/easy-rsa/
echo "yes" | easyrsa init-pki
echo "RIJNOVA" | easyrsa build-ca nopass
# RIJNOVA = CA NAME
# server (routers):
echo "
" | easyrsa gen-req DDWRT1 nopass
echo "yes" | easyrsa sign server DDWRT1
# clients:
echo "
" | easyrsa gen-req z1c nopass
echo "yes" | easyrsa sign client z1c
# end
easyrsa gen-dh
cp /etc/easy-rsa/pki/ca.crt $CLIENT_OUT_DIR
cp /etc/easy-rsa/pki/issued/z1c.crt $CLIENT_OUT_DIR
cp /etc/easy-rsa/pki/private/z1c.key $CLIENT_OUT_DIR
chmod 0777 /home/sodae/keys-openvpn/*
cat /etc/easy-rsa/pki/ca.crt
cat /etc/easy-rsa/pki/issued/DDWRT1.crt
cat /etc/easy-rsa/pki/private/DDWRT1.key
cat /etc/easy-rsa/pki/dh.pem
<!-- THIS IS HTML SNIPPET OF ARTICLE: http://www.stj.me/2016/02/17/openvpn-ddwrt.html - it is just case when page is unavailable -->
<header class="post-header">
<h1 class="post-title">OpenVPN and DD-WRT</h1>
<p class="post-meta"><abbr title="Feb 17, 2016 00:02">10 months and 3 weeks ago</abbr></p>
</header>
<article class="post-content">
<p>I’m not sure why but there is apparently <em>no</em> simple tutorial on how to get started with an OpenVPN server on DD-WRT.</p>
<p>When I set this up, I followed about 15 different guides and had to steal some configuration from a friend (who doesn’t remember where he found it).</p>
<p>This shouldn’t ever be this difficult, so I decided to write it all down for the next person to have an easier time.</p>
<!--more-->
<h2 id="step-1-install-tunnelblick">Step 1: Install Tunnelblick</h2>
<p>Okay, so the first thing we need is a OpenVPN client. I chose <a href="https://www.tunnelblick.net/">Tunnelblick</a> for OSX because it’s free, open source, and comes bundled with <a href="https://github.com/OpenVPN/easy-rsa">easy-rsa</a> (which will make our life REALLY easy).</p>
<p>Installing is simple, just install via <a href="https://www.tunnelblick.net/downloads.html">their website</a> or via <a href="http://brew.sh/">Homebrew</a>’s <a href="http://caskroom.io/">Cask</a>.</p>
<p><code>
$ brew cask install tunnelblick
</code></p>
<h2 id="step-2-generate-the-ca-certificate">Step 2: Generate the CA Certificate</h2>
<p>Once we have <a href="https://www.tunnelblick.net/">Tunnelblick</a> installed, we can use the built-in copy of <a href="https://github.com/OpenVPN/easy-rsa">easy-rsa</a> to generate all the certs we need. If you chose to install an alternative client in step 1, then you need to get <a href="https://github.com/OpenVPN/easy-rsa">easy-rsa</a> on your own.</p>
<p>Tunnelblick installs easy-rsa in your local home directory:</p>
<pre><code>$ cd "~/Library/Application Support/Tunnelblick/easy-rsa"
</code></pre>
<p>First thing we have to do is export the nice default variables they provide in <code>vars</code> and clean the environment. You can change them, but they are just defaults and you will be prompted for them later.</p>
<pre><code>$ . vars
$ ./clean-all
</code></pre>
<p>This has now created the <code>keys/</code> directory in this folder. This is where all the goodness will go.</p>
<p>Okay, now that everything is setup, we can finally make our global CA, the thing we’re going to use to sign all the device certificates. You can easily make this by running:</p>
<pre><code>$ ./pkitool --initca
</code></pre>
<p>You will now have two very important files:</p>
<pre><code>-rw-r--r-- 1 root wheel 1387 Feb 17 18:49 ca.crt
-rw------- 1 root wheel 890 Feb 17 18:49 ca.key
</code></pre>
<p>The <code>ca.crt</code> needs to be made available to all the devices you want to connect with (and serve from), but the <code>ca.key</code> should be kept secret (as it can be used to sign new device certificates).</p>
<h2 id="step-3-generate-the-servers-certificate">Step 3: Generate the Server’s Certificate</h2>
<p>Now that you have a CA, you can start creating some device certificates! Start by making one for the server:</p>
<pre><code>$ ./build-key-server server
</code></pre>
<p><strong><em>NOTE: It’s very important NOT to pick a password for this certificate, otherwise DD-WRT is not going to be able to decrypt it</em></strong></p>
<p>This process will generate some new files which will be needed for the server:</p>
<pre><code>-rw-r--r-- 1 root wheel 4174 Feb 17 18:50 server.crt
-rw------- 1 root wheel 890 Feb 17 18:50 server.key
</code></pre>
<p>These two will be used later in the DD-WRT configuration, so hang on to them.</p>
<h2 id="step-4-generate-diffie-hellman-parameters">Step 4: Generate Diffie-Hellman Parameters</h2>
<p>Now that we have a server certificate, we can make the Diffie-Hellman parameters for the SSL/TLS connection.</p>
<p>Easily done by running:</p>
<pre><code>$ ./build-dh
</code></pre>
<p>And you’ll get a fantastic pem file like this one:</p>
<pre><code>-rw-r--r-- 1 root wheel 244 Feb 17 18:50 dh1024.pem
</code></pre>
<p>We’ll use this later when configuring DD-WRT.</p>
<h2 id="step-5-generate-your-device-certificates">Step 5: Generate your Device Certificates</h2>
<p>We’re going to make two devices here, an iPhone and Laptop. I’m going to call the devices by those names in this tutorial, but your names should be more unique to the devices themselves (like hostnames for example).</p>
<pre><code>$ ./build-key iphone
$ ./build-key laptop
</code></pre>
<p><strong><em>NOTE: I recommend creating passwords for these, but you don’t HAVE to.</em></strong></p>
<p>This will generate us similar files as the previous steps:</p>
<pre><code>-rw-r--r-- 1 root wheel 4001 Feb 17 18:50 iphone.crt
-rw------- 1 root wheel 883 Feb 17 18:50 iphone.key
-rw-r--r-- 1 root wheel 4014 Feb 17 18:50 laptop.crt
-rw------- 1 root wheel 882 Feb 17 18:50 laptop.key
</code></pre>
<p>Hang on to them for your individual device setup.</p>
<h2 id="step-6-configure-dd-wrt-vpn-settings">Step 6: Configure DD-WRT VPN Settings</h2>
<p>Now go to your router’s VPN tab under Services and let’s start flipping some settings! All of these are under “OpenVPN Server/Daemon”.</p>
<h3 id="basic-settings">Basic Settings</h3>
<ul>
<li>OpenVPN: <code>Enable</code></li>
<li>Start Type: <code>WAN Up</code> (we want to have internet before starting)</li>
<li>Config as: <code>Server</code> (we’re a server, yeah?)</li>
<li>Server Mode: <code>Router (TUN)</code> (I don’t know)</li>
<li>Network: <code>10.0.2.0</code> (I chose this as it’s a dedicated segment of my network, my normal routing is <code>10.0.0.0</code> in this network)</li>
<li>Netmask: <code>255.255.255.0</code></li>
<li>Port: <code>1194</code> (I like to leave the default here)</li>
<li>Tunnel Protocol: <code>UDP</code> (and here)</li>
<li>Encryption Cipher: <code>Blowfish CBC</code></li>
<li>Hash Algoritm: <code>SHA1</code></li>
<li>Advanced Options <code>Disable</code> (don’t need any of that)</li>
</ul>
<p>Now for the big text fields, we’re going to go through them one by one.</p>
<h3 id="public-server-cert">Public Server Cert</h3>
<p>Take the <code>server.crt</code> and find where <code>-----BEGIN CERTIFICATE-----</code> starts. Copy from there until the end of the file, including the line <code>-----END CERTIFICATE-----</code>. Put this in that field.</p>
<h3 id="ca-cert">CA Cert</h3>
<p>Just stick the contents of <code>ca.crt</code> in here.</p>
<h3 id="private-server-key">Private Server Key</h3>
<p>The contents of <code>server.key</code> go in here.</p>
<h3 id="dh-pem">DH PEM</h3>
<p>This is where we put the <code>dh1024.pem</code> contents.</p>
<h3 id="additional-config">Additional Config</h3>
<p>For here, we don’t need to do much. I just have a couple basic tweaks I add:</p>
<pre><code># Route traffic from this new network into my existing network
push "route 10.0.0.0 255.255.255.0"
# DNS server is 10.0.0.1, a.k.a. my router.
push "dhcp-option DNS 10.0.0.1"
# Use the tun0 device (so we can refer to it later)
dev tun0
# Ping every 10 seconds, and restart after 120 seconds of inactivity
keepalive 10 120
</code></pre>
<p>Okay, that’s it for this page. Save and Apply changes!</p>
<h2 id="step-7-configure-the-firewall">Step 7: Configure the Firewall</h2>
<p>Now that we have the service running, there’s some final configuration required to ensure that the VPNed traffic can talk to the internet AND the intranet (inside your network). Go to <code>Administration</code> and then <code>Commands</code>.</p>
<p>This part may look a little scary, but it’s very simple when you break down each command.</p>
<p>We’re going to put the following Firewall configuration into the <code>Command Shell</code> / <code>Commands</code> section.</p>
<pre><code># Accepts incoming traffic via port 1194 UDP
iptables -I INPUT 1 -p udp --dport 1194 -j ACCEPT
# Allows the VPN client access to router internal
# processes, e.g. Web admin, SSH etc
iptables -I INPUT 3 -i tun0 -j ACCEPT
# Allows connections between VPN clients, if
# client-to-client is enabled in OpenVPN server
iptables -I FORWARD 3 -i tun0 -o tun0 -j ACCEPT
# Allows connection from local VPN to the internet
iptables -I FORWARD 1 --source 10.0.2.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.0.2.0/24 -j MASQUERADE
# Allows connections from local network to VPN network
# and other way around (br0 is LAN and WIFI)
iptables -I FORWARD -i br0 -o tun0 -j ACCEPT
iptables -I FORWARD -i tun0 -o br0 -j ACCEPT
</code></pre>
<p>Great, now hit <code>Save Firewall</code> and your server is done!</p>
<h2 id="step-8-configure-your-devices">Step 8: Configure your devices</h2>
<p>Now that you have a server, you need to setup your different devices. Like I said before, we’re going to stick to the <code>laptop</code> and <code>iphone</code> device types we made before.</p>
<h3 id="iphone">iPhone</h3>
<ul>
<li>Install OpenVPN Client (free on AppStore)</li>
<li>Create a folder to store stuff in locally (let’s call it <code>iphone/</code>)</li>
<li>Put the <code>iphone.key</code>, <code>iphone.crt</code>, and <code>ca.crt</code> in this directory</li>
<li>
<p>Create a new file called <code>config.ovpn</code> with the contents:</p>
<pre><code> # Specify that we are a client and that we
# will be pulling certain config file directives
# from the server.
client
# Use the same setting as you are using on
# the server.
dev tun0
# Are we connecting to a TCP or
# UDP server? Use the same setting as
# on the server.
proto udp
# The hostname/IP and port of the server.
remote YOURHOSTNAMEHERE 1194
# Keep trying indefinitely to resolve the
# host name of the OpenVPN server. Very useful
# on machines which are not permanently connected
# to the internet such as laptops.
resolv-retry infinite
# Most clients don't need to bind to
# a specific local port number.
nobind
# Try to preserve some state across restarts.
persist-key
persist-tun
# SSL/TLS parms.
ca ca.crt
cert iphone.crt
key iphone.key
# Verify server certificate by checking
# that the certicate has the nsCertType
# field set to "server". This is an
# important precaution to protect against
# a potential attack discussed here:
# http://openvpn.net/howto.html#mitm
ns-cert-type server
# Enable compression on the VPN link.
comp-lzo
# Allow me to change my IP address
# and/or port number (if I get a new
# local IP address at Starbucks).
float
</code></pre>
</li>
<li>Open iTunes, go to your device, then Applications. At the very bottom you will see <code>OpenVPN</code>, click on it. Drag all four files you created in the <code>iphone/</code> folder into the box on the right. This uploads them into the device. Click <code>sync</code>.</li>
<li>Open up the app on your phone, it will allow you to create a new profile based on this input.</li>
<li>Done! Connect to your network!</li>
</ul>
<h1 id="laptop">Laptop</h1>
<p>Okay, the reason I said to do the iPhone first, was that the Laptop is basically the same thing!</p>
<ul>
<li>Create a folder to store stuff in locally (let’s call it <code>HomeVPN/</code>)</li>
<li>Put the <code>laptop.key</code>, <code>laptop.crt</code>, and <code>ca.crt</code> in this directory</li>
<li>Create a new file called <code>config.ovpn</code> with similar contents as before (but replace <code>iphone</code> with <code>laptop</code>)</li>
<li>Rename the folder to <code>HomeVPN.tblk/</code></li>
<li>Double-click it and import into Tunnelblick</li>
</ul>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment