11 March 2026

Networking With OpenWRT

Topics: Linux, Networking
Tags: OpenWRT
OpenWRT For A Better Home (or Small Business) Router

I’ve tried open router distributions before. Installation has always been an ordeal, and even though a piece of hardware is supported, installation doesn’t always succeed. I did have DDWRT running for a while, until that router died. This time I decided to upgrade my router, rather than rush to replace a failed one. I considered these popular open firmwares: DDWRT, Fresh Tomato, and OpenWRT. DDWRT, while established and maintained, is often behind on hardware compatibility. Fresh Tomato is Broadcom Specific, limiting compatible hardware, and also lags on features. OpenWRT targets ARM based hardware, and is able to support a lot of newer hardware, and is ahead of the other distributions in both implementing new features.

I chose the Flynt 2 / GL.iNet GL-MT6000: it is wifi 6 capable, comes with a Quad Core 2Ghz ARMv8 processor, 1 GB of RAM and 8 GB of storage, making it a capable small server. It also ships with OpenWRT based firmware, installation is a simple firmware upgrade. It was easy, not just easy, impressively easy. GL.iNet’s own firmware is a fork of OpenWRT, and all one need to do is find the appropriate OpenWRT image, download it, and install it just as if it was an upgrade of the OEM firmware.

Now that installation was easy and it wasn’t an emergency replacement for a failed router, I really enjoyed that I could customize which services were installed and configure it like a Linux Server.

Basic Setup

Once flashed, OpenWRT defaults to 192.168.1.1, connect through ethernet and open a browser to that address. The initial page requires you to set a root password, this will also apply to the console root password.

First Steps

Each time you change settings, remember to click ‘Save and Apply’.

Check that NTP is turned on. System ⮞ System ⮞ Time_Synchronization.

Enable SSH access, System ⮞ Administration ⮞ SSH_Access, my recommended settings are not allow root to use a password and to only answer on the lan, then tab over and add your ssh keys.

Switch the web interface to https, System ⮞ Administration ⮞ HTTP(S)_Access. The router ships with a self signed certificate which you’ll want to replace, there are two routes for doing this: using acme, you can read the instructions at https://openwrt.org/docs/guide-user/services/tls/acmesh, or you can distribute certificates to it, I’ll talk a more about that later.

Set the IP address of your device. If you want the default with the router at 192.168.1.1, you don’t need to change anything, but I wanted to drop it in to replace a router on a different subnet, with a different ip address. The router will be pre-configured with 3 interfaces: lan, wan and wan6. By the way during setup giving the lan interface a temporary static ip on my network and then daisy chaining wan off the old router worked fine, which is helpful when you’re building the router and your setup computer isn’t isolated from the network.

Add missing packages. By design OpenWRT tries to select the minimal set of packages that will get you to a functional wifi router setup. If your device isn’t tight on storage install some common utilities, here are my suggestions: tcpdump ss bind-dig bind-host rsync bind-host bind-dig. FYI, netstat isn’t available, as the project considers it obsoleted by ss.

When you configure Wifi, check the country code on each of your connections, on my router this defaulted to 00-world, which limits the radio to a very low power level.

OpenWRT Linux Specifics

OpenWRT is minimal, and a lot of things that would normally go on persistent storage are on volatile storage. The reason it prefers volatile storage is that OpenWRT supports a lot of very limited devices, and concerns for SSD wear.

The web management interface is called LuCI, and it wraps the command line management interface uCI. You can edit the uCI configurations by hand in /etc/config, but you always need to be careful about whether a particular service is managed by uCI or it’s regular config files. A minor flaw is that if you disable uci for a service to use normal configs, if it is a core feature, you can’t disable it in LuCI or tell LuCI to only display the config file, if you make changes in LuCI, they’ll be ignored, which is much better than having two frontends trying to configure the same thing. My preference is to either work through LuCI or edit the uci config directly rather than use uci at the cli, it is important to remember that you should always make sure your changes are saved if youbetween LuCI and either of the CLI options.

OpenWRT has it’s own package manager: opkg. The package selection is limited, but this distribution has a narrow focus, the selection is pretty reasonable in context. Don’t forget to run opkg update if you’re installing from the cli, not only can the cache get stale, but it lives on volatile storage.

OpenWRT is lightweight and uses /etc/init.d to control daemons. The service command is a wrapper, so /etc/init.d uhttpd restart and service uhttpd are the same thing.

OpenWRT uses Dropbear as its ssh server, which uses both a system configuration for ssh keys in /etc/dropbear.

Installing Your Own Certificates

For my home environment I already have infrastructure using certbot and letsencrypt to generate wildcard certficates for my home network use the DNS API.

Make a directory for your certificates, and install rsync if you haven’t already.

/etc/config/uhttpd:
#       option cert '/etc/uhttpd.crt'
#       option key '/etc/uhttpd.key'
        option cert '/etc/mycert/fullchain.pem'
        option key '/etc/mycert/privkey.pem'

Create an ssh cert for root on the router and add it to authorized_keys for certagent on the infra server.

mkdir -p /root/.ssh
chmod 0700 /root.ssh
cd /root/.ssh
ssh-keygen -t ed25519 -f id_dropbear -C certagent@openwrt

Edit root’s crontab

# Run weekly on Sunday at 05:00
0 5 * * 0 rsync -r certagent@mycerthost:/ssl/mycert /etc/
# Reload utthpd which hosts LuCI after getting new cert c
# could be done with '&&' but I find separate entries more readable.
05 5 * * 0 /etc/init.d/uhttpd reload

Backing Up

You can run the sysupgrade command or use the LuCI interface. Small gzip tar files are created which are trivial to store. You can use a utility like ark to browse the configs from etc in the archive. When you customize configs you can add the files to /etc/sysupgrade.conf.

Configuring A Service Manually

For my home environment I was already running BIND for DNS and DNSMasq for DHCP only. During outages of my primary server I’ve temporarily stood up a second server, but I wanted to take this opportunity to go to a fault tolerant design, BIND is designed for it, doing it with DNSMasq will be another topic.

OpenWRT has prebuilt packages for named (BIND), and doesn’t expect it to be managed by uCI. There were still some considerations, which may be the topic of another article.

For DNSMasq I had to disable the built in service and create the ‘real’ service. Also note that you’ll want to remove the standard dnsmasq package and then install dnsmasq-full.

Create Standalone DNSMasq Config

/etc/init.d/dnsmasq-real

#!/bin/sh /etc/rc.common
START=60

start() {
    /usr/sbin/dnsmasq -C /etc/dnsmasq.conf
}

stop() {
    killall dnsmasq
}

Enable the real dnsmasq config

/etc/init.d/dnsmasq stop
/etc/init.d/dnsmasq disable
chmod +x /etc/init.d/dnsmasq-real
 /etc/init.d/dnsmasq-real enable
 /etc/init.d/dnsmasq-real start

# check for correct dnsmasq server in running processes.
pgrep -fa dnsmasq

Add Custom Config to Backup

Add the following to /etc/sysupgrade.conf, changes take effect after reboot.

/etc/dnsmasq.conf
/etc/dnsmasq.d/