DEV Community

ZeroTrust Architect
ZeroTrust Architect

Posted on • Originally published at cacheguard.com

Network-Level Parental Controls: Enforcing Web Filtering With a Proxy, Firewall Rules, and an Always-On VPN

Device-level parental controls — Screen Time, Family Link, router DNS filtering — share a common architectural weakness: they can all be bypassed by routing traffic around the enforcement point. This guide covers a network-level approach that closes those gaps technically.

CacheGuard Parental Controls

Why DNS-based filtering fails first

Most home router parental controls work at the DNS layer. The router intercepts DNS queries and returns NXDOMAIN or a block page IP for blacklisted domains. The bypass is trivial:

# Child changes DNS on their device
networksetup -setdnsservers Wi-Fi 8.8.8.8    # macOS
# or simply sets 1.1.1.1 in Android/iOS network settings
Enter fullscreen mode Exit fullscreen mode

No DNS query hits the router. The filter never sees the request. DNS filtering provides zero protection against a user who controls their own DNS resolver.

The proxy interception model

A forward proxy operating at the HTTP application layer is bypass-resistant by a different mechanism. Traffic must physically pass through the proxy to reach the internet — there is no DNS-level workaround because the proxy intercepts at Layer 7, not Layer 3.

In explicit proxy mode, client devices are configured to send all HTTP and HTTPS requests to the proxy. HTTPS connections use the HTTP CONNECT method:

CONNECT www.example.com:443 HTTP/1.1
Host: www.example.com:443
Enter fullscreen mode Exit fullscreen mode

The proxy sees the full destination URL in plaintext before any TLS handshake — enabling URL category filtering on HTTPS traffic without SSL decryption. If the destination matches a blocked category, the proxy returns:

HTTP/1.1 403 Forbidden
Enter fullscreen mode Exit fullscreen mode

No content is delivered. No TLS session is established.

Making the proxy mandatory with a firewall rule

Explicit proxy mode relies on client configuration — and a determined child can simply remove the proxy settings from their device. The fix is a firewall rule that makes bypassing the proxy impossible:

# Block all outbound HTTPS traffic that does NOT originate from the proxy process
# On the gateway, assuming proxy runs as user 'proxy' (UID 13 on Debian)
iptables -t nat -A OUTPUT -p tcp --dport 443 -m owner ! --uid-owner 13 -j REDIRECT --to-port 3128
iptables -A FORWARD -p tcp --dport 443 -j DROP
Enter fullscreen mode Exit fullscreen mode

The second rule drops any HTTPS traffic forwarded from internal clients that attempts to bypass the proxy. The client gets a connection timeout. The only path to port 443 on the internet is through the proxy — which applies the content filter.

With Squid as the proxy engine, transparent interception for HTTP is straightforward:

# Redirect internal HTTP traffic to Squid transparent port
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 3128
Enter fullscreen mode Exit fullscreen mode

For HTTPS in transparent mode, SNI-based filtering is possible but limited to hostname-level blocking. For full URL-path filtering on HTTPS, explicit mode with the CONNECT method is required.

Blocking anonymizer and redirector categories

Web-based proxy and anonymizer services — sites that let users route traffic through external servers — bypass local filtering regardless of proxy enforcement, because the destination URL appears to be a legitimate website.

The mitigation is category-based blocking. Most URL category databases include an anonymizer or proxy category. In Squid with SquidGuard:

# squidguard.conf
dest anonymizers {
    domainlist anonymizers/domains
    urllist anonymizers/urls
}

acl {
    default {
        pass !anonymizers all
        redirect http://gateway/blocked.html
    }
}
Enter fullscreen mode Exit fullscreen mode

This blocks access to known anonymizer domains before the child can use them to route around the content filter.

Extending filtering to mobile devices outside the home

Home gateway filtering only applies when devices are on the home network. When a child's smartphone switches to mobile data or a friend's hotspot, the gateway is bypassed entirely.

The solution is an IPsec VPN server on the home gateway. Client devices connect to the VPN using IKEv2 with the gateway's certificate, routing all traffic through the home network — and through the web proxy — regardless of the underlying connection.

StrongSwan server configuration (relevant excerpt):

conn parental-vpn
    keyexchange=ikev2
    left=%any
    leftid=@home.example.com
    leftcert=gateway-cert.pem
    leftsubnet=0.0.0.0/0      # Route all client traffic through gateway
    right=%any
    rightsourceip=10.9.0.0/24  # Virtual IPs for VPN clients
    rightdns=10.9.0.1
    ike=aes256-sha256-ecp256!
    esp=aes256-sha256!
    auto=add
Enter fullscreen mode Exit fullscreen mode

The leftsubnet=0.0.0.0/0 directive routes all client internet traffic through the VPN tunnel — not just traffic destined for the home network. Once the VPN client connects, all outbound traffic hits the gateway proxy and is filtered identically to home network traffic.

Enforcing always-on VPN on client devices:

On iOS, a configuration profile with OnDemandEnabled=1 and OnDemandRules set to activate on any network connection enforces the VPN without user interaction. The profile can be locked via Mobile Device Management or restricted using Screen Time's VPN settings control.

On Android, Settings → Network → VPN → [profile] → Always-on VPN with Block connections without VPN enabled drops all traffic if the VPN is not active — no internet access without the tunnel.

URL blacklist management

The content filter requires a category database mapping URLs to content categories. Options range from free community-maintained lists to commercially updated subscription databases.

For a home deployment, the choice matters primarily on two dimensions: coverage (how many URLs are categorized, particularly for adult content) and update frequency (how quickly newly registered adult/malicious domains are added).

Free lists are adequate for blocking well-established categories but lag significantly on newly registered domains — a common technique used to evade filters. A subscription database with daily or hourly updates provides meaningfully better coverage for the adult content category specifically.

CacheGuard as a complete implementation

CacheGuard is a free, open-source network security appliance (LFS-based Linux) that ships all of the above pre-integrated:

  • Squid-based web proxy with URL filtering (explicit and transparent modes)
  • IPsec VPN server (StrongSwan, IKEv2) with client profile generation for iOS, macOS, Android, Windows, Linux
  • Zone-based stateful firewall with built-in rules for mandatory proxy enforcement
  • SSL mediation (Squid ssl-bump) for full HTTPS content inspection
  • Optional URL blacklist subscription with regularly updated category databases
  • Browser-based management interface — no CLI required for standard configuration

It installs from a single ISO on any x86 machine or VM. The firewall rules enforcing mandatory proxy use and blocking direct HTTPS forwarding are configurable through the web interface without writing iptables commands manually.

For parents who are comfortable with basic network concepts but do not want to assemble Squid, StrongSwan, iptables, and a PKI from scratch, it eliminates the integration overhead while remaining fully open source and free.

https://www.cacheguard.com/parental-controls-home-network/


Originally published on the CacheGuard Blog. CacheGuard is free and open source — GitHub.

Top comments (0)