Openvpn (site-to-site)

Site-to-site bridged ethernet using OpenVPN (1 of 2)

Our headquarters is in San Diego, CA, where I live and work. The last few days, however, I’ve been working in El Paso, TX, where we have a branch office. I had three tasks this week:

  1. Help “turn up” (enable) the new T1 line to the El Paso office. I was there when it was installed 3 weeks ago, but I had to leave before it could be turned on.
  2. Bridge the LAN in the El Paso office with the LAN in San Diego, placing them on the same subnet.
  3. Install a new Avaya phone router for the El Paso phones (made by Lucent), which then are linked through the VPN to San Diego, again appearing as if both networks are contiguous.

Step 1: Get a server.

It needs two NIC’s…

Step 2: Install  Linux.

Step 3: Connect the hardware.

Give eth0 a static IP. The configs will be easier if eth0 is the external NIC. You should have one cable hooked into your LAN switch/hub, and the other cable should be on the other side of your broadband router or firewall. It should look like this:

Step 4: Install LZO compression and the lzo headers.

apt-get install liblzo1

apt-get install liblzo-dev

Step 5: Install OpenSSL and its headers.

apt-get install openssl

apt-get install libssl-dev

Step 6: Install OpenVPN.

Apt-get install openvpn

Replace ?? with the URL of the OpenVPN sources. Go to the OpenVPN website to find out what the URL of the most recent release is. Modify the following commands to match whatever release you end up downloading. Also, do your best to use the same version on both the server and the clients.

Step 7: Get more tools.

apt-get install bridge-utils

apt-get install tcpdump

Step 8: Turn on IP forwarding.

Edit /etc/network/options, set ip_forward=yes

Step 9: Configure the tun device.

mkdir /dev/net

mknod /dev/net/tun c 10 200

Step 10: Copy and edit the firewall script.

cp /usr/src/openvpn-2.0_rc21/sample-config-files/firewall.sh /etc/openvpn/firewall.sh

cd /etc/openvpn

vi firewall.sh

  • Change the value of PRIVATE to your local subnet. Yours might be 192.168.0.0/24
  • After iptables -A INPUT -p udp –dport 1194 -j ACCEPT
    add the line iptables -A INPUT -p udp –dport 4444:4449 -j ACCEPT
    or whatever port range you’re going to use for your clients.
  • If the example firewall script has NAT MASQUERADING turned on (last line), comment it out in your new copy.

Step 11: Create /etc/openvpn/opentuns.sh.

#!/bin/bash

/usr/sbin/brctl addbr br0

/usr/sbin/brctl addif br0 eth1

TAPS=”public rbre elpaso”

for name in $TAPS

do

/usr/local/sbin/openvpn –mktun –dev tap$name

/usr/sbin/brctl addif br0 tap$name

done

ifconfig eth1 0.0.0.0 promisc up

for name in $TAPS

do

ifconfig tap$name 0.0.0.0 promisc up

done

ifconfig br0 192.168.0.235 netmask 255.255.255.0 broadcast 192.168.0.255

exit 0

Add a new name to the TAPS list for each tap (port) you wish to create.

The brctl commands make a new ethernet bridge, and then bind eth1 to that bridge. This means br0 is now acting like an unmanaged switch on your LAN, and eth1 is “plugged into” that switch. When each tap is bound to the same bridge, they become participants on that switch, and will receive any traffic which passes over eth1 (they’re all “promiscuous”, which means they will listen for traffic even if it’s not directed specifically at them). The last ifconfig line in the script makes our bridge behave like a managed switch by giving it an IP address.

Remember to make opentuns.sh executable, using chmod.

Step 12: Create /etc/openvpn/common.conf.

This file provides a common config for all taps.

secret /etc/openvpn/static.key

float

ping 10

verb 5

comp-lzo

persist-tun

persist-remote-ip

persist-key

Step 13: Create an init script.

Create the file /etc/init.d/openvpn, to run everything at startup:

#!/bin/bash

/etc/openvpn/firewall.sh

/etc/openvpn/opentuns.sh

VPN=”/usr/local/sbin/openvpn –config /etc/openvpn/common.conf”

$VPN –dev tappublic –port 1194 –daemon tappublic

$VPN –dev taprbre   –port 4444 –daemon taprbre

$VPN –dev tapelpaso –port 4445 –daemon tapelpaso

exit 0

