I'm a big believer in privacy and don't want my ISP to collect data about my browsing. I have decided to setup an OpenVPN server on a DigitalOcean droplet for $5/mo (Get your own server here with $10 credit). However, for whatever reason, I wanted to set up the VPN on the router level, so that all my devices get it's benefits.
The router I choose to do this is TP-Link's TL-WR840N V5, which only has 4 MB of Flash memory, but has 64 MB of RAM.
The 4 MB of flash are a showstopper in most cases for OpenVPN on OpenWRT. The packages openvpn-openssl and libopenssl are too big to fit into the 4MB with the rest of the system, even with the Web UI (LUCI) removed.
A possible solution, that ended up working perfectly, is to download OpenVPN and OpenSSL on boot from the Internet into RAM (tmpfs), extract it and run OpenVPN from the /tmp directory which is stored in RAM.
Warning
Please note that this will only work with WR840N and not with WR740N! I am not responsible for any possible damage that may incur from following this tutorial. The prebuilt image and packages are applicable for WR840N V5 only, and must not be used with other routers. The same applies for the building instructions.
Prerequisites
Obtain a client.ovpn file that contains all the data necessary for your VPN connection. In a future post I will show how to install and setup OpenVPN on an Ubuntu server.
Install OpenWRT on your router, without LUCI but with kmod-tun zlib liblzo nano packages.
I used the following commands to build the system image:
sudo apt -y install build-essential subversion libncurses5-dev zlib1g-dev gawk gcc-multilib flex git-core gettext libssl-dev
cd ~
mkdir openwrt && cd openwrt
wget https://milankragujevic.com/uploads/openwrt/mt76x8/openwrt-imagebuilder-ramips-mt76x8.Linux-x86_64.tar.xz
tar -xaf openwrt-imagebuilder-ramips-mt76x8.Linux-x86_64.tar.xz
cd openwrt-imagebuilder-ramips-mt76x8.Linux-x86_64/
make image PROFILE=tl-wr840n-v5 PACKAGES="-ppp -ppp-mod-pppoe -ip6tables -odhcp6c -kmod-ipv6 -kmod-ip6tables nano opkg uhttpd -uhttpd-mod-ubus -libiwinfo-lua -luci-base -luci-app-firewall -luci-mod-admin-full -luci-theme-bootstrap kmod-tun zlib liblzo" CONFIG_IPV6=n
cd ~/openwrt/openwrt-imagebuilder-ramips-mt76x8.Linux-x86_64/bin/targets/ramips/mt76x8/
>> openwrt-ramips-mt76x8-tl-wr840n-v5-squashfs-sysupgrade.bin
Or, if you're lazy and trust me, you can download a prebuilt image that I created for WR840N V5. Note the version number!
Download openwrt-ramips-mt76x8-tl-wr840n-v5-squashfs-sysupgrade.bin
Also obtain libopenssl.ipk and openvpn-openssl.ipk and store them on some server. Please don't leech off of mine, and also I can't guarantee that the URLs will stay the same.
Store the IPK files on your VPN server, and install nginx to serve them.
SSH into the router (ssh [email protected]).
Create /etc/openvpn and /tmp/root
mkdir -p /etc/openvpn
mkdir -p /tmp/root
Download client.ovpn
cd /etc/openvpn
wget "http://[yourVpnServerIP]/client.ovpn" -O client.ovpn
Replace [yourVpnServerIP] with the actual IP of your VPN server.
Create the installer script
Create /etc/openvpn/install_openvpn_in_ram and put the following in it:
#!/bin/sh /etc/rc.common
RAM_ROOT=/tmp/root
export PATH=$PATH:$RAM_ROOT/usr/bin:$RAM_ROOT/usr/sbin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RAM_ROOT/usr/lib
PACKAGES='libopenssl openvpn-openssl'
start() {
[ ! -d $RAM_ROOT ] && mkdir $RAM_ROOT
cd $RAM_ROOT
for PACKAGE in $PACKAGES
do
echo Installing $PACKAGE...
wget http://[yourVpnServerIP]/$PACKAGE.ipk
tar xzf $PACKAGE.ipk
tar xzf data.tar.gz
find . -maxdepth 1 -type f -exec rm {} \;
done
}
Replace [yourVpnServerIP] with the actual IP of your VPN server.
Create the starter script
Create /etc/openvpn/openvpn and put the following in it:
#!/bin/sh /etc/rc.common
RAM_ROOT=/tmp/root
export PATH=$PATH:$RAM_ROOT/usr/bin:$RAM_ROOT/usr/sbin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RAM_ROOT/usr/lib
start() {
openvpn --writepid /tmp/openvpn.pid --daemon --cd /etc/openvpn --config client.ovpn
}
stop() {
PIDOF=$(ps | egrep openvpn | egrep -v grep | awk '{print $1}')
kill ${PIDOF}
}
Make OpenVPN auto start on boot
Replace the contents of /etc/rc.local with the following:
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
## Download and Install OpenVPN in RAM ##
sleep 60
# Execute install script
/etc/openvpn/install_openvpn_in_ram start
## Start OpenVPN ##
sleep 300
# OpenVPN start script
/etc/openvpn/openvpn start
exit 0
Make the scripts executable
chmod +x /etc/openvpn/install_openvpn_in_ram
chmod +x /etc/openvpn/openvpn
chmod +x /etc/rc.local
Add network interface tun0 as vpn
Open /etc/config/network and add the following:
config interface 'vpn'
option ifname 'tun0'
option proto 'unmanaged'
Add firewall rules to forward traffic through vpn
Open /etc/config/firewall and replace the contents of the file with the following:
config defaults
option syn_flood 1
option input ACCEPT
option output ACCEPT
option forward REJECT
option disable_ipv6 1
config zone
option name lan
list network 'lan'
option input ACCEPT
option output ACCEPT
option forward ACCEPT
config zone
option name wan
list network 'wan'
option input REJECT
option output ACCEPT
option forward REJECT
option masq 1
option mtu_fix 1
config zone
option name vpn
list network 'vpn'
option input REJECT
option output ACCEPT
option forward REJECT
option masq 1
option mtu_fix 1
config forwarding
option src lan
option dest vpn
config rule
option name Allow-DHCP-Renew
option src wan
option proto udp
option dest_port 68
option target ACCEPT
option family ipv4
config rule
option name Allow-Ping
option src wan
option proto icmp
option icmp_type echo-request
option family ipv4
option target ACCEPT
config rule
option name Allow-IGMP
option src wan
option proto igmp
option family ipv4
option target ACCEPT
config rule
option name Allow-IPSec-ESP
option src wan
option dest lan
option proto esp
option target ACCEPT
config rule
option name Allow-ISAKMP
option src wan
option dest lan
option dest_port 500
option proto udp
option target ACCEPT
config include
option path /etc/firewall.user
Make sure the configuration is preserved when upgrading
Edit /etc/sysupgrade.conf and add the following:
/etc/openvpn
Reboot the router
Either execute reboot in the shell or unplug the router then plug it back in.
Check your IP
Make sure that your IP is shown as being the IP of your VPN. You can check this using my script here or by searching Google for "what's my ip".