In this guide I'll show you how to run OpenVPN server on router without enough flash (4 MB) and with enough RAM (atleast 32MB) without building custom image. It's possible to run it in RAM. The only downside is that it has to be reinstalled everytime we power cycle the router. We solve this problem by downloading and reinstalling it on every boot.

I installed it on OpenWRT and Gargoyle firmware. The only difference between two is that TUN kernel module is already included in Gargoyle, whereas it has to be inserted everytime on OpenWRT.


Let's start!

You can download scripts that do everything automatically for you below. Make sure you edit variables according to your configuration and wishes. Put config and certificates in folder on flash memory (etc. /openvpn).

OpenWRT:

#!/bin/sh
# OpenVPN in RAM script for ar71xx routers!


#Variables! Adjust to your needs!

#URL to OpenVPN package (.ipk)
OPENVPNURL="http://downloads.openwrt.org/attitude_adjustment/12.09/ar71xx/generic/packages/openvpn_2.2.2-2_ar71xx.ipk"

#Path to config file
CONFIG="/openvpn/config"

#OpenVPN port
PORT="443"

#Protocol (TCP or UDP)
PROTOCOL="tcp"
#PROTOCOL="udp"


#Start of script

#Symlink libraries that we need for OpenVPN to work as OpenVPN looks for the in /lib
ln -s /tmp/usr/lib/libssl.so.1.0.0 /lib
ln -s /tmp/usr/lib/libcrypto.so.1.0.0 /lib
ln -s /tmp/usr/lib/liblzo2.so.2 /lib

#Add commands to rc.local script, so OpenVPN is downloaded and run on boot
echo -e "while ! ping -c1 www.google.com &>/dev/null; do :; done\nopkg update\nwget -O /tmp/openvpn.ipk "$OPENVPNURL"\nopkg install /tmp/openvpn.ipk -d ram\nrm /tmp/openvpn.ipk\ninsmod /tmp/lib/modules/3.3.8/tun.ko\n/tmp/usr/sbin/openvpn --config $CONFIG\n\n$(cat /etc/rc.local)" > /etc/rc.local

#Add firewall rules
echo -e "config 'rule'\noption 'target' 'ACCEPT'\noption 'dest_port' '$PORT'\noption 'src' 'wan'\noption 'proto' 'tcpudp'\noption 'family' 'ipv4'\nconfig include\noption path '/etc/firewall.user'\n\n$(cat /etc/config/firewall)" > /etc/config/firewall

#Add iptables to firewall.user
echo -e "iptables -t nat -A prerouting_wan -p $PROTOCOL --dport $PORT -j ACCEPT\niptables -A input_wan -p $PROTOCOL --dport $PORT -j ACCEPT\niptables -I INPUT -i tun+ -j ACCEPT\niptables -I FORWARD -i tun+ -j ACCEPT\niptables -I OUTPUT -o tun+ -j ACCEPT\niptables -I FORWARD -o tun+ -j ACCEPT\n\n$(cat /etc/firewall.user)" > /etc/firewall.user

#Rebooting router to start OpenVPN
reboot

exit 0

Gargoyle:

#!/bin/sh
# OpenVPN in RAM script for ar71xx routers!


#Variables! Adjust to your needs!

#URL to OpenVPN package (.ipk)
OPENVPNURL="http://downloads.openwrt.org/attitude_adjustment/12.09/ar71xx/generic/packages/openvpn_2.2.2-2_ar71xx.ipk"

#Path to config file
CONFIG="/openvpn/config"

#OpenVPN port
PORT="443"

#Protocol (TCP or UDP)
PROTOCOL="tcp"
#PROTOCOL="udp"


#Start of script

#Symlink libraries that we need for OpenVPN to work as OpenVPN looks for the in /lib
ln -s /tmp/usr/lib/libssl.so.1.0.0 /lib
ln -s /tmp/usr/lib/libcrypto.so.1.0.0 /lib
ln -s /tmp/usr/lib/liblzo2.so.2 /lib