Sorry, but you have to add a new line for each tap you create. This maps the port to the tap.

Remember to make this file executable, using chmod.

In /etc/rc2.d through rc5.d, add symlinks to the file you just created. The “S number” you supply in the filename will determine the order in which your startup script is run (lowest first). I picked 19 a bit arbitrarily, based on other scripts in the rc folders.

ln -s ../init.d/openvpn S19openvpn

Step 14: Make a static key on the server.

cd /etc/openvpn (mkdir the folder if necessary)

openvpn –genkey –secret static.key

chmod go-rwx static.key

Step 15: Install OpenVPN on the client(s).

All of my roaming clients are Windows 2k or XP; download the installer on each client. Each client needs a .conf file (the name doesn’t matter) which matches the one on the server (for most items):

remote openvpn.aminus.org

port 4444

dev tap

dev-node my-tap

secret static.key

ping 10

verb 5

comp-lzo

mute 10

The remote parameter needs to point to eth0 on your server. My domain registrar has a nice DNS tool, so I added an A (host) record for openvpn.aminus.org and pointed it to the IP which I gave eth0. If you don’t care to use DNS, you can just type the IP of eth0.

On Windows clients, remember to name the new network connection “my-tap”, or whatever name you use in the client config.

Copy the static.key from the server into the /config folder on each client.

Step 16: Test OpenVPN.

On the server, type the following. Note that, for the most part, we are doing by hand what your init.d script does. We do it by hand so we can see the output at each step, in case something goes wrong:

cd /etc/openvpn

./firewall.sh

./opentuns.sh

/usr/local/sbin/openvpn –config /etc/openvpn/common.conf –dev tappublic –port 1194

Notice we do not supply the daemon argument to openvpn on the command line. This means your terminal will now be occupied running openvpn. If you need to check anything on the server while testing, Alt-F2 to another tty and login again.

Now start OpenVPN on a client; make sure the port is the same (1194, in our example). On the server side, you should start seeing traffic display in the openvpn process: it’ll start spitting out w’s and r’s as it reads and writes data from the client. On the client side, if you start openvpn manually (in Windows, right-click on your .conf file and select “Start OpenVPN on this file”) you should also see the connection as it happens. From the client, try accessing resources on the LAN (ping IPs, browse network shares, or access an internal website). If something goes wrong, fix it before proceeding to the next step.

The first thing that will most likely go wrong: you’ve got your server LAN running on the 192.168.0.x subnet, and you’re running the client at home, also on a 192.168.0.x subnet. This doesn’t work well, because your client doesn’t know whether to send local packets through the tunnel or not. If your home was running on, say, 192.168.15.x, then there would be no conflict. Change your work or home subnet to something else.

Step 17: Test your startup script.

Kill the openvpn process from step 16 using Ctrl-C. Reboot the server. Test a client again, manually. If that works, test the OpenVPNService (on Windows clients).

Site-to-site ethernet bridge over OpenVPN (2 of 2)

In a previous post, I laid out step-by-step how to set up an OpenVPN server, to support roaming VPN clients. We created an ethernet bridge so that each remote client appears on the LAN just like any desktop PC in your office. We used a dedicated OpenVPN server to act like a network switch; however, each client has to install and run software in order to connect.

Now I’m going to discuss a permanent bridge, using two Linux boxes. This allows all clients on each side to see all clients on the other side. None of the clients need to run any special software. You might use this, as I did, to connect a branch office to your headquarters. Throughout this discussion, I’m going to refer to these two Linux boxes as “vpnmaster” and “vpnslave”.

Steps 1-9: Build vpnslave.

See the previous post, steps 1 to 9. Follow those steps without any changes. We’re going to end up with the same, bridged ethernet setup on the vpnslave machine that we did with the vpnmaster.

Unlike with roaming clients, you want the same subnet in both locations. It’s no good having a bridge between divergent networks. When we’re done, all clients will exist on the same network. Imagine you have an unmanaged switch halfway between both locations, with very long cables in-between.  You need to set aside a block of IP addresses which only the computers on the slave LAN will use. For example, you might tell your DHCP server(s) at the master site to lease the addresses 192.168.0.20 to .99, and the DHCP server(s) at your slave site to lease 192.168.0.234 to .254. We’ll block any DHCP broadcasts from going over the VPN, so that computers in the slave LAN will only talk to their local DHCP servers.

Step 10: Copy and edit the firewall script.

