This project was a few weeks in the making. When I started there was a problem with some of the software not behaving. I leave the hardware driver voodoo to those that understand it. After an update this morning I was able to get all the parts working. So what exactly is a WiFi VPN access point?
It’s the combination of several pieces of hardware and software that when running on my Pogo provides me with:
- A WiFi access point with WPA security.
- A private wireless network.
- VPN security for all wifi connections.
The end result is the Pogo acting as an Wi-Fi hotspot that any computer, tablet or phone can connect to. The wireless connection is tunneled through the ethernet connection using a VPN tunnel. The result is that any Wi-Fi connection to the Pogo automatically uses the VPN with no client configuration needed.
What follows are things I discovered from many sources. None of them were exactly what I needed for this project. Getting it all working together was a lot of work. Mostly because of the driver conflicts that came from using the Edimax EW-7811Un adapter.
Right now, this guide covers a situation that I haven’t seen anywhere else.
If you’ve been looked at my other Pogo guides, you should have almost everything. The Pogo needs to be connected to your cable/DSL modem with an ethernet cable and have internet access. This guide is built around the Edimax EW-7811Un USB Adapter. It is a low-priced and small adapter with driver support in Linux. I purchased mine for $8.99 in early March.
The problem is with the drivers for the 7811Un in the Linux kernel. They are buggy and don’t let the 7811Un work as a hotspot. The 7811Un will only work in client mode. This means the Pogo can connect to another hotspot normally. But without custom drivers, it won’t work as its own hotspot.
This was the reason for holding up this guide. The custom kernel driver for the 7811Un chip wouldn’t compile. The package was updated on March 11 and now works.
Quite a few software packages are needed. It’s all available within the ArchLinux build system.
- ArchLinux ARM
- TunnelBear VPN service
8192cunetwork driver (custom built)
The build system needs to be installed because we’re going to compile two packages. First, update your existing system.
$ sudo pacman -Syu
Then install the compiler tools and kernel headers. Using the headers from the regular kernel won’t work. It has to be the ones for the Kirkwood ARM platform. (Hint: the
--needed flag will skip packages already installed.)
$ sudo pacman -S --needed base-devel linux-kirkwood-headers
OpenVPN & DNSMasq
Install these two packages, as they are the cornerstone of our project.
$ sudo pacman -S openvpn dnsmasq
If you plan on using TunnelBear as your VPN provider, read my guide. They package their drivers in a non-standard way. I’ve sorted it out and created a system service and helper program to make life easier.
Follow the directions in the README.md file, and make sure it works. If you’re using another VPN provider, get it working using their configuration files.
This is probably the most time-consuming part. This driver has to be built against the current installed kernel. The compiling takes time. With a slow computer like the Pogo, you might want to go get a sandwich.
The package is in the
alarm repository. A standard ArchLinux ARM installation already has this configured. Start the installation and then read about why this step is needed.
$ sudo pacman -S dkms-8192cu
The original driver package was released by RealTek as GPL software. This is actually more than most companies do. It was eventually included in the mainline Linux kernel driver package. It was also a buggy turd of code. Lots of smart people have worked on it over the last couple of years. Now it’s in much better shape. But the fixes haven’t made it into the kernel yet. This is why we have to compile our own driver.
The standard install of
hostapd doesn’t work with the updated driver we just built. Luckily there’s an AUR package that applies the needed patches. Download the tarball, unpack it, and navigate into the new directory.
$ curl -O https://aur.archlinux.org/packages/ho/hostapd-rtl871xdrv/hostapd-rtl871xdrv.tar.gz $ tar xf hostapd-rtl871xdrv.tar.gz $ cd hostapd-rtl871xdrv/
Edit the build file. The version as of March 15 is missing a conflict check. If your system happens to have
hostapd already installed this will prevent an error.
$ nano PKGBUILD
Add the following after the
license line so it looks like this:
license=('custom') provides=('hostapd') conflicts=('hostapd') makedepends=('git')
Finally make the package.
Once it’s done (you might want to get another sandwich) it can be installed as a normal package. The
-U flag is to tell
pacman to use the file we just built, and not the one from its repositories.
$ sudo pacman -U hostapd-rtl871xdrv-2.2-2-arm.pkg.tar.xz
We’ll deal with the configuration files once all the software is up and running.
The default Linux packet filter will be enough for our needs. We only need to add three rules. First add some security for packets that might try and find their way into the VPN.
$ sudo iptables -A INPUT -i tun0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT $ sudo iptables -A INPUT -i tun0 -j DROP
This rule will connect the Wi-Fi network to the VPN.
$ sudo -t nat iptables -A POSTROUTING -o tun0 -j MASQUERADE
(Update 2015-04-21: add
Right now, these rules are temporary and will be lost on a reboot. To have them active, they need to be reloaded. This is done by exporting these rules then having the
iptables service load them at boot.
Export the rules. The
sudo tee command writes the
stdin as root, otherwise the redirect would fail for lack of permission.
$ sudo iptables-save | sudo tee /etc/iptables/iptables.rules
iptables and load the saved rules at startup.
$ sudo systemctl enable iptables.service
If you’ve used
iptables before you noticed that our NAT is being done of the
tun0 interface. This way if the VPN is down no traffic will get out to the internet. OpenVPN creates the
tun0 interface when it’s active. If it’s active, traffic can flow.
This is on purpose. Without the VPN, the Pogo would just be regular router. It’s also slower than my dedicated hardware cable modem/router/AP all-in-one. I don’t want to use it as a dedicated router. It’s only job is to funnel Wi-Fi to the VPN.
One bonus is the built-in self-diagnostic. If the Internet is unreachable, the VPN must be down. This way I won’t be fooled into thinking my traffic is over the VPN when it isn’t.
None of this will work if the kernel doesn’t know about it. We have to enable port forwarding. This can be done by setting the
ip_forward flag to true.
$ echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
But it will reset to
0 on reboot. We can fix that with a
$ echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-ip-forward.conf
99 at the beginning of the file ensures that it will be loaded last, after the
/proc tree is ready.
This is a good time to check that everything we’ve done so far is working. Go ahead and reboot.
$ sudo systemctl reboot
ssh’d back in, check a few things.
$ cat /proc/sys/net/ipv4/ip_forward
$ sudo iptables-save
Should output the settings we saved earlier. Mine looks like this:
# Generated by iptables-save v1.4.21 on Sun Mar 15 20:37:43 2015 *filter :INPUT ACCEPT [2304:285431] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [1199:181244] -A INPUT -i tun0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -i tun0 -j DROP COMMIT # Completed on Sun Mar 15 20:37:43 2015 # Generated by iptables-save v1.4.21 on Sun Mar 15 20:37:43 2015 *nat :PREROUTING ACCEPT [178:31347] :INPUT ACCEPT [176:30691] :OUTPUT ACCEPT [21:2489] :POSTROUTING ACCEPT [21:2489] -A POSTROUTING -o tun0 -j MASQUERADE COMMIT # Completed on Sun Mar 15 20:37:43 2015
Now, plug in the 7811Un Wi-Fi adapter. Check that it was recognized as a valid interface. It will be the one with the awkward name. It’s named
enp0s1u2 on my system.
$ ifconfig -a -s Iface MTU ... enp0s1u2 1500 ... eth0 1500 ... lo 65536 ...
If you have a name starting with
wl there’s a chance the new driver isn’t loaded.
After all this, we should have all the software ready to configure. Also, the hardware is installed and recognized.
There’s several steps involved and they touch quite a few files, I’ll break this into sections to keep it organized.
First, we need to make sure our DNS is correct. If you followed the directions for the TunnelBear setup, the
eth0.network file should be good to go. This will make sure we’re using the OpenDNS servers all of the time. It will also automatically update
If not, edit
/etc/systemd/network/eth0.network to look like this:
[Match] Name=eth0 [Network] DHCP=both DNS=22.214.171.124 DNS=126.96.36.199 [DHCP] UseDNS=false
We need to create a new file for our new interface. This does two things, it is assigned the network address
10.0.0.1 and then it is activated.
Create the file
/etc/systemd/network/enp0s1u2.network and add the following contents.
[Match] Name=enp0s1u2 [Network] Address=10.0.0.1/24
Once these files are saved, restart the network.
$ sudo systemctl restart systemd-networkd
Check that all the interfaces are now up. (Notice we’re not using the
-a flag this time.)
You should see the same results as before,
enp0s1u2 should have the
inet 10.0.0.1 address.
This one is easy, our DHCP and DNS server will come from the same program. DNSMasq has sane defaults and doesn’t require much configuration. The file
/etc/dnsmasq.conf should contain the following:
dhcp-authoritative interface=enp0s1u2 dhcp-range=enp0s1u2,10.0.0.5,10.0.0.100,255.255.255.0,6h dhcp-option=3,10.0.0.1
There are other options shown by other how-to articles, but this way doesn’t repeat settings. Mainly it’s using
/etc/resolv.conf for the DNS servers. In our case that’s okay. We set up our name servers in the
eth0.network file. If we want to change them in the future, it’s only one file that needs changing.
Create the file
/etc/hostapd/hostapd.conf with the following contents. If you have a preference, change the
wpa_passphrase to your liking. This will create a functioning 802.11n access point with WPA security. The most important change from a normal config is the use of the
rtl871xdrv driver instead of
# Wireless Interface # ================== interface=enp0s1u2 #driver=nl80211 driver=rtl871xdrv # Wireless Environment # ================== ssid=AP_Pogo channel=3 country_code=US hw_mode=g # Wireless N settings # ================== wme_enabled=1 ieee80211n=1 # WPA Settings # ================== wpa=2 auth_algs=1 wpa_passphrase=testpogo wpa_key_mgmt=WPA-PSK wpa_pairwise=TKIP rsn_pairwise=CCMP
Finally! It’s time to test our new toys. Start up the hotspot, DNS server, and VPN.
$ sudo systemctl start dnsmasq $ sudo systemctl start hostapd $ sudo tunnelbear
If you’re using another VPN, start it the more traditional way.
$ sudo systemctl start openvpn@[conf]
Then from another computer or device, find the
AP_Pogo access point and login with your passphrase.
Start at boot
To make everything start at boot enable the services with
$ sudo systemctl enable dnsmasq $ sudo systemctl enable hostapd
Having the VPN running all the time is your choice. Remember it needs the config file name added to the service name.
$ sudo systemctl enable tunnelbear@UnitedStates
I hope this guide got everything working for you. If not, leave a comment and I’ll try and help. Comments close after 14 days. After that, you can find me on Twitter.