Is It Possible to Embed VPN Server Into Pre-configured Compiled Firmware?


I've compiled firmware for my router several times now and I often pre-configure the firmware with the config files that hold all settings. This is brilliant because I can simply factory reset the router and it goes back to a fully working router without needing to re-configure everything.

I would like to setup a OpenVPN server and I'm currently following this guide

Unfortunately I've found it too long winded and instead I've created the certificates using the desktop version of Easy-RSA using the below commands:-

sudo apt-get update
sudo-apt-get install openvpn && sudo apt-get install easy-rsa
sudo cp -r /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/

# Modify 'vars' file
sudo su
mkdir keys
source ./vars
./pkitool --initca
./pkitool --server server
cd keys
openvpn --genkey --secret ta.key

# The 4 files needed for OpenVPN:-

# Create Client key
sudo su
cd /etc/openvpn/easy-rsa/
source ./vars
./pkitool John.Smith

# Copy files to client:-
chmod -R 777 /etc/openvpn/easy-rsa

My next step is to create the server itself on OpenWrt. Would I be better off using the LuCI OpenVPN GUI or using something like WinSCP, editing the '/etc/config/openvpn' and pointing the settings to the 4 files I created with Easy-RSA inside a folder, for example '/etc/config/OpenVPN/Easy-RSA'?

The following code was pulled from an earlier revision of the guide mentioned above. This is what I was planning on using:-

# Configure Interface
uci set network.vpn="interface"
uci set network.vpn.ifname="tun0"
uci set network.vpn.proto="none"
uci set"1"
uci commit network

# Configure Firewall
uci add firewall rule
uci set firewall.@rule[-1].name="Allow-OpenVPN-Inbound"
uci set firewall.@rule[-1].target="ACCEPT"
uci set firewall.@rule[-1].src="wan"
uci set firewall.@rule[-1].proto="udp"
uci set firewall.@rule[-1].dest_port="1194"

# Configure firewall zone
uci add firewall zone
uci set firewall.@zone[-1].name="vpn"
uci set firewall.@zone[-1].input="ACCEPT"
uci set firewall.@zone[-1].forward="ACCEPT"
uci set firewall.@zone[-1].output="ACCEPT"
uci set firewall.@zone[-1].masq="1"
uci set firewall.@zone[-1].network="vpn"

# Configure port forwarding
uci add firewall forwarding
uci set firewall.@forwarding[-1].src="vpn"
uci set firewall.@forwarding[-1].dest="wan"
uci add firewall forwarding
uci set firewall.@forwarding[-1].src="vpn"
uci set firewall.@forwarding[-1].dest="lan"
uci commit firewall

# Save and reload settings
/etc/init.d/network reload
/etc/init.d/firewall reload

Many thanks


Rereading, this first paragraph probably wasn't what you were after.

Consider a script in /etc/uci-defaults/ -- it will run at every boot until it completes successfully, and will then will be deleted. You can see examples in /rom/etc/uci-defaults/ on a typical OpenWrt install, as the ROM is not altered, just the overlay.

This may be closer.

While I seldom use LuCI on a system to configure, I do find that letting it generate a working config that is close to what I want is a big time saver. You can examine its output in /etc/config/whatever and then fine-tune it to the files you want to include in your ROM.

1 Like

Yes, it's possible, I pre-generate certificates and then use the image builder to generate an image with the pre-configured OpenVPN server baked in.

I also use uci-defaults like @jeff already suggested.


I don't usually work with UCI so I'll have to reverse engineer the config files into commands. I know this sounds stupid, but is there such thing as config > uci converter; something that can print out a config file to commands? If not, I will continue to work through each of my config files. The only confusion I have for example is

uci set wireless.radio1.multicast_to_unicast='0'


uci set wireless.default_radio1.multicast_to_unicast='0'

What's the difference between radio and default_radio?

How do I know what parameter goes under what radio?

For testing purposes through SSH how do I paste a block of uci commands so they run one after another?

ssh root@routerip << EOF
 uci ...
1 Like

Yes. uci itself...
See "uci export" and "uci show" commands.


I'm trying to save my /etc/config/dhcp to UCI commands but it's not pre-fixing the UCI add/set. If I make changes in the LuCI and click save I can see what UCI commands will be executed and they look a little different to the export from UCI.

UCI export



uci add dhcp **host** # =cfg0afe63
uci set dhcp.@host[-1].name= 'PC2'
uci set dhcp.@host[-1].dns= '1'
uci set dhcp.@host[-1].mac= '11:AA:22:BB:33:CC'
uci set dhcp.@host[-1].ip= ''
uci set dhcp.@host[-1].leasetime= 'infinite'

Would I be better of running a combination of both pre-configured files and the script?