cp /usr/src/openvpn-2.0_rc21/sample-config-files/firewall.sh /etc/openvpn/firewall.sh

cd /etc/openvpn

vi firewall.sh

  • Change the value of PRIVATE to your local subnet. Yours might be 192.168.0.0/24. Again, use the same network for the slave site that you use at the master site.
  • After iptables -A INPUT -p udp –dport 1194 -j ACCEPT
    add the line iptables -A INPUT -p udp –dport 4444:4460 -j ACCEPT
    or whatever port range you’re going to use for your clients.
  • If the example firewall script has NAT MASQUERADING turned on (last line), comment it out in your new copy. (If you’re wondering, we can’t simply use NAT to bridge two different networks, because the broadcasts would not then be routed across the bridge).
  • Add the following lines to the script. These turn off DHCP broadcasts across the slave’s bridge. You probably do not want to do this wholesale DROP on vpnmaster, because it’s probably serving roaming clients who want

iptables -A FORWARD -p tcp –dport 67:68 -j DROP

iptables -A FORWARD -p udp –dport 67:68 -j DROP

iptables -A INPUT -p tcp –dport 67:68 -j DROP

iptables -A INPUT -p udp –dport 67:68 -j DROP

Step 11: Create /etc/openvpn/opentuns.sh.

At this point, you only need one item in the TAPS list. I used “0” to make “tap0”. You may use vpnslave to serve its own remote clients, as well, but we’re not going to describe that here.

Step 12: Create /etc/openvpn/bridge.conf.

This file provides config information for the permanent bridge on vpnslave. It’s a little bit different from common.conf on vpnmaster.

remote openvpn.aminus.org

dev tap0

port 1194

secret /etc/openvpn/static.key

ping 10

verb 5

comp-lzo

Step 13: Create an init script.

Create the file /etc/init.d/openvpn, to run everything at startup:

#!/bin/bash

/etc/openvpn/firewall.sh

/etc/openvpn/opentuns.sh

/usr/local/sbin/openvpn –config /etc/openvpn/bridge.conf –daemon tap0

exit 0

Remember to make this file executable, using chmod.

Notice we’re only running one instance of openvpn. Again, if you want to serve additional, roaming clients from vpnslave, feel free. But I’d recommend doing that after the permanent pipe is up and running.

In /etc/rc2.d through rc5.d, add symlinks to the file you just created. The “S number” you supply in the filename will determine the order in which your startup script is run (lowest first). I picked 19 a bit arbitrarily, based on other scripts in the rc folders.

ln -s /etc/init.d/openvpn S19openvpn

Step 14: Copy the static.key from vpnmaster to vpnslave.

Use scp, sftp, a floppy, a thumbdrive…whatever it takes. But keep it secret. Keep it safe.

Step 15: There is no Step 15.

Step 16: Test OpenVPN.

Make sure that OpenVPN is running on vpnmaster. On vpnslave, type the following. Note that, for the most part, we are doing by hand what your init.d script does. We do it by hand so we can see the output at each step, in case something goes wrong:

cd /etc/openvpn

./firewall.sh

./opentuns.sh

/usr/local/sbin/openvpn –config /etc/openvpn/bridge.conf –dev tap0 –port 1194

Notice we do not supply the daemon argument to openvpn on the command line. This means your terminal will now be occupied running openvpn. You should start seeing traffic display in the openvpn process: it’ll start spitting out w’s and r’s as it reads and writes data from vpnmaster.

Alt-F2 to another tty and login again so you can test the connection. Try accessing resources on the LAN (ping remote boxes by IP and by name). If something goes wrong, fix it before proceeding to the next step.

If the vpnslave can ping machines on the master LAN (over the VPN), then move to another computer on the slave LAN and see if you get the same results. In some network setups, your default gateway may need a new static route, directing 192.168.0.0 packets to eth1 on vpnslave. If you’ve got a single gateway and a single switch or hub, you shouldn’t have to do this.

Step 17: Test your startup script.

Kill the openvpn process from step 16 using Ctrl-C. Reboot vpnslave. Test the connection again (from vpnslave). If that works, test again from another computer on the slave LAN.

If all that works, you’re done! Unplug the monitor, keyboard, and mouse from vpnslave and tuck it away somewhere. Come back in 5 years when the hard drive starts to make loud banging noises.

This entry was posted in Guides. Bookmark the permalink.