An Open Access Peon

24 August 2015

Routing Wireless LAN over a VPN

The goal of this set up is to create a Wireless LAN (WLAN) that gets routed over a VPN. In this way we can create multiple WLANs that route to different places, enabling clients to pick a network to connect to. My specific use-case was to allow house users to connect to a virtual German network or to the local network.

My set up has Cisco WAP121 Small Business Access Points and a Ubuntu 14.04 server (acting as DHCP and router). My local network just consists of unmanaged switches, which will forward all VLAN traffic to every port.

Make sure Ubuntu is configured to forward IP traffic.

The new VLAN will use id 20 and the IP range 192.168.20.0-255.

In the Cisco control panel under Wireless, Networks I created a new Virtual Access Point with a VLAN ID of 20 (default is 1).

The rest of the configuration is in the Ubuntu server.

The VPN in use is OpenVPN but I expect these instructions would work with any device-based VPN. In my system this is "tun0". Having configured and confirmed the OpenVPN connects and working correctly it then needs some additional steps. Because I'm not routing all traffic through the VPN I needed to add route-nopull to the OpenVPN configuration. Additional up and down scripts are required to configure firewall and routing, so the following needs adding to the OpenVPN configuration:
route-nopull
script-security 2
up /etc/openvpn/scripts/vpn-up.sh
down /etc/openvpn/scripts/vpn-down.sh
vpn-up.sh:
#!/bin/sh
# block all incoming connections i.e. block access to this box
iptables -A INPUT -m state --state ESTABLISHED,RELATED -i $dev -j ACCEPT
iptables -A INPUT -p icmp -i $dev -j ACCEPT
iptables -A INPUT -i $dev -j DROP
# NAT connections over the tunnel
iptables -t nat -A POSTROUTING -s 192.168.20.0/24 -o $dev -j MASQUERADE
# Route between eth0.20 and the tunnel
iptables -A FORWARD -i eth0.20 -o $dev -j ACCEPT
iptables -A FORWARD -i $dev -o eth0.20 -j ACCEPT
# Start routing traffic over the tun
ip route add default table 20 dev tun0
ip rule add from 192.168.20.0/255.255.255.0 table 20
vpn-down.sh:
#!/bin/sh
# stop routing traffic to the tun
ip rule del from 192.168.20.0/255.255.255.0 table 20
ip route del default table 20 dev tun0
# block all incoming connections i.e. block access to this box
iptables -D INPUT -m state --state ESTABLISHED,RELATED -i $dev -j ACCEPT
iptables -D INPUT -p icmp -i $dev -j ACCEPT
iptables -D INPUT -i $dev -j DROP
# NAT connections over the tunnel
iptables -t nat -D POSTROUTING -s 192.168.20.0/24 -o $dev -j MASQUERADE
# Route between eth0.20 and the tunnel
iptables -D FORWARD -i eth0.20 -o $dev -j ACCEPT
iptables -D FORWARD -i $dev -o eth0.20 -j ACCEPT
We need to create an interface that will listen to VLAN 20. Install vlan interfaces support:
apt-get install vlan
Create a new file /etc/network/interfaces.d/eth0:
auto eth0.20
iface eth0.20 inet static
        address 192.168.20.1
        netmask 255.255.255.0
        vlan-raw-device eth0
We need a DHCP server to provide addresses to the VLAN:
apt-get install isc-dhcp-server
We only want DHCP offered on the new VLAN so we tell dhcpd to bind only to eth0.20 in /etc/default/isc-dhcp-server:
# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
#       Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACES="eth0.20"
Create a new subnet entry to offer IPs for in /etc/dhcp/dhcpd.conf:
subnet 192.168.20.0 netmask 255.255.255.0 {
        range 192.168.20.100 192.168.20.200;
        option routers                  192.168.20.1;
        option subnet-mask              255.255.255.0;
        option broadcast-address        192.168.20.255;
        option domain-name              "localdomain";
        option domain-name-servers      8.8.8.8;
}
Note: 8.8.8.8 is Google's public DNS, you may wish to allow DNS lookups from the Ubuntu server.

Reboot to bring the new interfaces and services up. You can manually create a VLAN interface with ip as follows:
ip link add link eth0 name eth0.20 type vlan id 20
ip addr add 192.168.20.1/24 brd 192.168.20.255 dev eth0.20
ip link set dev eth0.20 up