Tuesday, February 19, 2013

[Tutorial - 30 Minutes or Less] Site to Site VPN with TomatoUSB and OpenVPN

The intent of the tutorial is to provide you with the quickest and least painful step-by-step process for setting up a secure, yet simple, Site to Site VPN between two locations using TomatoUSB and OpenVPN, allowing resources to be accessed and shared from both locations (resources behind the routers will be accessible to each other).

A Site to Site VPN can be setup between your home and business, two office locations, or between family members. Some common use cases would be to share files, printers, provide technical support (RDP/VNC),  view webcams (without opening webcam to the internet) and my favorite, as a mean for secure offsite backups.

By going through this tutorial you'll also learn:
    - How to setup a Certificate Authority on your router and generate Certificates and Keys
    - Setup (free) Dynamic DNS
    - Setup cross site name resolution (static DNS host entries)
    - A little bit on expanding the setup to include Client to Site VPN
    - How to enable SFTP on your router for secure access to certificates and keys
 
Last updated and verified on 3/3/2014

Here's a video walk-through of the whole process (24 minutes!). Note that this video is a little dated and should only be used as a reference. This blog has the correct instructions:




What you'll need:
  1. Two routers with Tomato already installed.*
    1. The OpenVPN Server router should be running TomatoUSB (with a USB port)
    2. The OpenVPN Client router can run regular Tomato (no USB port required)
  2. USB Flash Drive >=1GB (will be completely wiped)
  3. Publicly accessible IP address for OpenVPN Server router.
If you're looking for a recommendation on which router to use for this project, please check out the Belkin routers I mention in this post, [Tutorial] Apple AirPlay on TomatoUSB Router.

Outline of Steps

1) Setup OpenVPN Server on Site A Router
        a) Setup Entware (package manager)
        b) Generate RSA Certificates and Keys
        c) Configure OpenVPN Server
        d) Setup Free Dynamic DNS Service
        e) Start OpenVPN Server
2) Setup OpenVPN Client on Site B Router
     
        a) Configure OpenVPN Client
3) Setup Cross Site Name Resolution [Added 10/19/2013]
4) That's it! Enjoy.

Network Info

Site A
     OpenVPN Server
     Internal network/subnetmask - 192.168.1.0/255.255.255.0
     External Public IP Address

Site B
     OpenVPN Client
     Internal network/subnetmask - 192.168.2.0/255.255.255.0
     External Public IP Address

-------------------------------------------------------------------------------
LETS GET STARTED!

Setup OpenVPN Server on Site A Router

Plug in USB flash drive. Make sure the router has internet access.
Connect via SSH into router. For Windows, I recommend Putty.
Log in with username of root and password of admin.

Execute the following commands:

#Partition your usb flash drive
umount /dev/sda1
fdisk /dev/sda


Type in the following commands to create a primary partition on your USB Flash drive
# p       # list current partitions
# o       # to delete all partitions
# n       # new partition
# p       # primary partition
# 1 (one) # first partition
# <enter> # default start block
# <enter> # default end block #use the whole flash drive
# w       # write new partition to disk

#format newly created partition
#label disk as 'optware' case sensitive

umount /dev/sda1
mke2fs -j -L optware /dev/sda1


Install Entware (a package manager that allows you to install additional software on your router)

#mount the new disk partition
mount /dev/sda1 /opt
cd /opt
wget http://wl500g-repo.googlecode.com/svn/ipkg/entware_install.sh
sh ./entware_install.sh


#Make sure /opt is properly mounted on a reboot.
echo "LABEL=optware /opt ext3 defaults 1 1" >> /etc/fstab
nvram setfile2nvram /etc/fstab 
nvram commit


Install openvpn-easy-rsa

opkg install openvpn-easy-rsa nano

Setup working folder for openvpn-easy-rsa
It's recommended that you cut/paste everything up to Setup CA section into your console window to prevent any error/typos


#copy files to working directory
cd /opt/etc/easy-rsa
cp /opt/sbin/sign-req .
cp /opt/sbin/build-req .
cp /opt/sbin/inherit-inter .
cp /opt/sbin/revoke-full .
cp /opt/sbin/clean-all .
cp /opt/sbin/build-ca .
cp /opt/sbin/pkitool .
cp /opt/sbin/build-dh .
cp /opt/sbin/build-key-pass .
cp /opt/sbin/build-key-pkcs12 .
cp /opt/sbin/list-crl .
cp /opt/sbin/whichopensslcnf .
cp /opt/sbin/build-key-server .
cp /opt/sbin/build-key .
cp /opt/etc/easy-rsa/openssl-1.0.0.cnf .
cp /opt/sbin/build-inter .
cp /opt/sbin/build-req-pass .