#Add commands to rc.local script, so OpenVPN is downloaded and run on boot
echo -e "while ! ping -c1 www.google.com &>/dev/null; do :; done\nopkg update\nwget -O /tmp/openvpn.ipk "$OPENVPNURL"\nopkg install /tmp/openvpn.ipk -d ram\nrm /tmp/openvpn.ipk\n/tmp/usr/sbin/openvpn --config $CONFIG\n\n$(cat /etc/rc.local)" > /etc/rc.local

#Add firewall rules
echo -e "config 'rule'\noption 'target' 'ACCEPT'\noption 'dest_port' '$PORT'\noption 'src' 'wan'\noption 'proto' 'tcpudp'\noption 'family' 'ipv4'\nconfig include\noption path '/etc/firewall.user'\n\n$(cat /etc/config/firewall)" > /etc/config/firewall

#Add iptables to firewall.user
echo -e "iptables -t nat -A prerouting_wan -p $PROTOCOL --dport $PORT -j ACCEPT\niptables -A input_wan -p $PROTOCOL --dport $PORT -j ACCEPT\niptables -I INPUT -i tun+ -j ACCEPT\niptables -I FORWARD -i tun+ -j ACCEPT\niptables -I OUTPUT -o tun+ -j ACCEPT\niptables -I FORWARD -o tun+ -j ACCEPT\n\n$(cat /etc/firewall.user)" > /etc/firewall.user

#Rebooting router to start OpenVPN
reboot

exit 0

Entire script is commented so you can see what is going on. You can also look in manual install below, as It's the same as script.


MANUAL INSTALL:

First we put config file and certificates on routers flash memory (etc. /openvpn). These are files that has to be in this folder (ta.key is optional, but It's recommended):

OpenVPN files

Now we paste this code in /etc/local.rc. Code in this file get's executed on boot.
Remember to edit $CONFIG with path to your config.

#Ping google.com until internet connection is working
while ! ping -c1 www.google.com &>/dev/null; do :; done
#Update package list
opkg update
#Download OpenVPN
wget -O /tmp/openvpn.ipk "http://downloads.openwrt.org/attitude_adjustment/12.09/ar71xx/generic/packages/openvpn_2.2.2-2_ar71xx.ipk"
#Install OpenVPN
opkg install /tmp/openvpn.ipk -d ram
#Remove openvpn.ipk to preserve space in ram
rm /tmp/openvpn.ipk
#Insert TUN kernel module. Delete this line on Gargoyle, as it's not needed.
insmod /tmp/lib/modules/3.3.8/tun.ko
#Start OpenVPN
/tmp/usr/sbin/openvpn --config $CONFIG

Maybe you will think why I didn't use "opkg install openvpn" to install OpenVPN. The reason is that I always got invalid package error after reboot using this command. I solved this problem with using wget to download package and then installing it with opkg.

Now we have to simlink libraries, because OpenVPN looks for them in /lib. Execute commands below.

ln -s /tmp/usr/lib/libssl.so.1.0.0 /lib
ln -s /tmp/usr/lib/libcrypto.so.1.0.0 /lib
ln -s /tmp/usr/lib/liblzo2.so.2 /lib

We have to add some lines to firewall (/etc/config/firewall) to make sure it won't block OpenVPN. Replace $PORT with port you are running OpenVPN on.

config 'rule'
option 'target' 'ACCEPT'
option 'dest_port' '$PORT'
option 'src' 'wan'
option 'proto' 'tcpudp'
option 'family' 'ipv4'
config include
option path '/etc/firewall.user'

Some iptables that are needed to get OpenVPN working correctly. Put them into /etc/firewall.user. Replace $PORT with port OpenVPN is running on and $PROTOCOL with protocol OpenVPN is using (TCP/UDP).

iptables -t nat -A prerouting_wan -p $PROTOCOL --dport $PORT -j ACCEPT
iptables -A input_wan -p $PROTOCOL --dport $PORT -j ACCEPT
iptables -I INPUT -i tun+ -j ACCEPT
iptables -I FORWARD -i tun+ -j ACCEPT
iptables -I OUTPUT -o tun+ -j ACCEPT
iptables -I FORWARD -o tun+ -j ACCEPT

After that we just reboot router and OpenVPN should be working.

I hope you will find this guide helpful.

(Last edited by n0pin on 8 Jul 2014, 19:10)