Controlling a Linux Laptop’s Internet Access

I fear the Internet. It’s powerful and full of awesome and awful things. That might be why, in my house, there are no smart devices.

This fear is now warring with my duties as a parent for ensuring my child has the best chance at succeeding in whatever she chooses to do with her life. No matter what she chooses, the Internet is likely to be a part of it because the Internet underpins everything these days. So like swimming, riding a bike, and driving a car (skills I see as necessities in Canada), she needs to learn how to handle herself on the Internet.

And like swimming, I need a shallow end. Like cycling, training wheels. Like driving, a learner’s permit. I need something to get both her and I used to the idea of the whole thing… but safer. More restrictive.

So to act as a stepping stone between always-on Full Internet Access and the “ask your parents to look something up for you”, my wife and I determined we’d repurpose an ancient and underpowered laptop (with the battery removed) as an Email and Scratch (MIT’s visual programming language that she’s using to make a Star Wars video game at the moment) machine.

I thought this’d be easy. There’s Scratch for Linux, and I could adjust the firewall to only pass IMAP (for email receipt) and SMTP (for email sending). Alas, her email is hosted by GMail, and all Google properties have standardized on OAuth2 for authentication. OAuth2 means HTTP requests. Letting HTTP access into the Laptop opens it up to always-on Full Internet Access, so what to do, what to do.

Luckily there is precisely one Google OAuth2 server with a well-known name that we need to reach over HTTP. Unluckily it can be at an arbitrary number of different IP addresses. Luckily I just learned how to use `dnsmasq` to configure how name resolution works on the laptop.

So this is how to adjust Linux Mint 19 to allow DNS queries to resolve exactly the servers I want to allow for email… and no others.

1) Tell `NetworkManager` (the network manager) to use its `dnsmasq` plugin by editing `/etc/NetworkManager/conf.d/00-use-dnsmasq.conf` to contain

[main]
dns=dnsmasq

2) Configure `dnsmasq` to our specifications by editing `/etc/NetworkManager/dnsmasq.d/00-urlfilter.conf` to contain

log-queries # Log all DNS queries for debugging purposes
log-facility=/var/log/dnsmasq.log # Log things here

no-resolv # don't use resolv.conf
interface=wlp12s0 # Bind requests on this interfaced (maybe I should bind eth0 too in case she plugs it in?)
listen-address=127.0.0.53 # This is where the system's expecting to find systemd-resolve's DNS. Take it over.

address=/#/127.0.0.1 # Resolve all hosts to localhost. Excepting the below
server=/imap.gmail.com/8.8.8.8 # Use Google's DNS to resolve incoming mail server
server=/smtp.gmail.com/8.8.8.8 # Use Google's DNS to resolve outgoing mail server
server=/googleapis.com/8.8.8.8 # Use Google's DNS to resolve OAuth2 server

3) Tell `systemd-resolved` (our current DNS resolver) not to get in our way by editing `/etc/systemd/resolved.conf` to have the line

DNSStubListener=no # Don't start the local `resolved` DNS cache/server (conflicts with dnsmasq)

4) Restart `​systemd-resolved` so it stops its DNS listener

sudo systemctl restart systemd-resolved.service

5) Restart `NetworkManager` so that `dnsmasq` can take over

sudo systemctl restart NetworkManager

Caveats:

Though this works for now insofar as loading up Firefox and trying to go to example.com will fail, it doesn’t stop the laptop from accessing the Internet. If you have an IP Address in hand, you can still get to where you want to be (though most third-party-hosted resources will fail (and since that’s how trackers work on the web, maybe this is a feature not a bug)).

Also this prevents even beneficial services from running. To update packages I need to bypass the filter (by commenting out `address=/#/127.0.0.1` and putting in `server=/#/8.8.8.8`).

Also also this effectively forbids access to local services like my network-attached storage and the printer: both things that my daughter should be able to use. (( there might be exactly one `server` line I need to add to make LAN-local shortnames resolve using my router, but I haven’t looked that up yet ))

But this was enough to get it up and running (though the laptop is ancient enough that even legacy gpu drivers have dropped support for it), and that’s the important thing. Now she’s sending emails to her relatives and fielding their responses regularly… and can crack open her Star Wars videogame and do a little recreational programming on the side.

I even had her type up her Science Fair documentation on it the other day (though she still hasn’t learned how to manually Save documents, so the ancient laptop’s instability caused some friction).

We’ll see how long this lasts. Not bad for a couple hour’s work and available parts. I wonder how soon I’ll be convinced to upgrade her to more of the Internet or a less-decrepit machine.

:chutten