Linux router parental control
Run adblock on your router. Change password for one WIFI beacon with one button on your phone.
Table of Contents
Our Generation
It’s not information overload. It’s filter failure.
–Clay Shirky
Like every generation, user’s of the internet are faced with an overwhelming problem particular to them and no one else, doubly so for kids among them…
Of course like every tool in existence, the internet is just that. A tool that can be used either to strengthen ones arsenal for problem solving, or for nothing of substance.
The smart among this generation understand that they are outgunned, there is no shortage of data that companies on the internet can use to figure out how to keep more eyes glued to their sites and services. The industry has built an army of psychologists, data scientists, and engineers to capitalize on this treasure trove of a weapon.
The wise understand the rules of the game and know that the best winning move is neutralizing this weapon. OpenWRT Routers are the gateway to the internet, most have basic settings from the ISP, some aftermarket builds have extra settings but most useful of all are scriptable routers running Linux. Every use-case that an engineer can think of and effectively develop is at their disposal!
Linux routers are not usually sold running Linux, it must be built using stock routers. Here is the OpenWrt guide. Rather than spend a blog post going through the boring process of finding a router and flashing OpenWRT, I’ll leave that to guides or YouTube, and focus on the scripting solution I use to create a reliable parental control system.
The environment
OpenWRT is predictably very minimal, it runs a bare bones
Linux system providing very little to work with but there is
a package manager bundled, making the job way easier. The
only program I wanted that is not on the package manager was
lf
, but a binary can be downloaded easily here and copied
over using scp
.
Steps to setup the environment
adblock
and msmtp
are at the core of the
filtering solution. However, to ease editing vim-full
over
the bundled vi
. Finally, opendoas
and shadow-useradd
to setup a user that will only execute the script over ssh.
scp -O ./lf root@192.168.1.1:/bin opkg install adblock luci-app-adblock msmtp opkg update && opkg install vim-full opendoas shadow-useradd
Adblock
Router level adblocking has a very important caveat: Bypassable by VPN. To wit, device level parental control is needed using Screen Time for example to block installation of apps.
The GUI has Blacklist/Whitelist options and many others but I think this is something sensible without delving deep into the configuration of adblock:
Choose the adblock zones
What interfaces have adblock running on them.
Enable safe search
Redirect search to safe search on major search engines.
Enable safe search on all search engines
Safe search enabled on these sites. Blacklisting can be used to get rid of other search engines for good measure.
Here is an example of an alternative search engine blacklist.
/etc/adblock/adblock.blacklist
ivacy.com www.onesearch.com onesearch.com startpage.com www.startpage.com www.flickr.com flickr.com you.com www.you.com search.brave.com search.yahoo.com www.ask.com www.baidu.com www.dogpile.com www.ecosia.org www.elastic.co www.3ds.com excite.com www.gigablast.com www.hotbot.com www.lycos.com www.metacrawler.com www.mojeek.com www.mojeek.co.uk www.petalsearch.com www.qwant.com searx.space www.sogou.com www.swisscows.com www.webcrawler.com yacy.net search.yahoo.com www.yandex.com you.com www.walla.co.il reddit.com old.reddit.com
Force local DNS
Force clients to use the router’s DNS
Flush DNS
More odds the bigger blocklists fits in RAM when reloading the adblock service.
Disabling Ethernet
Straight forward:
- network -> interfaces -> devices
then
- -> br-lan -> configure -> General device options -> Brdige ports (untick all)
Users & SSH
Here is how to add a user:
useradd netreload -g 0 -d /home/netreload -s /bin/ash passwd netreload # change the password for ssh later
netreload
: the name of the user-g 0
: Group id 0 (root)-d /home/netreload
: home directory-s /bin/ash
: default shell
Here is how to set up ssh to only execute a specific
command, in this case our script:
in /home/netreload/.ssh/authorized_keys
add the executing
machine’s ssh key like so:
command="netb-reload", ssh-ed25519 WHATEVER+YOUR+KEY+IS IOS(Shortcuts)
command="netb-reload"
: restricts dropbear ssh sessions from the following key to only execute this script that we will drop in /bin later.IOS(Shortcuts)
: Labelling the key so I can tell what it is in the future.
The script
The main file to operate on is the wireless
configuration.
Luckily awk/sed
search and replace is not needed
because OpenWRT comes bundled with it’s own scriptable
configuration tool: uci
.
/etc/config/wireless
# Some very old routers don't have this config wifi-device 'radio0' option type 'mac80211' option path 'soc/soc:pcie/pci0000:00/0000:00:01.0/0000:01:00.0' option band '5g' option hwmode '11a' option txpower '22' option country 'CA' option channel 'auto' option htmode 'VHT80' # Standard depending on the router config wifi-device 'radio1' option type 'mac80211' option path 'soc/soc:pcie/pci0000:00/0000:00:02.0/0000:02:00.0' option band '2g' option country 'CA' option htmode 'HT40' option channel '11' option cell_density '0' # Uncontrolled by the script, but under adblocking rules config wifi-iface '5Ghz' option device 'radio0' option network 'lan' option mode 'ap' option macaddr 'a0:36:22:ba:c0:31' option ssid 'Net' # hiding this network will disable apple's share password feature option hidden '1' option key 'some_other_password' option encryption 'psk2' # Target wireless network, operated on by netb-reload config wifi-iface '2Ghz' option device 'radio1' option mode 'ap' option network 'lan' option ssid 'Net B' option encryption 'psk-mixed' option key 'some_generated_password' # this is generated using /bin/pgen
pgen
: password generator.- Caveats: it’s not a strong password in the following. It’s
missing a couple of confusing characters like
l,O,0
and not using any symbols. This can be easily changed by adding characters to thechars
variable and modifying therand()
to generate indices with an upper-limit equal to the number of characters inchars
for example adding one character to chars results in 34 like so:s = s "" substr(chars, int(rand() * 34), 1);
/bin/pgen
#!/usr/bin/awk -f BEGIN { srand(); chars = "abcdefghijkmnpqrstuvwxyz123456789" s = ""; for(i = 0; i < 8;i++) { s = s "" substr(chars, int(rand() * 33), 1); } print s }
/bin/netb-reload
#!/bin/sh pass=$(pgen) log=~/password.log [ "$1" ] && log=$1 uci_pass() { doas uci set wireless.2GhzB.key="${pass}" doas uci commit doas wifi reload } mail() { EMAIL="To: $1 Subject: ROUTER PASSWORD CHANGE $pass" echo "$EMAIL" | doas msmtp -t } echo $(date) >> $log # For debugging in the future mail "notification@gmail.com" uci_pass
Remember to chmod +x netb-reload pgen
. This will run at
this point but the password wont be sent to the email until
msmtp
is configured.
msmtp
for sending emails
/etc/msmtprc
account default host smtp.gmail.com port 587 auth on user router@gmail.com password YOUR_EMAIL_PASSWORD auto_from off from router@gmail.com tls on tls_starttls on tls_certcheck off
Usage
- A simple ssh script on IOS shortcuts could ssh to
netreload@192.168.1.1
and execute the only command we let it (netb-reload
). The phone must be connected to any WIFI beacon broadcasted by the router. - In IOS shortcuts this can be automated to trigger on a specific alarm.
- A cron job can be created on the router to run at predefined times.