#reduce key_size to 1024 in vars file
cd /opt/etc/easy-rsa
sed -i 's:KEY_SIZE=2048:KEY_SIZE=1024:' ./vars

#update PATH to pick up correct openssl (save a reboot)
#correct = /opt/bin/openssl
PATH=/opt/bin:$PATH

Setup Certificate Authority (CA)

#Setup and initialize environment
cd /opt/etc/easy-rsa
source ./vars
./clean-all

#Select Default for All, Keep Hitting <Enter> (8 times)
./build-ca


Generate Diffie Hellman parameters (DH file)

./build-dh

Generate Certificate and Key for the OpenVPN Server router at Site A with Common Name [CN] of "OpenVPNServer".

#Generate Cert/Key for Site2SiteClient
#<Enter> 10 times to take default value
#Followed by two 'y' <Enter> when asked to sign and commit
./build-key-server OpenVPNServer

Generate Certificate and Key for the OpenVPN Client router Site B with Common Name [CN] of "Site2SiteClient". The "Common Name" isn't really "common". Make sure its unique for all your clients.

#Generate Cert/Key for Site2SiteClient
#<Enter> 10 times to take default value
#Followed by two 'y' <Enter> when asked to sign and commit
./build-key Site2SiteClient

Output Certificate and Key to console - cut/paste into text file for later use.


cat /opt/etc/easy-rsa/keys/ca.crt
cat /opt/etc/easy-rsa/keys/Site2SiteClient.crt
cat /opt/etc/easy-rsa/keys/Site2SiteClient.key

Create a new text file on your computer and name it "ClientRouterKeys.txt" and cut and paste in the output of the three cat commands above. You'll need this file to setup the OpenVPN Client Router later in the tutorial.

That's it for the SSH Console. The rest of the configuration will be done via a web browser.

Configure OpenVPN Server

