Skip to content

The child's Mac

This is everything that makes the child’s Mac filtered and recorded, in order. It’s for a new Mac, or for rebuilding one. scripts/child-mac-check.sh checks the result.

You need: the child’s Mac, with their account and an administrator account; a parent’s Mac with the repo and ssh to the Firewalla; and AirDrop between them.

  • WireGuard peer 🔑. In the Firewalla app, add a VPN client for the Mac and save its config to filter/private/<name>.conf. Git ignores that folder.

  • VPN profile 🔑: always on, with the home check, and with IPv6 sent into the tunnel:

    Terminal window
    filter/scripts/make-profile.py --wg filter/private/<name>.conf --name "<the Mac>" \
    --mac --no-cert --home-check https://home-check.<tailnet>.ts.net/
  • History service token 🔑, named after the Mac’s history folder (the computer name, with ' as _): filter/scripts/history-token.sh add write "<folder name>".

  • History Sync Lock profile 🔑, with that token and the history service’s address as the Mac sees it through the VPN (the Firewalla’s tunnel address, port 8092): sync/scripts/make-lock-profile.py --token-file filter/private/<token file> --server http://<Firewalla tunnel address>:8092 --out filter/private/<lock profile>.

  • History Sync, signed and notarized: NOTARY_PROFILE=history-sync sync/scripts/build-app.sh.

  • Have chrome-policy/Chrome History Lock.mobileconfig and scripts/child-mac-check.sh ready to AirDrop (neither holds a secret).

  1. The child’s account is a standard user (Users & Groups, from the administrator account).
  2. The filter’s certificate. On the home network, open http://<Firewalla LAN address>:8091/ca.mobileconfig in Safari, and install it in System Settings ▸ General ▸ Device Management. Then in Keychain Access ▸ System ▸ “mitmproxy”:
    • remove any other mitmproxy certificate. The fingerprint must match curl -s http://<Firewalla LAN address>:8091/ca.pem | openssl x509 -noout -fingerprint -sha256;
    • set Trust ▸ Always Trust, in the System keychain. Not the login keychain, which the child could change. On macOS 27 the profile alone isn’t enough for Safari.
  3. WireGuard from the Mac App Store, if it isn’t there. The profile’s tunnel runs on it.
  4. VPN profile 🔑: install it. Then delete any tunnel inside the WireGuard app (keep the app), so there aren’t two with the same key.
  5. History Sync: copy it to /Applications and open it. Click Open Settings… and turn on Full Disk Access. Choose the shared folder. If it says Waiting for approval, allow it under Login Items. See History Sync.
  6. History Sync Lock profile 🔑: install it. History Sync’s Turn Off and Change… are then greyed out.
  7. Chrome History Lock, if Chrome is installed: see Chrome History Lock.
  8. VPN reconnect helper: see below.
  9. Delete the 🔑 files from the child’s Mac: Downloads, Desktop, and anywhere else AirDrop put them.

Only once the certificate is trusted, add the Mac to clients.txt, and to devices.txt as a mac.

  • From the child’s account: FILTER_IP=<Firewalla tunnel address> HOME_CHECK=https://home-check.<tailnet>.ts.net/ bash child-mac-check.sh. Every line should be ✓. It covers the account, the VPN, the reconnect helper and the home check, the certificate and its trust, a site really coming through the filter, History Sync (installed, loaded, locked, Full Disk Access, a recent check, the history service) and the Chrome lock.
  • In Family Filter for Mac: the Mac has checked in recently and no alert shows for it. A page opened on it appears in the history and in the filter’s log.

Family Filter for Mac: today’s visits from the Mac in the timeline

The Mac’s VPN connects only while home can be reached, so the Mac keeps its internet when home is down. The home check is a page that answers ok only while home can be reached. It’s served from a Tailscale container on the Firewalla through Tailscale Funnel, so nothing is opened on the router. The VPN profile also sends IPv6 into the tunnel.

A root job that makes sure the VPN comes back after the Mac wakes on a new network, such as at school. It starts the VPN when it’s disconnected, the child’s standard account is at the screen, and the home check answers.

Set its home check address first: edit HOME_CHECK at the top of scripts/vpn-reconnect/vpn-reconnect.sh to your own https://home-check.<tailnet>.ts.net/. The launch daemon doesn’t see your shell’s environment, so the default in the file is what it uses.

Terminal window
scp -r scripts/vpn-reconnect <admin>@<child's Mac>:
ssh -t <admin>@<child's Mac> 'sudo bash vpn-reconnect/install.sh && rm -r vpn-reconnect'

The files go to the administrator’s home folder, not /Users/Shared, where the child’s account could swap them before they run as root. It installs a script in /usr/local/libexec/ and a launch daemon, both owned by root. It logs each start to /Library/Logs/vpn-reconnect.log.

Sources: docs/child-mac-setup.md, scripts/vpn-reconnect/README.md, filter/README.md