Setting up a Secure Bridged (Wireless) Network with OpenVPN

Getting Routed OpenVPN working for FreeBSD

Author: kz

This howto is variation off of the Routed tutorial, however we’ll do this by example since that is probably easiest to visualize for most people. This example has been tested on FreeBSD 5.4 and OpenVPN 2.0.5 but will likely work on other versions of FreeBSD including FreeBSD 6.x. The Scenario

Here’s the scenario. You have a network like the below

[FreeBSD Router]
     |    |__________
     |               |
 [Wireless Bridge] [Other servers]

Now in this scenario, you have no choice but to encrypt your network with WEP or WPA, both of which are notoriously insecure. You can choose to block by mac address but people can still sniff your mac address and in some cases they can switch the mac of their wireless and join your network anyhow, and even if they can’t there’s a high likelyhood they can sniff your traffic capturing any websites you browse to, and maybe even passwords if they are unencrypted.

OpenVPN offers a solution with this network topology:

[FreeBSD Router]
   |(if2)  |(if1)
   |       |_________
   |                 |
[Wireless Bridge]  [Other Servers]

If this solution you have a private network for your wireless bridge, and a separate network for your other ethernet connected servers.

In the following example we’ll set up this network with these assumptions (match them to your own): Our FreeBSD router has the following interfaces:

if0 at ip
if1 at ip
if2 at ip

On the router you must make sure you have the following in your kernel:

options BRIDGING
device tap

And you need to have these sysctls set (you can put them in /etc/sysctl.conf).,tap0

Getting keys set up

You can try using the tools in /usr/local/share/doc/openvpn/easy-rsa but they don’t seem to work that well. Here’s a way that does.

First step is to get you SSL keys generated. I’m not going to outline everything here since it’s mostly covered in Basics of using OpenSSL.

Suffice to say you’ll need a Root CA Cert and key (called cacert.pem and cakey.pem) outlined in Making your own CA.

You’ll need a server cert and key as well (see Making a new Certificate which will be like myserver.crt and myserver.key.

You can follow these steps to make client and server keys:

openssl req -nodes -new -keyout client1.key -out client1.csr
openssl ca -out client1.crt -in client1.csr -policy policy_anything

You’ll want to make sure that you replace client1 with something that makes sense also make sure that you make a unique common name (CN) for each client key that you create.

Likewise for the examples below you’ll want to name the server keys:

server.key, server.csr, and server.crt

Last you’ll need to generate Diffie Hellman parameters.

Configuring OpenVPN

You can find sample config files in:


We’ll start with server.conf. Copy it to


Creating your Server openvpn.conf file

Here’s an example of a full working openvpn.conf. If you read the conf that comes with openvpn it has lots of great explanations for what everything does:

port 1194
proto udp
dev tap
mode server

ca keys/cacert.pem
cert keys/
key keys/
dh keys/dh2048.pem
# Don't put this in the keys directory unless user nobody can read it
crl-verify keys/crl.pem

ifconfig-pool-persist /tmp/ipp.txt
push "redirect-gateway local def1"

client-config-dir /usr/local/etc/openvpn/bridge-clients
keepalive 10 120

cipher BF-CBC        # Blowfish (default)
max-clients 100
user nobody
group nobody

verb 3

In the above configuration the default route will automatically get pushed to the client, so there’s no need to worry about routes. One thing you should also note. In the config

client-config-dir /usr/local/etc/openvpn/bridge-clients

This allows you to explicitly assign addresses to clients based on the CN of their key. So in this example:

# ls /usr/local/etc/openvpn/bridge-clients
# cat /usr/local/etc/openvpn/bridge-clients/

We see that once they connect to OpenVPN, their tap device will get assigned to be used on the other network. A sample client.conf (for FreeBSD, Linux or OS X)

On the client side you’ll need the client keys (see above) and the conf. Like the server I store the configs in /usr/local/etc/openvpn and the keys in /usr/local/etc/openvpn/keys. For OS X you can use tunnelblick with the configuration below, likewise for Linux and FreeBSD.

#Begin client.conf
dev tap
proto udp
remote 1194
resolv-retry infinite
user nobody
group nobody
ca keys/cacert.pem
cert keys/client.crt
key keys/client.key
cipher BF-CBC
verb 3
mute 20

We can connect to the server by starting this up like the server conf:

cd /usr/local/etc/openvpn && openvpn client.conf

Getting a client working in Windows

Install the openvpn-gui from

Click on Start->OpenVPN->OpenVPN Sample Configuration Files Edit client.opvn

Change the following, make sure the client1 keys reflect the names of the keys you created for this workstation.

remote 1194

ca cacert.pem
cert client1.crt
key client1.key

cipher blowfish

Once finished click on File-> Save as… And save it in Program Files/OpenVPN/config name the file client1.ovpn

Take the certs you created above and make sure they’re in Program Files/OpenVPN/config

Right click on the Openvpn icon at the bottom (it should look like a pair of computer with red screens), and select connect and you should be connected to your network! Revoking a cetificate

This is how you’ll be making your access list. You’ll need to make sure that crl-verify is enabled in your server.conf.

To revoke a cert perform these steps:

openssl ca -revoke client.crt
openssl ca -gencrl -out /etc/ssl/CA/crl/crl.pem
cp /etc/ssl/CA/crl/crl.pem /usr/local/etc/openvpn

If you’re not running openvpn jailed you can also just create a symlink instead of copying each time. A note on OS X and Bonjour

To get bonjour/rendezvous/zeroconf working over your bridge you’ll need to make some firewall rules to pass bonjour multicast packets. If you have other multicast packets to pass, you can find their multicast addresses here:

Using pf (with the example interfaces above) here’s what I did to do so:

pass in quick on if1 dup-to if2 inet proto udp from any to port = 5353
pass in quick on if2 dup-to if1 inet proto udp from any to port = 5353

Note that these multicast packets will pass into the private network unencrypted which means any hackers sitting there wondering why they can’t route out or do anything, and using tcpdump or other like program will see these broadcasts. If this is a problem you probably shouldn’t use it.


Stress tests on a Soekris 4801 show that you’ll likely need a faster server if you plan on serving more than one client. I’ve found that with 2 clients with a high network load can cause high packet loss. If you want a similar solution using IPSec, follow these instructions.