← Back to feed

My kids lie about the internet when they argue

Permalink
Published: 2025-12-30 16:30:00
Discovered: 2026-03-19 13:50:20
Hash: 4896163eb964d9ae1c1cf87229d39be0219192dc
https://www.tornevalls.se/my-kids-lie-about-the-internet-when-they-argue/
Description
Warning! This is techy mumbo jumbo linux-howto-article! To get a translation of this text, hide the swedish version and click on the english version.
Content
Warning! This is techy mumbo jumbo linux-howto-article!

To get a translation of this text, hide the swedish version and click on the english version.

Svensk Version

Det enda som verkligen tycks betyda något i barnens liv, bortsett från de gånger de faktiskt uppskattar att träffa vänner och gå ut, är internet. Därför har jag under lång tid använt internet som ett tydligt styrmedel: sköter man sina åtaganden är internet öppet. Sköter man inget alls är internet helt stängt.

Det fungerar för det mesta. Problemet uppstår när det blir bråk.

I de lägena dyker det ofta upp påståenden om att internet absolut behövs för skolarbete. Det är inte särskilt troligt mitt under ett lov, men det händer faktiskt att skolarbeten måste göras även då. Ibland handlar det inte ens om skola, utan om något så basalt som att någon behöver kunna somna med ljud i hörlurarna.

Table of Contents
Toggle
Så hur gör man då?Vad jag faktiskt har byggtHur ser det ut?1. Fasta IP per enhet (DHCP)2. En konfigurationsfil med domäner som ska kunna blockas3. Resolver som gör om domäner till CIDR-ranges4. State per person5. Styrning med ett kommando6. Apply-fasen (iptables)So how do you deal with it?What I have actually builtWhat does it look like?1. Fixed IPs per device (DHCP)2. A configuration file with domains that can be blocked3. Resolver that turns domains into CIDR ranges4. State per person5. Control with a single command6. Apply phase (iptables)
Så hur gör man då?

Den enkla lösningen är inte att antingen stänga allt eller släppa allt. Lösningen är att begränsa internet på personnivå.

Problemet är att de flesta färdiga brandväggslösningar och föräldrakontroller som klarar detta på riktigt ofta är dyra, inlåsta eller alldeles för grova. DNS-baserade lösningar räcker inte heller i ett hushåll där flera personer delar samma uppkoppling. Då måste man kunna begränsa per individ, inte per nätverk.

Det var här behovet uppstod på riktigt. Inte minst eftersom Emily aktivt försökte hitta kryphål till internet.

Vad jag faktiskt har byggt

Jag har byggt ett system där varje person i hushållet behandlas individuellt på nätverksnivå. Varje enhet har ett fast internt IP och knyts till en person. Utifrån det kan internet styras i tre tydliga lägen:

Full tillgång: allt är öppet

Avstängt: all trafik stoppas helt

Begränsat: internet är på, men utvalda tjänster blockeras

Den begränsade nivån är den intressanta. I stället för att försöka filtrera innehåll via DNS eller appar används brandväggsregler som blockerar hela nätblock (CIDR-ranges) för specifika tjänster som spelplattformar och streaming. Det gör det betydligt svårare att kringgå, eftersom det inte räcker att byta DNS, app eller domän.

För att detta ska vara hanterbart i praktiken har jag byggt ett eget styrscript. Med ett enda kommando kan jag slå på, stänga av eller begränsa internet för en specifik person eller till och med en specifik enhet. Status går alltid att se, och systemet överlever både omstarter och nätverksändringar.

Resultatet är att argumenten om “jag behöver internet till skolan” inte längre automatiskt innebär fritt spelrum. Internet kan vara öppet där det faktiskt behövs, samtidigt som det som orsakar konflikterna hålls borta.

Det här är ingen kommersiell produkt och inget universallösning. Det är ett tekniskt svar på ett väldigt vardagligt problem i ett hushåll där internet blivit en central del av allt.

Hur ser det ut?

Här är en förenklad bild av hur det fungerar i praktiken. Inget är magiskt: allt bygger på fasta interna IP per enhet, en liten state-fil per person och en apply-slinga som lägger iptables-regler.

1. Fasta IP per enhet (DHCP)

Varje relevant enhet får en fast adress i DHCP (MAC -> fixed-address). Exempel:

host Emily {
hardware ethernet <mac>;
fixed-address 10.1.1.53;
}

host SkolEmily {
hardware ethernet <mac>;
fixed-address 10.1.1.51;
}

host SkolEmily2 {
hardware ethernet <mac>;
fixed-address 10.1.1.52;
}

2. En konfigurationsfil med domäner som ska kunna blockas

Filen /var/tornevall/system/etc/resolver/iplist.conf innehåller bara hostnames/domäner, en per rad:

roblox.com
www.roblox.com
youtube.com
www.youtube.com
steamcommunity.com
store.steampowered.com

3. Resolver som gör om domäner till CIDR-ranges

Resolvern är ett separat hjälpscript som heter resolvecidr. Dess enda uppgift är att ta en lista med domäner och översätta dem till hela nätblock (CIDR-ranges).

Detta är nödvändigt eftersom stora tjänster använder många IP-adresser för redundans och lastbalansering. Att blockera en enskild IP-adress är i praktiken meningslöst; man måste blockera hela det nät som tjänsten är tilldelad.

Resolvern arbetar i tre steg:

Slår upp en eller flera IPv4-adresser för varje domän

Kör whois på varje IP-adress

Plockar ut hela CIDR-rangen från registry-datat

En förenklad version av scriptet ser ut så här:

#!/bin/bash
set -e

CONF="/var/tornevall/system/etc/resolver/iplist.conf"
OUT="/var/tornevall/system/etc/resolver/iplist.resolved"

tmp=$(mktemp)