Open your favorite browser and connect to your router and go to VPN Tunneling -> OpenVPN Server (http://192.168.1.1/vpn-server.asp).

On "Server 1 -> Basic" Tab, check "Start with WAN". Leave everything else as default.

OpenVPN Server Configuration Server 1->Basic Screen should look like the following:



Change to the Advanced Tab

Check "Respond to DNS"
Check "Manage Client-Specific Options"
Check "Allow Client<->Client"
Check "Enable"
Type in "Site2SiteClient" under "Common Name"
Type in "192.168.2.0" under Subnet
Type in "255.255.255.0" under Netmask
Check Push
Click 'Add' button. (pushes routes to the client router and add route to server router. No need for router/iptable commands)
In the "Custom Configuration" box, paste in the following (saves us from pasting in the certs/key in the Keys Tab and valuable nvram space):

ca /opt/etc/easy-rsa/keys/ca.crt
cert /opt/etc/easy-rsa/keys/OpenVPNServer.crt
key /opt/etc/easy-rsa/keys/OpenVPNServer.key
dh /opt/etc/easy-rsa/keys/dh1024.pem

[Save]

OpenVPN Server Configuration Server 1->Advanced Screen should look like the following:




Setup Free Dynamic DNS Service (http://freedns.afraid.org/)

If you don't have a public static IP (most don't), you'll need to setup DDNS so your OpenVPN client(s) can find your OpenVPN server.

Go to http://freedns.afraid.org and setup an account and then setup a subdomain.

I'm using "OpenVPNServer.mooo.com" (use something else). We'll need this subdomain during the OpenVPN Client setup.




On the left hand side, select "Dynamic DNS" or go to http://freedns.afraid.org/dynamic

Find the subdomain you just created and right click on the "Direct URL" link and select "Copy link address"


On your router, go to Basic -> DDNS (http://192.168.1.1/basic-ddns.asp)

For Dynamic DNS 1, select "FreeDNS(afraid.org)" in the "Service" dropdown.
Paste in the URL you copied in the previous step (note that the URL will change to a token)
Check "Force next update"
Change the "Auto refresh every" to 7 or something lower than 30.
[Save]
Last Result should say Update Successfully.



Start OpenVPN Server

Go to VPN Tunneling -> OpenVPN Server (http://192.168.1.1/vpn-server.asp).

On "Server 1 -> Status" Tab, click the "Start Now" button. Give it a few seconds and click on the "Refresh Status" link.

If you see the following, then the OpenVPN Server has started successfully. Congratulations we're almost there. Note that the button will change to "Stop Now". If the button remains as "Start Now", we have a problem. Go back and review the instructions.



Configuration of Site A Router is complete. Go ahead and reboot the router and verify that OpenVPN Server started properly.

Let's move on to setting up your Site B Router.

Setup OpenVPN Client on Site B Router

Configure OpenVPN Client

At Site B, open up your browser and go to VPN Tunneling -> OpenVPN Client (http://192.168.2.1/vpn-client.asp). Go to Client 1 -> Basic.

Type in the Dynamic DNS address (subdomain) you setup for your Site A router in the "Server Address" field. In my example,  "OpenVPNServer.mooo.com"
Uncheck the "Connect NAT on tunnel"
Check "Start with WAN"
[Save]




Nothing has to be changed on the Client 1 -> Advanced Tab

Open up the Client 1 -> Keys Tab.

Open up "ClientRouterKeys.txt" file you created earlier in the tutorial and cut/paste the certificates and key into the appropriate field.

ca.crt in the Certificate Authority box
Site2SiteClient.crt in the Client Certificate box
Site2SiteClient.key in the Client Key box

Don't forget to [Save].






Your done with the configuration. The moment of truth, on the Client 1 -> Status Tab, Click "Start Now"

Wait a few seconds and click on the "Refresh Status" link. Hopefully you'll see some bytes in the Value column.



From Site B, you should now be able to access Site A network resources and vice-versa.

Lets give the VPN a quick test. Still connected to Site B, open up the OpenVPN Server Configuration page on your Site A router @ http://192.168.1.1/vpn-server.asp. Hopefully you can see a successfully status page like the one below:



Cross Site Name Resolution

At this point your Site to Site VPN is setup, but you'll only able to access network resources via IP Addresses.

To access network resources via a friendly name, you'll need to do two things:

1) Setup static DHCP lease reservation for the network device (you don't want the IP address changing)
      - Go to Basic->Static DHCP/ARP/IPT
2) On the opposite router, setup a static WINS/DNS entry for the same network device

Go to Basic->Static DHCP/ARP/IPT. Typically the Static DHCP/ARP/IPT screen is for configuring static DHCP lease reservation, however you can use for static WINS/DNS entries also. The secret is to leave the MAC Address blank or with all zeros, "00:00:00:00:00".

In the screenshot below, on SiteB, I've setup a static hostname of "SiteARouter" so that I can access it via the friendly name versus the IP Address (192.168.1.1). From SiteB, I'm now able to access SiteARouter via name. Configure static hostname entries for all network resources you want to access on both your VPN sites.



That's it!! Enjoy.

Client to Site VPN

You should easily be able to add additional OpenVPN Clients (for Client to Site VPN) by generating additional RSA Certs/Key on your OpenVPN Server Router.

#Setup and initialize environment
PATH=/opt/bin:$PATH

cd /opt/etc/easy-rsa
source ./vars

./build-key Zoe-Laptop
./build-key Landon-Laptop

#Install SFTP so you can securely access your keys
#Location of keys = /opt/etc/easy-rsa/keys
#Connect as root
opkg install openssh-sftp-server

#scp is another alternative method to access your keys

[Tutorial] CentOS 6 OpenVPN Client - Connecting to Existing Site to Site VPN

Troubleshooting and FAQ:

- Watch my walk-through video
- Make sure the time is correct on both routers (NTP is setup, watch video)
- Check the logs
- Restore Default Configuration and start fresh (backup your current config, just in case).
        Erase all data in NVRAM memory (thorough) @ http://192.168.1.1/admin-config.asp
     


Special Thanks to Shibby for the excellent firmware, the Entware Team, and Wasaga Computer's for their excellent blog (which is the original tutorial I used to successfully setup my first Site to Site VPN using TomatoUSB).

If you have any issues, have any questions or notice any mistakes, please don't hesitate to leave a comment. Your feedback will help me improve the tutorial and keep it up to date. Thank you.

28 comments :

  1. Followed this to the letter. Having an issue with the client router crashing when I start the service. No log entries to see what the problem is. Any ideas where to look?

    I have tried other tutorials with the same result of having the client router crash. Tried several builds of shibby and even bought a new Asus n66 and tried merlin's firmware.

    ReplyDelete
    Replies
    1. FYI - Chris managed to resolve this issue himself. We're not clear on the root cause, so if you experience this problem please let me know.

      The OpenVPN client router configuration is trivial. My suspicion is it has to do with the copy/pasting of the cert/keys. Maybe a illegal character somehow got added, or you're missing a required line feed.

      Delete
    2. Or could it be over nvram limit? Did you configure more than one client?

      Delete
  2. You have any recommendations for a script that can be used to monitor that status of the line and when marked as down to retry to reconnect?

    This would be useful if the OpenVPN server's connection would to go down. The script would trigger OpenVPN to retry to reconnect after x amount of time.

    ReplyDelete
    Replies
    1. Hi Nick,

      I believe this is built into the OpenVPN client. The OpenVPN client will automatically reconnect once the OpenVPN server is available again. I just rebooted my OpenVPN Server router yesterday and all my clients reconnected back just fine.

      Qui

      Delete
  3. I don't think port forwarding on server is necessary.

    My client and server setup is almost same as yours, except the port forwarding part. Anyway, I can ping server lan from a host on client lan, but not from server to a host on client lan. Any idea how to fix that?

    ReplyDelete
    Replies
    1. Hi Kevin,

      Thanks for your question.

      The only port forwarding I have is "Forward UDP Port 1194 to your router internal IP @192.168.1.1" which is definitly required.

      Server LAN to Client LAN routing is handled in the Advanced Tab of the OpenVPN Server configuration - the screenshot and section right before the Port Forwarding Section. Specifically the "Allow Client<->Client" and the "Push" based on Common Name, Subnet, Netmask.

      Please let me know if that help resolve your issue.

      Delete
    2. I fixed my own problem. The problem was the windows firewall on Win7 host. Once disabled, it can be pinged.

      I summarize things I did differently than yours:
      * I used windows version of openvpn to generate the certificates/keys. It is much easier than installing optware/entware. Besides, it reduces the need for USB drive.
      * I used jffs to store the ca/key files. Again, this relieves the need for usb drive. I used winscp to transfer ca/key files into /jffs/etc/openvpn
      * USB drive is not needed. Although Tomato with USB provides many benefits, it is not a prerequisite for running openvpn.
      * server firewall port forwarding of 1194 to server router itself is NOT necessary. I don't have it and mine worked flawlessly.
      * even on the client router, do NOT use web GUI to paste the ca/key. Use winscp to transfer to /jffs/etc/openvpn/. Entering ca/key in web GUI will use up the tiny 32kb nvram. It may be OK if you only configure one openvpn client or server. But if you ever configure/enter them for another client or server, you are bound to exceed the 32k nvram limit, and your router will behave strangely, even restoring to default setup. It is better never use web GUI to store any ca/key files for openvpn, just to be safe.

      Delete
    3. Thanks Kevin for your feedback. The USB drive isn't required for the OpenVPN setup, however I find it more elegant to generate the keys on the router and it makes for a more easy to follow tutorial (cut/paste, minimal steps).

      I understand some people, like yourself, prefer to generate the keys on their computer.

      Using /jffs to store the keys to save nvram is a great solution.

      I'll have to double check on the port forwarding. I'm confused how it would work without it. Did you start from scratch with a wipe of NVRAM? Any chance you might have some pre-existing IPTABLES entries?

      Delete
    4. Port forwarding is not needed to reach a server running on the router itself and listening on the WAN interface. Just like you don't need to forward port 22 for ssh into the router from WAN, or you don't need to forward port 8080(or 443) to reach the router web GUI from WAN. Openvpn client does not need the forwarded port 1194 to reach the openvpn server on the router from WAN.

      I agree optware is really powerful and I am still learning it. But to use it properly, you need proper setup, like partitioning the USB harddrive with a swap partition and a ext3 partition (for optware and data). It is overkill if all you need is openvpn. Removing this setup opens up the possibility for all non-USB Tomato routers.

      I want to stress the importance of my last point of it is better NOT to paste the ca/key contents directly into the web gui. Since it it very possible to exceed the nvram 32k limit. None of the Openvpn tutorials I found on the web mentions this, and I learned this the hard way. I turned on two openvpn servers and did not know it exceeded the nvram limit. The router ran OK for a couple of days, but one day, it restarted and some of my router configurations were lost. I took me a full week to troubleshoot, trying to restore the config, until I read online about this nvram limit problem.

      Delete
    5. @Kevin7890, just wanted to thank you for pointing out that the Port Forwarding section wasn't required. I've verified it and removed it from the tutorial.

      Delete
  4. I have this setup and can ping ip addresses from the either side.

    I have server using domain family1.lan and client router using family2.lan. How can I ping host.family2.lan from the server lan? I tried using server=/family2.lan/192.168.1.1 in the dnsmasq settings of server gateway, but it doesn't seem to work.

    ReplyDelete
    Replies
    1. Eddie,

      Great question on name resolution. Sorry, I don't have an ideal solution for you.

      - you can always use a host file
      - assuming you're on a windows network, on the OpenVPN Client network router, I set "WINS (for DHCP)" to point to the OpenVPN Server router IP Address.

      I believe you're on the path to the correct/ideal solution with the dnsmasq settings. If you manage to get it to work, please share. Thanks

      Delete
    2. FYI - I just added a section on name resolution.

      Delete
  5. Thank you so much for the awesome tutorial. Is there a way to route all the internet traffic through the vpn server? If I check my external IP it is still the one from the ISP

    ReplyDelete
    Replies
    1. The "Direct clients to redirect internet traffic" checkbox on the OpenVPN Server Configuration Server 1->Advanced Screen looks promising.

      You might want to look here also -
      http://openvpn.net/index.php/open-source/documentation/howto.html#redirect

      I assume the checkout will add the "redirect-gateway" directive to the OpenVPN Server configuration.

      If you get it working please report back on how. Thanks

      Delete
    2. One way of accomplishing this is by adding the "redirect-gateway" option to the client configuration file. I usually have two configuration files on each client machine where one config uses that option and one doesn't.

      Delete
  6. I have everything setup correctly, but I am unable to reach any host on the OpenVPN server LAN from the client side, apart from the server itself. Any idea what may be going on here?

    ReplyDelete
    Replies
    1. Perhaps I should also mention that the OpenVPN server router is not the gateway for this network, but sits behind another router which is forwarding the VPN traffic to it.

      Delete
    2. Sorry Ethan I can not help. Your configuration is out side the scope of the tutorial.

      Delete
    3. I've made that configuration work sometime ago by adding a new route to your gateway, that routes the OpenVPN subnet back to your OpenVPN server. If I remember correctly the problem is that the hosts on your LAN tries to respond back on requests from the OpenVPN tunnel, but sends the responses to your gateway which doesn't know how to properly route them onward. How to add this route to your gateway is device specific, but I hope you can find that information somewhere :-)

      Delete
  7. It's me again... Wanted to set up a new site-to-site... Having troubles.

    I noticed a couple of differences in the text from the video and whats posted on the blog. Not sure if that stuff matters. Anyway I have been cutting and pasting directly from this page. Here is what I have noticed.

    The key sizes are being created at 2048 instead of 1024... Not sure if this matters.

    After creating all of the certificates, outputting the the counsel does not work... Throws out an error. After a bit of poking around I discovered that the /opt/openvpn-easy-rsa/keys (keys folder) folder does not exist.

    Any insight. Where would the keys be located?

    ReplyDelete
    Replies
    1. Follow the blog. I would recommend that you start over from scratch.

      There are specific commands in the tutorial for changing the key size and creating the necessary folders which weren't properly executed.

      Delete
    2. #Set working directory and reduce key_size to 1024 in vars file
      cd /opt/openvpn-easy-rsa
      sed -i 's:`pwd`:/opt/openvpn-easy-rsa:' ./vars
      sed -i 's:KEY_SIZE=2048:KEY_SIZE=1024:' ./vars

      Delete
    3. Thanks for your quick response... Ran through this three more times today, exactly as shown in the guide.

      Still doing the 2048 key size and the keys directory does not exist.... Here is what I see after I paste the final code into putty.

      root@SiteARouter:/opt/openvpn-easy-rsa# cd /opt/openvpn-easy-rsa/keys
      -sh: cd: can't cd to /opt/openvpn-easy-rsa/keys
      root@SiteARouter:/opt/openvpn-easy-rsa# cat ./ca.crt
      cat: can't open './ca.crt': No such file or directory
      root@SiteARouter:/opt/openvpn-easy-rsa# cat ./Site2SiteClient.crt
      cat: can't open './Site2SiteClient.crt': No such file or directory
      root@SiteARouter:/opt/openvpn-easy-rsa# cat ./Site2SiteClient.key
      cat: can't open './Site2SiteClient.key': No such file or directory
      root@SiteARouter:/opt/openvpn-easy-rsa#

      Delete
    4. Hey Chris,

      Looks like the openvpn-easy-rsa entware packaged changed a little bit which broke the tutorial.

      I've updated it and just re-verified it.

      Note that I removed the Port Forwarding Section as @Kevin7890 pointed out that it's not needed (I've verified this).

      I really appreciate your persistence and letting me know that the tutorial is broken.

      Give it a try again and let me know if you're still having any issues.

      Qui

      Delete
    5. Golden! All is well... Gonna buy you some coffee..

      I appreciate your attention to my posts.

      Take Care!

      Chris

      Delete
    6. Hey Chris, thank you for the generous donation! Glad to hear you got it working.

      Delete