while read -r host; do
[ -z "$host" ] && continue
[[ "$host" =~ ^# ]] && continue

for ip in $(getent ahostsv4 "$host" | awk '{print $1}'); do
whois "$ip" | awk '/^CIDR:/ {print $2}'
done
done < "$CONF" | tr ',' '
' | sort -u > "$tmp"

mv "$tmp" "$OUT"

Resultatet skrivs till /var/tornevall/system/etc/resolver/iplist.resolved och innehåller enbart CIDR-ranges:

128.116.0.0/17
142.250.0.0/15
172.217.0.0/16
216.58.192.0/19
23.0.0.0/12

Det är den här listan som kopieras in i personens state-fil när man aktiverar strict.

4. State per person

Varje person har en state-fil:

/var/tornevall/system/etc/resolver/state-emily

/var/tornevall/system/etc/resolver/state-max

/var/tornevall/system/etc/resolver/state-thomas

Tom fil = full tillgång. Thomas = Test-state. Man bör inte blocka sig själv dock.

När man kör strict kopieras iplist.resolved in i personens state-fil.

5. Styrning med ett kommando

Scriptet kan slå av/på per person eller per enhet:

# Status
nethandle

# Stäng allt internet för Emily
nethandle emily off

# Släpp på internet men blocka valda tjänster (CIDR-listan)
nethandle emily on strict

# Bara en enhet (Antilopen) får strict, övriga kan få andra lägen
nethandle emily-antilopen on strict

# Full tillgång igen (tömmer state)
nethandle emily on

6. Apply-fasen (iptables)

En separat apply-komponent körs efter varje ändring och vid boot. Den läser state-filerna och skapar:

en kedja per person, t.ex. NH_EMILY

en JUMP-regel i FORWARD per intern IP som ska styras

DROP-regler i kedjan för varje CIDR i state-filen

Förenklat ser det ut så här:

Chain FORWARD
NH_EMILY all -- 10.1.1.23 0.0.0.0/0
NH_EMILY all -- 10.1.1.52 0.0.0.0/0
NH_EMILY all -- 10.1.1.51 0.0.0.0/0
NH_EMILY all -- 10.1.1.53 0.0.0.0/0

Chain NH_EMILY
DROP all -- 0.0.0.0/0 128.116.0.0/17
DROP all -- 0.0.0.0/0 142.250.0.0/15
...

Poängen är att blocken blir “per person” eftersom bara just de interna IP-adresserna hoppar in i kedjan.

English version
The only thing that really seems to matter in my children’s lives, apart from the times when they actually appreciate meeting friends and going out, is the internet. Because of that, for a long time I have used internet access as a clear tool for control: if you take care of your responsibilities, the internet is open. If you take care of nothing at all, the internet is completely shut off.

This works most of the time. The problem arises when arguments happen.

In those situations, claims often appear that the internet is absolutely necessary for schoolwork. That is not particularly likely in the middle of a school break, but it does in fact happen that school assignments need to be done even then. Sometimes it is not even about school, but about something as basic as someone needing to be able to fall asleep with audio in their headphones.

So how do you deal with it?

The simple solution is not to either shut everything down or let everything through. The solution is to limit internet access on a per-person basis.

The problem is that most off-the-shelf firewall solutions and parental control systems that can actually do this properly are often expensive, locked down, or far too coarse. DNS-based solutions are not sufficient either in a household where several people share the same connection. In that case, you need to be able to limit per individual, not per network.

That was where the need truly emerged. Not least because Emily actively tried to find loopholes to get internet access.

What I have actually built

I have built a system where each person in the household is handled individually at the network level. Each device has a fixed internal IP address and is tied to a person. Based on that, internet access can be controlled in three clear modes:

Full access: everything is open

Off: all traffic is completely blocked

Limited: the internet is on, but selected services are blocked

The limited mode is the interesting one. Instead of trying to filter content via DNS or apps, firewall rules are used to block entire network blocks (CIDR ranges) for specific services such as gaming platforms and streaming. This makes it significantly harder to circumvent, because it is not enough to change DNS, an app, or a domain.

To make this manageable in practice, I have built my own control script. With a single command, I can turn internet access on, off, or limit it for a specific person or even a specific device. Status is always visible, and the system survives both reboots and network changes.

The result is that arguments like “I need the internet for school” no longer automatically mean free rein. The internet can be open where it is actually needed, while what causes the conflicts is kept out.

This is not a commercial product and not a universal solution. It is a technical response to a very everyday problem in a household where the internet has become a central part of everything.

What does it look like?

Here is a simplified picture of how it works in practice. Nothing is magical: everything is based on fixed internal IPs per device, a small state file per person, and an apply loop that installs iptables rules.

1. Fixed IPs per device (DHCP)

Each relevant device gets a fixed address in DHCP (MAC -> fixed-address). Example:

host Emily {
hardware ethernet <mac>;
fixed-address 10.1.1.53;
}

host SchoolEmily {
hardware ethernet <mac>;
fixed-address 10.1.1.51;
}

host SchoolEmily2 {
hardware ethernet <mac>;
fixed-address 10.1.1.52;
}

2. A configuration file with domains that can be blocked

The file /var/tornevall/system/etc/resolver/iplist.conf contains only hostnames/domains, one per line:

roblox.com
www.roblox.com
youtube.com
www.youtube.com
steamcommunity.com
store.steampowered.com

3. Resolver that turns domains into CIDR ranges

The resolver is a separate helper script called resolvecidr. Its sole purpose is to take a list of domains and translate them into entire network blocks (CIDR ranges).

This is necessary because large services use many IP addresses for redundancy and load balancing. Blocking a single IP address is practically meaningless; you have to block the entire network that the service is assigned.

The resolver works in three steps:

Looks up one or more IPv4 addresses for each domain

Runs whois on each IP address

Extracts the full CIDR range from the registry data

A simplified version of the script looks like this:

#!/bin/bash
set -e

CONF="/var/tornevall/system/etc/resolver/iplist.conf"
OUT="/var/tornevall/system/etc/resolver/iplist.resolved"

tmp=$(mktemp)

while read -r host; do
[ -z "$host" ] && continue
[[ "$host" =~ ^# ]] && continue

for ip in $(getent ahostsv4 "$host" | awk '{print $1}'); do
whois "$ip" | awk '/^CIDR:/ {print $2}'
done
done < "$CONF" | tr ',' '\n' | sort -u > "$tmp"

mv "$tmp" "$OUT"

The result is written to /var/tornevall/system/etc/resolver/iplist.resolved and contains only CIDR ranges:

128.116.0.0/17
142.250.0.0/15
172.217.0.0/16
216.58.192.0/19
23.0.0.0/12

This is the list that is copied into a person’s state file when strict is activated.

4. State per person

Each person has a state file:

/var/tornevall/system/etc/resolver/state-emily

/var/tornevall/system/etc/resolver/state-max

/var/tornevall/system/etc/resolver/state-thomas

An empty file means full access. Thomas = test state. You should not block yourself.

When strict is used, iplist.resolved is copied into the person’s state file.

5. Control with a single command

The script can turn access on or off per person or per device:

# Status
nethandle

# Shut down all internet for Emily
nethandle emily off

# Allow internet but block selected services (CIDR list)
nethandle emily on strict

# Only one device (Antilopen) gets strict, others can have different modes
nethandle emily-antilopen on strict

# Full access again (clears state)
nethandle emily on

6. Apply phase (iptables)

A separate apply component runs after every change and at boot. It reads the state files and creates:

one chain per person, for example NH_EMILY

a JUMP rule in FORWARD per internal IP that should be controlled

DROP rules in the chain for each CIDR in the state file

Simplified, it looks like this:

Chain FORWARD
NH_EMILY all -- 10.1.1.23 0.0.0.0/0
NH_EMILY all -- 10.1.1.52 0.0.0.0/0
NH_EMILY all -- 10.1.1.51 0.0.0.0/0
NH_EMILY all -- 10.1.1.53 0.0.0.0/0

Chain NH_EMILY
DROP all -- 0.0.0.0/0 128.116.0.0/17
DROP all -- 0.0.0.0/0 142.250.0.0/15
...

The point is that the blocks become “per person” because only those specific internal IP addresses jump into the chain.

History (2 versions shown )

Changes

From 2025-12-30 16:30:00 (discovered: 2026-02-05 14:24:02) hash: 8f20e4a085f7a1980f371bb88d4b935d7346ba62
To 2025-12-30 16:30:00 (discovered: 2026-03-19 13:50:20) hash: 4896163eb964d9ae1c1cf87229d39be0219192dc
Title
My kids lie about the internet when they argue
Description
Warning! This is techy mumbo jumbo linux-howto-article! To get a translation of this text, hide the swedish version and click on the english version.
Content
Warning! This is techy mumbo jumbo linux-howto-article! To get a translation of this text, hide the swedish version and click on the english version. Svensk Version Det enda som verkligen tycks betyda nÃ¥got något i barnens liv, bortsett frÃ¥n från de gÃ¥nger gånger de faktiskt uppskattar att träffa vänner träffa vänner och gÃ¥ ut, är är internet. Därför Därför har jag under lÃ¥ng lång tid använt använt internet som ett tydligt styrmedel: sköter sköter man sina Ã¥taganden är åtaganden är internet öppet. Sköter öppet. Sköter man inget alls är är internet helt stängt. stängt. Det fungerar för för det mesta. Problemet uppstÃ¥r när uppstår när det blir brÃ¥k. bråk. I de lägena lägena dyker det ofta upp pÃ¥stÃ¥enden påståenden om att internet absolut behövs för behövs för skolarbete. Det är är inte särskilt särskilt troligt mitt under ett lov, men det händer händer faktiskt att skolarbeten mÃ¥ste göras även dÃ¥. måste göras även då. Ibland handlar det inte ens om skola, utan om nÃ¥got sÃ¥ något basalt som att nÃ¥gon behöver någon behöver kunna somna med ljud i hörlurarna. hörlurarna. Table of Contents Toggle SÃ¥ hur gör gör man dÃ¥?Vad då?Vad jag faktiskt har byggtHur ser det ut?1. Fasta IP per enhet (DHCP)2. En konfigurationsfil med domäner domäner som ska kunna blockas3. Resolver som gör gör om domäner domäner till CIDR-ranges4. State per person5. Styrning med ett kommando6. Apply-fasen (iptables)So how do you deal with it?What I have actually builtWhat does it look like?1. Fixed IPs per device (DHCP)2. A configuration file with domains that can be blocked3. Resolver that turns domains into CIDR ranges4. State per person5. Control with a single command6. Apply phase (iptables) SÃ¥ hur gör gör man dÃ¥? då? Den enkla lösningen är lösningen är inte att antingen stänga stänga allt eller släppa släppa allt. Lösningen är Lösningen är att begränsa begränsa internet pÃ¥ personnivÃ¥. personnivå. Problemet är är att de flesta färdiga brandväggslösningar färdiga brandväggslösningar och föräldrakontroller föräldrakontroller som klarar detta pÃ¥ riktigt ofta är är dyra, inlÃ¥sta inlåsta eller alldeles för för grova. DNS-baserade lösningar räcker lösningar räcker inte heller i ett hushÃ¥ll där hushåll där flera personer delar samma uppkoppling. DÃ¥ mÃ¥ste måste man kunna begränsa begränsa per individ, inte per nätverk. nätverk. Det var här här behovet uppstod pÃ¥ riktigt. Inte minst eftersom Emily aktivt försökte försökte hitta kryphÃ¥l kryphål till internet. Vad jag faktiskt har byggt Jag har byggt ett system där där varje person i hushÃ¥llet hushållet behandlas individuellt pÃ¥ nätverksnivÃ¥. nätverksnivå. Varje enhet har ett fast internt IP och knyts till en person. UtifrÃ¥n Utifrån det kan internet styras i tre tydliga lägen: lägen: Full tillgÃ¥ng: tillgång: allt är öppet Avstängt: är öppet Avstängt: all trafik stoppas helt Begränsat: Begränsat: internet är pÃ¥, är på, men utvalda tjänster tjänster blockeras Den begränsade nivÃ¥n är begränsade nivån är den intressanta. I stället för stället för att försöka försöka filtrera innehÃ¥ll innehåll via DNS eller appar används brandväggsregler används brandväggsregler som blockerar hela nätblock nätblock (CIDR-ranges) för för specifika tjänster tjänster som spelplattformar och streaming. Det gör gör det betydligt svÃ¥rare svårare att kringgÃ¥, kringgå, eftersom det inte räcker räcker att byta DNS, app eller domän. För domän. För att detta ska vara hanterbart i praktiken har jag byggt ett eget styrscript. Med ett enda kommando kan jag slÃ¥ pÃ¥, stänga slå på, stänga av eller begränsa begränsa internet för för en specifik person eller till och med en specifik enhet. Status gÃ¥r går alltid att se, och systemet överlever bÃ¥de överlever både omstarter och nätverksändringar. nätverksändringar. Resultatet är är att argumenten om “jag behöver behöver internet till skolan” inte längre längre automatiskt innebär innebär fritt spelrum. Internet kan vara öppet där öppet där det faktiskt behövs, behövs, samtidigt som det som orsakar konflikterna hÃ¥lls hålls borta. Det här är här är ingen kommersiell produkt och inget universallösning. universallösning. Det är är ett tekniskt svar pÃ¥ ett väldigt väldigt vardagligt problem i ett hushÃ¥ll där hushåll där internet blivit en central del av allt. Hur ser det ut? Här är Här är en förenklad förenklad bild av hur det fungerar i praktiken. Inget är är magiskt: allt bygger pÃ¥ fasta interna IP per enhet, en liten state-fil per person och en apply-slinga som lägger lägger iptables-regler. 1. Fasta IP per enhet (DHCP) Varje relevant enhet fÃ¥r får en fast adress i DHCP (MAC -> fixed-address). Exempel: host Emily { hardware ethernet ; fixed-address 10.1.1.53; } host SkolEmily { hardware ethernet ; fixed-address 10.1.1.51; } host SkolEmily2 { hardware ethernet ; fixed-address 10.1.1.52; } 2. En konfigurationsfil med domäner domäner som ska kunna blockas Filen /var/tornevall/system/etc/resolver/iplist.conf innehÃ¥ller innehåller bara hostnames/domäner, hostnames/domäner, en per rad: roblox.com www.roblox.com youtube.com www.youtube.com steamcommunity.com store.steampowered.com 3. Resolver som gör gör om domäner domäner till CIDR-ranges Resolvern är är ett separat hjälpscript hjälpscript som heter resolvecidr. Dess enda uppgift är är att ta en lista med domäner domäner och översätta översätta dem till hela nätblock nätblock (CIDR-ranges). Detta är nödvändigt är nödvändigt eftersom stora tjänster använder mÃ¥nga tjänster använder många IP-adresser för för redundans och lastbalansering. Att blockera en enskild IP-adress är är i praktiken meningslöst; meningslöst; man mÃ¥ste måste blockera hela det nät nät som tjänsten är tjänsten är tilldelad. Resolvern arbetar i tre steg: SlÃ¥r Slår upp en eller flera IPv4-adresser för för varje domän Kör domän Kör whois pÃ¥ varje IP-adress Plockar ut hela CIDR-rangen frÃ¥n från registry-datat En förenklad förenklad version av scriptet ser ut sÃ¥ här: här: #!/bin/bash set -e CONF="/var/tornevall/system/etc/resolver/iplist.conf" OUT="/var/tornevall/system/etc/resolver/iplist.resolved" tmp=$(mktemp) while read -r host; do [ -z "$host" ] && continue [[ "$host" =~ ^# ]] && continue for ip in $(getent ahostsv4 "$host" | awk '{print $1}'); do whois "$ip" | awk '/^CIDR:/ {print $2}' done done < "$CONF" | tr ',' ' ' | sort -u

Versions

  1. 2025-12-30 16:30:00
    Discovered: 2026-03-19 13:50:20 Hash: 4896163eb964d9ae1c1cf87229d39be0219192dc
    Title:
    My kids lie about the internet when they argue
    Description:
    Warning! This is techy mumbo jumbo linux-howto-article! To get a translation of this text, hide the swedish version and click on the english version.
    Content
    Warning! This is techy mumbo jumbo linux-howto-article!

    To get a translation of this text, hide the swedish version and click on the english version.

    Svensk Version

    Det enda som verkligen tycks betyda något i barnens liv, bortsett från de gånger de faktiskt uppskattar att träffa vänner och gå ut, är internet. Därför har jag under lång tid använt internet som ett tydligt styrmedel: sköter man sina åtaganden är internet öppet. Sköter man inget alls är internet helt stängt.

    Det fungerar för det mesta. Problemet uppstår när det blir bråk.

    I de lägena dyker det ofta upp påståenden om att internet absolut behövs för skolarbete. Det är inte särskilt troligt mitt under ett lov, men det händer faktiskt att skolarbeten måste göras även då. Ibland handlar det inte ens om skola, utan om något så basalt som att någon behöver kunna somna med ljud i hörlurarna.

    Table of Contents
    Toggle
    Så hur gör man då?Vad jag faktiskt har byggtHur ser det ut?1. Fasta IP per enhet (DHCP)2. En konfigurationsfil med domäner som ska kunna blockas3. Resolver som gör om domäner till CIDR-ranges4. State per person5. Styrning med ett kommando6. Apply-fasen (iptables)So how do you deal with it?What I have actually builtWhat does it look like?1. Fixed IPs per device (DHCP)2. A configuration file with domains that can be blocked3. Resolver that turns domains into CIDR ranges4. State per person5. Control with a single command6. Apply phase (iptables)
    Så hur gör man då?

    Den enkla lösningen är inte att antingen stänga allt eller släppa allt. Lösningen är att begränsa internet på personnivå.

    Problemet är att de flesta färdiga brandväggslösningar och föräldrakontroller som klarar detta på riktigt ofta är dyra, inlåsta eller alldeles för grova. DNS-baserade lösningar räcker inte heller i ett hushåll där flera personer delar samma uppkoppling. Då måste man kunna begränsa per individ, inte per nätverk.

    Det var här behovet uppstod på riktigt. Inte minst eftersom Emily aktivt försökte hitta kryphål till internet.

    Vad jag faktiskt har byggt

    Jag har byggt ett system där varje person i hushållet behandlas individuellt på nätverksnivå. Varje enhet har ett fast internt IP och knyts till en person. Utifrån det kan internet styras i tre tydliga lägen:

    Full tillgång: allt är öppet

    Avstängt: all trafik stoppas helt

    Begränsat: internet är på, men utvalda tjänster blockeras

    Den begränsade nivån är den intressanta. I stället för att försöka filtrera innehåll via DNS eller appar används brandväggsregler som blockerar hela nätblock (CIDR-ranges) för specifika tjänster som spelplattformar och streaming. Det gör det betydligt svårare att kringgå, eftersom det inte räcker att byta DNS, app eller domän.

    För att detta ska vara hanterbart i praktiken har jag byggt ett eget styrscript. Med ett enda kommando kan jag slå på, stänga av eller begränsa internet för en specifik person eller till och med en specifik enhet. Status går alltid att se, och systemet överlever både omstarter och nätverksändringar.

    Resultatet är att argumenten om “jag behöver internet till skolan” inte längre automatiskt innebär fritt spelrum. Internet kan vara öppet där det faktiskt behövs, samtidigt som det som orsakar konflikterna hålls borta.

    Det här är ingen kommersiell produkt och inget universallösning. Det är ett tekniskt svar på ett väldigt vardagligt problem i ett hushåll där internet blivit en central del av allt.

    Hur ser det ut?

    Här är en förenklad bild av hur det fungerar i praktiken. Inget är magiskt: allt bygger på fasta interna IP per enhet, en liten state-fil per person och en apply-slinga som lägger iptables-regler.

    1. Fasta IP per enhet (DHCP)

    Varje relevant enhet får en fast adress i DHCP (MAC -> fixed-address). Exempel:

    host Emily {
    hardware ethernet <mac>;
    fixed-address 10.1.1.53;
    }

    host SkolEmily {
    hardware ethernet <mac>;
    fixed-address 10.1.1.51;
    }

    host SkolEmily2 {
    hardware ethernet <mac>;
    fixed-address 10.1.1.52;
    }

    2. En konfigurationsfil med domäner som ska kunna blockas

    Filen /var/tornevall/system/etc/resolver/iplist.conf innehåller bara hostnames/domäner, en per rad:

    roblox.com
    www.roblox.com
    youtube.com
    www.youtube.com
    steamcommunity.com
    store.steampowered.com

    3. Resolver som gör om domäner till CIDR-ranges

    Resolvern är ett separat hjälpscript som heter resolvecidr. Dess enda uppgift är att ta en lista med domäner och översätta dem till hela nätblock (CIDR-ranges).

    Detta är nödvändigt eftersom stora tjänster använder många IP-adresser för redundans och lastbalansering. Att blockera en enskild IP-adress är i praktiken meningslöst; man måste blockera hela det nät som tjänsten är tilldelad.

    Resolvern arbetar i tre steg:

    Slår upp en eller flera IPv4-adresser för varje domän

    Kör whois på varje IP-adress

    Plockar ut hela CIDR-rangen från registry-datat

    En förenklad version av scriptet ser ut så här:

    #!/bin/bash
    set -e

    CONF="/var/tornevall/system/etc/resolver/iplist.conf"
    OUT="/var/tornevall/system/etc/resolver/iplist.resolved"

    tmp=$(mktemp)

    while read -r host; do
    [ -z "$host" ] && continue
    [[ "$host" =~ ^# ]] && continue

    for ip in $(getent ahostsv4 "$host" | awk '{print $1}'); do
    whois "$ip" | awk '/^CIDR:/ {print $2}'
    done
    done < "$CONF" | tr ',' '
    ' | sort -u > "$tmp"

    mv "$tmp" "$OUT"

    Resultatet skrivs till /var/tornevall/system/etc/resolver/iplist.resolved och innehåller enbart CIDR-ranges:

    128.116.0.0/17
    142.250.0.0/15
    172.217.0.0/16
    216.58.192.0/19
    23.0.0.0/12

    Det är den här listan som kopieras in i personens state-fil när man aktiverar strict.

    4. State per person

    Varje person har en state-fil:

    /var/tornevall/system/etc/resolver/state-emily

    /var/tornevall/system/etc/resolver/state-max

    /var/tornevall/system/etc/resolver/state-thomas

    Tom fil = full tillgång. Thomas = Test-state. Man bör inte blocka sig själv dock.

    När man kör strict kopieras iplist.resolved in i personens state-fil.

    5. Styrning med ett kommando

    Scriptet kan slå av/på per person eller per enhet:

    # Status
    nethandle

    # Stäng allt internet för Emily
    nethandle emily off

    # Släpp på internet men blocka valda tjänster (CIDR-listan)
    nethandle emily on strict

    # Bara en enhet (Antilopen) får strict, övriga kan få andra lägen
    nethandle emily-antilopen on strict

    # Full tillgång igen (tömmer state)
    nethandle emily on

    6. Apply-fasen (iptables)

    En separat apply-komponent körs efter varje ändring och vid boot. Den läser state-filerna och skapar:

    en kedja per person, t.ex. NH_EMILY

    en JUMP-regel i FORWARD per intern IP som ska styras

    DROP-regler i kedjan för varje CIDR i state-filen

    Förenklat ser det ut så här:

    Chain FORWARD
    NH_EMILY all -- 10.1.1.23 0.0.0.0/0
    NH_EMILY all -- 10.1.1.52 0.0.0.0/0
    NH_EMILY all -- 10.1.1.51 0.0.0.0/0
    NH_EMILY all -- 10.1.1.53 0.0.0.0/0

    Chain NH_EMILY
    DROP all -- 0.0.0.0/0 128.116.0.0/17
    DROP all -- 0.0.0.0/0 142.250.0.0/15
    ...

    Poängen är att blocken blir “per person” eftersom bara just de interna IP-adresserna hoppar in i kedjan.

    English version
    The only thing that really seems to matter in my children’s lives, apart from the times when they actually appreciate meeting friends and going out, is the internet. Because of that, for a long time I have used internet access as a clear tool for control: if you take care of your responsibilities, the internet is open. If you take care of nothing at all, the internet is completely shut off.

    This works most of the time. The problem arises when arguments happen.

    In those situations, claims often appear that the internet is absolutely necessary for schoolwork. That is not particularly likely in the middle of a school break, but it does in fact happen that school assignments need to be done even then. Sometimes it is not even about school, but about something as basic as someone needing to be able to fall asleep with audio in their headphones.

    So how do you deal with it?

    The simple solution is not to either shut everything down or let everything through. The solution is to limit internet access on a per-person basis.

    The problem is that most off-the-shelf firewall solutions and parental control systems that can actually do this properly are often expensive, locked down, or far too coarse. DNS-based solutions are not sufficient either in a household where several people share the same connection. In that case, you need to be able to limit per individual, not per network.

    That was where the need truly emerged. Not least because Emily actively tried to find loopholes to get internet access.

    What I have actually built

    I have built a system where each person in the household is handled individually at the network level. Each device has a fixed internal IP address and is tied to a person. Based on that, internet access can be controlled in three clear modes:

    Full access: everything is open

    Off: all traffic is completely blocked

    Limited: the internet is on, but selected services are blocked

    The limited mode is the interesting one. Instead of trying to filter content via DNS or apps, firewall rules are used to block entire network blocks (CIDR ranges) for specific services such as gaming platforms and streaming. This makes it significantly harder to circumvent, because it is not enough to change DNS, an app, or a domain.

    To make this manageable in practice, I have built my own control script. With a single command, I can turn internet access on, off, or limit it for a specific person or even a specific device. Status is always visible, and the system survives both reboots and network changes.

    The result is that arguments like “I need the internet for school” no longer automatically mean free rein. The internet can be open where it is actually needed, while what causes the conflicts is kept out.

    This is not a commercial product and not a universal solution. It is a technical response to a very everyday problem in a household where the internet has become a central part of everything.

    What does it look like?

    Here is a simplified picture of how it works in practice. Nothing is magical: everything is based on fixed internal IPs per device, a small state file per person, and an apply loop that installs iptables rules.

    1. Fixed IPs per device (DHCP)

    Each relevant device gets a fixed address in DHCP (MAC -> fixed-address). Example:

    host Emily {
    hardware ethernet <mac>;
    fixed-address 10.1.1.53;
    }

    host SchoolEmily {
    hardware ethernet <mac>;
    fixed-address 10.1.1.51;
    }

    host SchoolEmily2 {
    hardware ethernet <mac>;
    fixed-address 10.1.1.52;
    }

    2. A configuration file with domains that can be blocked

    The file /var/tornevall/system/etc/resolver/iplist.conf contains only hostnames/domains, one per line:

    roblox.com
    www.roblox.com
    youtube.com
    www.youtube.com
    steamcommunity.com
    store.steampowered.com

    3. Resolver that turns domains into CIDR ranges

    The resolver is a separate helper script called resolvecidr. Its sole purpose is to take a list of domains and translate them into entire network blocks (CIDR ranges).

    This is necessary because large services use many IP addresses for redundancy and load balancing. Blocking a single IP address is practically meaningless; you have to block the entire network that the service is assigned.

    The resolver works in three steps:

    Looks up one or more IPv4 addresses for each domain

    Runs whois on each IP address

    Extracts the full CIDR range from the registry data

    A simplified version of the script looks like this:

    #!/bin/bash
    set -e

    CONF="/var/tornevall/system/etc/resolver/iplist.conf"
    OUT="/var/tornevall/system/etc/resolver/iplist.resolved"

    tmp=$(mktemp)

    while read -r host; do
    [ -z "$host" ] && continue
    [[ "$host" =~ ^# ]] && continue

    for ip in $(getent ahostsv4 "$host" | awk '{print $1}'); do
    whois "$ip" | awk '/^CIDR:/ {print $2}'
    done
    done < "$CONF" | tr ',' '\n' | sort -u > "$tmp"

    mv "$tmp" "$OUT"

    The result is written to /var/tornevall/system/etc/resolver/iplist.resolved and contains only CIDR ranges:

    128.116.0.0/17
    142.250.0.0/15
    172.217.0.0/16
    216.58.192.0/19
    23.0.0.0/12

    This is the list that is copied into a person’s state file when strict is activated.

    4. State per person

    Each person has a state file:

    /var/tornevall/system/etc/resolver/state-emily

    /var/tornevall/system/etc/resolver/state-max

    /var/tornevall/system/etc/resolver/state-thomas

    An empty file means full access. Thomas = test state. You should not block yourself.

    When strict is used, iplist.resolved is copied into the person’s state file.

    5. Control with a single command

    The script can turn access on or off per person or per device:

    # Status
    nethandle

    # Shut down all internet for Emily
    nethandle emily off

    # Allow internet but block selected services (CIDR list)
    nethandle emily on strict

    # Only one device (Antilopen) gets strict, others can have different modes
    nethandle emily-antilopen on strict

    # Full access again (clears state)
    nethandle emily on

    6. Apply phase (iptables)

    A separate apply component runs after every change and at boot. It reads the state files and creates:

    one chain per person, for example NH_EMILY

    a JUMP rule in FORWARD per internal IP that should be controlled

    DROP rules in the chain for each CIDR in the state file

    Simplified, it looks like this:

    Chain FORWARD
    NH_EMILY all -- 10.1.1.23 0.0.0.0/0
    NH_EMILY all -- 10.1.1.52 0.0.0.0/0
    NH_EMILY all -- 10.1.1.51 0.0.0.0/0
    NH_EMILY all -- 10.1.1.53 0.0.0.0/0

    Chain NH_EMILY
    DROP all -- 0.0.0.0/0 128.116.0.0/17
    DROP all -- 0.0.0.0/0 142.250.0.0/15
    ...

    The point is that the blocks become “per person” because only those specific internal IP addresses jump into the chain.
  2. 2025-12-30 16:30:00
    Discovered: 2026-02-05 14:24:02 Hash: 8f20e4a085f7a1980f371bb88d4b935d7346ba62
    Title:
    My kids lie about the internet when they argue
    Description:
    Warning! This is techy mumbo jumbo linux-howto-article! To get a translation of this text, hide the swedish version and click on the english version.
    Content
    Warning! This is techy mumbo jumbo linux-howto-article!

    To get a translation of this text, hide the swedish version and click on the english version.

    Svensk Version

    Det enda som verkligen tycks betyda något i barnens liv, bortsett från de gånger de faktiskt uppskattar att träffa vänner och gå ut, är internet. Därför har jag under lång tid använt internet som ett tydligt styrmedel: sköter man sina åtaganden är internet öppet. Sköter man inget alls är internet helt stängt.

    Det fungerar för det mesta. Problemet uppstår när det blir bråk.

    I de lägena dyker det ofta upp påståenden om att internet absolut behövs för skolarbete. Det är inte särskilt troligt mitt under ett lov, men det händer faktiskt att skolarbeten måste göras även då. Ibland handlar det inte ens om skola, utan om något så basalt som att någon behöver kunna somna med ljud i hörlurarna.

    Table of Contents
    Toggle
    Så hur gör man då?Vad jag faktiskt har byggtHur ser det ut?1. Fasta IP per enhet (DHCP)2. En konfigurationsfil med domäner som ska kunna blockas3. Resolver som gör om domäner till CIDR-ranges4. State per person5. Styrning med ett kommando6. Apply-fasen (iptables)So how do you deal with it?What I have actually builtWhat does it look like?1. Fixed IPs per device (DHCP)2. A configuration file with domains that can be blocked3. Resolver that turns domains into CIDR ranges4. State per person5. Control with a single command6. Apply phase (iptables)
    Så hur gör man då?

    Den enkla lösningen är inte att antingen stänga allt eller släppa allt. Lösningen är att begränsa internet på personnivå.

    Problemet är att de flesta färdiga brandväggslösningar och föräldrakontroller som klarar detta på riktigt ofta är dyra, inlåsta eller alldeles för grova. DNS-baserade lösningar räcker inte heller i ett hushåll där flera personer delar samma uppkoppling. Då måste man kunna begränsa per individ, inte per nätverk.

    Det var här behovet uppstod på riktigt. Inte minst eftersom Emily aktivt försökte hitta kryphål till internet.

    Vad jag faktiskt har byggt

    Jag har byggt ett system där varje person i hushållet behandlas individuellt på nätverksnivå. Varje enhet har ett fast internt IP och knyts till en person. Utifrån det kan internet styras i tre tydliga lägen:

    Full tillgång: allt är öppet

    Avstängt: all trafik stoppas helt

    Begränsat: internet är på, men utvalda tjänster blockeras

    Den begränsade nivån är den intressanta. I stället för att försöka filtrera innehåll via DNS eller appar används brandväggsregler som blockerar hela nätblock (CIDR-ranges) för specifika tjänster som spelplattformar och streaming. Det gör det betydligt svårare att kringgå, eftersom det inte räcker att byta DNS, app eller domän.

    För att detta ska vara hanterbart i praktiken har jag byggt ett eget styrscript. Med ett enda kommando kan jag slå på, stänga av eller begränsa internet för en specifik person eller till och med en specifik enhet. Status går alltid att se, och systemet överlever både omstarter och nätverksändringar.

    Resultatet är att argumenten om “jag behöver internet till skolan” inte längre automatiskt innebär fritt spelrum. Internet kan vara öppet där det faktiskt behövs, samtidigt som det som orsakar konflikterna hÃ¥lls borta.

    Det här är ingen kommersiell produkt och inget universallösning. Det är ett tekniskt svar på ett väldigt vardagligt problem i ett hushåll där internet blivit en central del av allt.

    Hur ser det ut?

    Här är en förenklad bild av hur det fungerar i praktiken. Inget är magiskt: allt bygger på fasta interna IP per enhet, en liten state-fil per person och en apply-slinga som lägger iptables-regler.

    1. Fasta IP per enhet (DHCP)

    Varje relevant enhet får en fast adress i DHCP (MAC -> fixed-address). Exempel:

    host Emily {
    hardware ethernet <mac>;
    fixed-address 10.1.1.53;
    }

    host SkolEmily {
    hardware ethernet <mac>;
    fixed-address 10.1.1.51;
    }

    host SkolEmily2 {
    hardware ethernet <mac>;
    fixed-address 10.1.1.52;
    }

    2. En konfigurationsfil med domäner som ska kunna blockas

    Filen /var/tornevall/system/etc/resolver/iplist.conf innehåller bara hostnames/domäner, en per rad:

    roblox.com
    www.roblox.com
    youtube.com
    www.youtube.com
    steamcommunity.com
    store.steampowered.com

    3. Resolver som gör om domäner till CIDR-ranges

    Resolvern är ett separat hjälpscript som heter resolvecidr. Dess enda uppgift är att ta en lista med domäner och översätta dem till hela nätblock (CIDR-ranges).

    Detta är nödvändigt eftersom stora tjänster använder många IP-adresser för redundans och lastbalansering. Att blockera en enskild IP-adress är i praktiken meningslöst; man måste blockera hela det nät som tjänsten är tilldelad.

    Resolvern arbetar i tre steg:

    Slår upp en eller flera IPv4-adresser för varje domän

    Kör whois på varje IP-adress

    Plockar ut hela CIDR-rangen från registry-datat

    En förenklad version av scriptet ser ut så här:

    #!/bin/bash
    set -e

    CONF="/var/tornevall/system/etc/resolver/iplist.conf"
    OUT="/var/tornevall/system/etc/resolver/iplist.resolved"

    tmp=$(mktemp)

    while read -r host; do
    [ -z "$host" ] && continue
    [[ "$host" =~ ^# ]] && continue

    for ip in $(getent ahostsv4 "$host" | awk '{print $1}'); do
    whois "$ip" | awk '/^CIDR:/ {print $2}'
    done
    done < "$CONF" | tr ',' '
    ' | sort -u > "$tmp"

    mv "$tmp" "$OUT"

    Resultatet skrivs till /var/tornevall/system/etc/resolver/iplist.resolved och innehåller enbart CIDR-ranges:

    128.116.0.0/17
    142.250.0.0/15
    172.217.0.0/16
    216.58.192.0/19
    23.0.0.0/12

    Det är den här listan som kopieras in i personens state-fil när man aktiverar strict.

    4. State per person

    Varje person har en state-fil:

    /var/tornevall/system/etc/resolver/state-emily

    /var/tornevall/system/etc/resolver/state-max

    /var/tornevall/system/etc/resolver/state-thomas

    Tom fil = full tillgång. Thomas = Test-state. Man bör inte blocka sig själv dock.

    När man kör strict kopieras iplist.resolved in i personens state-fil.

    5. Styrning med ett kommando

    Scriptet kan slå av/på per person eller per enhet:

    # Status
    nethandle

    # Stäng allt internet för Emily
    nethandle emily off

    # Släpp på internet men blocka valda tjänster (CIDR-listan)
    nethandle emily on strict

    # Bara en enhet (Antilopen) får strict, övriga kan få andra lägen
    nethandle emily-antilopen on strict

    # Full tillgång igen (tömmer state)
    nethandle emily on

    6. Apply-fasen (iptables)

    En separat apply-komponent körs efter varje ändring och vid boot. Den läser state-filerna och skapar:

    en kedja per person, t.ex. NH_EMILY

    en JUMP-regel i FORWARD per intern IP som ska styras

    DROP-regler i kedjan för varje CIDR i state-filen

    Förenklat ser det ut så här:

    Chain FORWARD
    NH_EMILY all -- 10.1.1.23 0.0.0.0/0
    NH_EMILY all -- 10.1.1.52 0.0.0.0/0
    NH_EMILY all -- 10.1.1.51 0.0.0.0/0
    NH_EMILY all -- 10.1.1.53 0.0.0.0/0

    Chain NH_EMILY
    DROP all -- 0.0.0.0/0 128.116.0.0/17
    DROP all -- 0.0.0.0/0 142.250.0.0/15
    ...

    Poängen är att blocken blir “per person” eftersom bara just de interna IP-adresserna hoppar in i kedjan.

    English version
    The only thing that really seems to matter in my children’s lives, apart from the times when they actually appreciate meeting friends and going out, is the internet. Because of that, for a long time I have used internet access as a clear tool for control: if you take care of your responsibilities, the internet is open. If you take care of nothing at all, the internet is completely shut off.

    This works most of the time. The problem arises when arguments happen.

    In those situations, claims often appear that the internet is absolutely necessary for schoolwork. That is not particularly likely in the middle of a school break, but it does in fact happen that school assignments need to be done even then. Sometimes it is not even about school, but about something as basic as someone needing to be able to fall asleep with audio in their headphones.

    So how do you deal with it?

    The simple solution is not to either shut everything down or let everything through. The solution is to limit internet access on a per-person basis.

    The problem is that most off-the-shelf firewall solutions and parental control systems that can actually do this properly are often expensive, locked down, or far too coarse. DNS-based solutions are not sufficient either in a household where several people share the same connection. In that case, you need to be able to limit per individual, not per network.

    That was where the need truly emerged. Not least because Emily actively tried to find loopholes to get internet access.

    What I have actually built

    I have built a system where each person in the household is handled individually at the network level. Each device has a fixed internal IP address and is tied to a person. Based on that, internet access can be controlled in three clear modes:

    Full access: everything is open

    Off: all traffic is completely blocked

    Limited: the internet is on, but selected services are blocked

    The limited mode is the interesting one. Instead of trying to filter content via DNS or apps, firewall rules are used to block entire network blocks (CIDR ranges) for specific services such as gaming platforms and streaming. This makes it significantly harder to circumvent, because it is not enough to change DNS, an app, or a domain.

    To make this manageable in practice, I have built my own control script. With a single command, I can turn internet access on, off, or limit it for a specific person or even a specific device. Status is always visible, and the system survives both reboots and network changes.

    The result is that arguments like “I need the internet for school” no longer automatically mean free rein. The internet can be open where it is actually needed, while what causes the conflicts is kept out.

    This is not a commercial product and not a universal solution. It is a technical response to a very everyday problem in a household where the internet has become a central part of everything.

    What does it look like?

    Here is a simplified picture of how it works in practice. Nothing is magical: everything is based on fixed internal IPs per device, a small state file per person, and an apply loop that installs iptables rules.

    1. Fixed IPs per device (DHCP)

    Each relevant device gets a fixed address in DHCP (MAC -> fixed-address). Example:

    host Emily {
    hardware ethernet <mac>;
    fixed-address 10.1.1.53;
    }

    host SchoolEmily {
    hardware ethernet <mac>;
    fixed-address 10.1.1.51;
    }

    host SchoolEmily2 {
    hardware ethernet <mac>;
    fixed-address 10.1.1.52;
    }

    2. A configuration file with domains that can be blocked

    The file /var/tornevall/system/etc/resolver/iplist.conf contains only hostnames/domains, one per line:

    roblox.com
    www.roblox.com
    youtube.com
    www.youtube.com
    steamcommunity.com
    store.steampowered.com

    3. Resolver that turns domains into CIDR ranges

    The resolver is a separate helper script called resolvecidr. Its sole purpose is to take a list of domains and translate them into entire network blocks (CIDR ranges).

    This is necessary because large services use many IP addresses for redundancy and load balancing. Blocking a single IP address is practically meaningless; you have to block the entire network that the service is assigned.

    The resolver works in three steps:

    Looks up one or more IPv4 addresses for each domain

    Runs whois on each IP address

    Extracts the full CIDR range from the registry data

    A simplified version of the script looks like this:

    #!/bin/bash
    set -e

    CONF="/var/tornevall/system/etc/resolver/iplist.conf"
    OUT="/var/tornevall/system/etc/resolver/iplist.resolved"

    tmp=$(mktemp)

    while read -r host; do
    [ -z "$host" ] && continue
    [[ "$host" =~ ^# ]] && continue

    for ip in $(getent ahostsv4 "$host" | awk '{print $1}'); do
    whois "$ip" | awk '/^CIDR:/ {print $2}'
    done
    done < "$CONF" | tr ',' '\n' | sort -u > "$tmp"

    mv "$tmp" "$OUT"

    The result is written to /var/tornevall/system/etc/resolver/iplist.resolved and contains only CIDR ranges:

    128.116.0.0/17
    142.250.0.0/15
    172.217.0.0/16
    216.58.192.0/19
    23.0.0.0/12

    This is the list that is copied into a person’s state file when strict is activated.

    4. State per person

    Each person has a state file:

    /var/tornevall/system/etc/resolver/state-emily

    /var/tornevall/system/etc/resolver/state-max

    /var/tornevall/system/etc/resolver/state-thomas

    An empty file means full access. Thomas = test state. You should not block yourself.

    When strict is used, iplist.resolved is copied into the person’s state file.

    5. Control with a single command

    The script can turn access on or off per person or per device:

    # Status
    nethandle

    # Shut down all internet for Emily
    nethandle emily off

    # Allow internet but block selected services (CIDR list)
    nethandle emily on strict

    # Only one device (Antilopen) gets strict, others can have different modes
    nethandle emily-antilopen on strict

    # Full access again (clears state)
    nethandle emily on

    6. Apply phase (iptables)

    A separate apply component runs after every change and at boot. It reads the state files and creates:

    one chain per person, for example NH_EMILY

    a JUMP rule in FORWARD per internal IP that should be controlled

    DROP rules in the chain for each CIDR in the state file

    Simplified, it looks like this:

    Chain FORWARD
    NH_EMILY all -- 10.1.1.23 0.0.0.0/0
    NH_EMILY all -- 10.1.1.52 0.0.0.0/0
    NH_EMILY all -- 10.1.1.51 0.0.0.0/0
    NH_EMILY all -- 10.1.1.53 0.0.0.0/0

    Chain NH_EMILY
    DROP all -- 0.0.0.0/0 128.116.0.0/17
    DROP all -- 0.0.0.0/0 142.250.0.0/15
    ...

    The point is that the blocks become “per person” because only those specific internal IP addresses jump into the chain.