Secure your children Internet access

I’m a big fan of PiHole for my children but also for my IoT devices [not the one I build but the one I’m purchasing 🙂 ]. That said, there are two things missing in it:

  • The first one is that Pi-Hole is operating on DNS request so any malicious solution using its own DNS or direct IP will bypass Pi-Hole protection.
  • The second one is the lake of functionalities like stopping Internet for a certain group of user during certain period of time.

So, when a friend of me contacted me to share its work on a different solution using a proxy, I’ve been happy to let him make a blog post here to introduce his solution. And this solution can be used in complement of PiHole. So, let’s make some place here to Manu PILLANT

Purpose

I have 3 kids. Yes so much happiness ! But the oldest ones are teenagers and that’s also the age when internet becomes exciting for them, but also dangerous.
I want to allow them to go freely on the internet, but I want to be able to check what they see, and I want a filter to block nasty pages.
Why don’t I use parental control systems ? Because they are too restrictive. But it is another debate.

The system here consists in having a proxy to provide internet for my kids. I named this proxy “octopus”. This page will explain in details how to configure it.

Material & principles

The diagram of the system is the following:

  • Internet access is provided through a freebox in a local network 192.168.0.x,
    • All workstations connected to this network have direct and uncontrolled access to the web,
  • Octopus is a Linux computer running under Debian 10,
    • wlp3s0 is a WiFi interface that I use to connect to my freebox,
    • enp0s18 is an Ethernet interface connected to the WiFi router,
  • The WiFi router is the “TP-Link Router WiFi AC 1200”.

Note that “Free” is a French Internet provider. And the freebox is the Internet gateway provided by “Free”

Note that I chose the WiFi router to amplify the WiFi signal. This router is not mandatory at all: you could remove it from the schema and configure octopus directly as access point.
The truth is that in this schema, your could choose to replace network interfaces by any other kind of interface (wired network for instance).

Kids devices connect to WiFi router to access Internet. This router automatically forwards packets from LAN1 to Octopus and the way around.
The first step for those devices is to get an IP address. So I installed a DHCP server on Octopus. Its role is to provide IP address to each device.
On Octopus is also installed a proxy. This proxy is named squid (http://www.squid-cache.org/) and is associated with e2guardian (https://github.com/e2guardian/e2guardian/wiki). Squid is the base proxy while e2guardian is a web content filter. We’ll see below the way they communicate with each other.

e2guardian is the one that receives internet requests coming from LAN1. After applying its internal filters, it forwards packets to squid that manages connections with internet.
We basically have two ways to use a proxy:

  • you configure your device with a proxy IP/port. This configuration must be done at device level,
  • you configure your gateway (in my case Octopus) to forward all packets to your proxy.

The second approach is called “transparent proxy” and this is the one I have chosen. No it’s not because I’m too lazy to configure each device !
But when I performed testings, I realized that some applications just ignore proxy settings…

This data forwarding is assumed by iptables (http://www.netfilter.org/) which is a very powerful firewall/NAT. We will configure it to forward internet packets to e2guardian.

As I said, the main purpose of this configuration is to filter internet content. But I also want to allow my kids to use some applications like Whatsapp. We’ll use iptables for that too.

Configuration

Internet box provider

To simplify the setup below I configured Octopus with static DHCP lease on LAN0. That means that octopus workstation will always have the same IP address on LAN0: 192.168.0.10.

Wifi router

This router is configured very simply:

  • Operation Mode is configured as “Access Point”,
  • Lan Settings is “Smart IP(DHCP)”

Smart IP(DHCP) means that the router will get an IP address from Octopus DHCP, and will route all packets from LAN1 to octopus.

Octopus

This is a computer with Debian 10 buster installed.
Here is the list of packages installed with the associated version:

  • e2guardian 5.3.1-1,
  • squid 4.6-1+deb10u4,
  • isc-dhcp-server 4.4.1-2

Network configuration

As I said previously, the network configuration on LAN0 side is simple since I get the IP address 192.168.0.10 provided by my internet box. But on LAN1 I have to configure the IP address. I’ll just get the first one: 192.168.1.1.
This configuration is simply done in /etc/network/interfaces as follow:

auto enp0s18
iface enp0s18 inet static
address 192.168.1.1
netmask 255.255.255.0

DHCP

The first role of Octopus is to provide IP addresses for LAN1. This is done by installing and configuring a DHCP server on octopus.
DHCP server package is isc-dhcp-server.
We first configure the network interface the DHCP server must work with. This is done in file /etc/default/isc-dhcp-server with parameter “INTERFACESv4”:

INTERFACESv4="enp0s18"

Then we configure the DHCP in file /etc/dhcp/dhcpd.conf as follow:

# The name of my domain
option domain-name "octopus.org";
# DNS server (I simply took the one of google)
option domain-name-servers 8.8.8.8;
# The main gateway on LAN1
option routers 192.168.1.1;

# The subnet for address distribution and associated range
subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.40 192.168.1.50;
}

In this configuration, the main gateway is defined to 192.168.1.1. This way every device connected to LAN1 knows that accessing the rest of the world shall be done through octopus.

squid

My squid configuration is almost unchanged comparing to the initial configuration file. I’ve just added the line “http_access allow localnet” to allow the access from local network.
Here is the content of my squid configuration file /etc/squid/squid.conf:

acl localnet src 0.0.0.1-0.255.255.255	
acl localnet src 10.0.0.0/8
acl localnet src 100.64.0.0/10		
acl localnet src 169.254.0.0/16 	
acl localnet src 172.16.0.0/12		
acl localnet src 192.168.0.0/16	
acl localnet src fc00::/7
acl localnet src fe80::/10 
acl SSL_ports port 443
acl Safe_ports port 80	
acl Safe_ports port 21	
acl Safe_ports port 443	
acl Safe_ports port 70	
acl Safe_ports port 210	
acl Safe_ports port 1025-65535
acl Safe_ports port 280	
acl Safe_ports port 488	
acl Safe_ports port 591	
acl Safe_ports port 777
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
include /etc/squid/conf.d/*
http_access allow localhost
http_access allow localnet
http_access deny all
http_port 3128
coredump_dir /var/spool/squid
refresh_pattern ^ftp:		1440	20%	10080
refresh_pattern ^gopher:	1440	0%	1440
refresh_pattern -i (/cgi-bin/|\?) 0	0%	0
refresh_pattern .		0	20%	4320

e2guardian

Basic configuration

To configure e2guardian you can have multiple configuration files, but at least two:

  • /etc/e2guardian/e2guardian.conf for the global configuration
  • /etc/e2guardian/e2guardianf1.conf for the first filter group.

You guess it: you can have more than one filter group (e2guardianf2, e2guardianf3, …).
In my case I’ve used the first one only.
Here is the list of parameters I’ve updated in /etc/e2guardian/e2guardian.conf:

language = 'french' # Yes I'm a froggy :)
proxyip = 127.0.0.1 # This is the IP of squid: we'll use loopback network interface to connect  e2guardian to squid.
proxyport = 3128 # See squid configuration above, this is the port listening to external requests

So far I’ve changed nothing into e2guardianf1.conf.
Note that the e2guardian ports configuration is done with the two following parameters:

filterports = 8080 # port for http connexions
transparenthttpsport = 8443 # port for https connexions
Logs

e2guardian logs are located into /var/log/e2guardian/.

Blacklists

In addition with e2guardian you need blacklists ! That is to say, the lists with internet content you want to filter.
You can do it yourself, you can ! But it will take you plenty of hours…you should download lists provided on this website:
https://www.shallalist.de/
You just have to copy files into /etc/e2guardian/lists/blacklists/ and that’s done !

MITM (Man In The Middle)

Due to end-to-end SSL encryption, https connections cannot be decrypted. Unless you use MITM hack!
In our case, the man in the middle is e2guardian and we want him to read the full content of internet pages (so it can filter it).
We will then generate our own certificate (on octopus) and provide it to LAN1 clients so they will blindly trust octopus as “certificate authority”.
The tutorial here https://github.com/e2guardian/e2guardian/wiki/MITM—Filtering-HTTPS describes precisely how to configure this MITM for e2guardian.
To install the certificate under Windows 10, proceed as following:

  • copy the CRT file on the windows 10 device
  • open it and click on “install a certificate”
  • it is important to install it as “root certification authority”,
  • restart your browser.

Iptables

Thanks to Iptables we will have a transparent proxy!
To use ip forwarding in iptables, you have to enable the following option into /etc/sysctl.conf:

net.ipv4.ip_forward=1

Once done, apply modifications:

sudo sysctl -p

The two scripts below have been copied (and largely inspired) from the excellent page at the following URL: https://lea-linux.org/documentations/Iptables (french).
The first script cleans up the iptables configuration whilst the second one applies the correct settings. I’ve detailed precisely so you can understand what is done here.

Note that I saved myself these scripts into /etc/iptables/, this directory does not exist in debian 10.

/etc/iptables/flushIptables.sh:

#!/bin/sh
#
# This script clean all iptables rules
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT

iptables -F
iptables -t nat -F

iptables -X
iptables -t nat -X

echo " [done]" 

/etc/iptables/transparent-proxy.sh:

#!/bin/sh
# The following commands defines logs associated to DROP or ACCEPT rules
# limits added to avoid too much logs
iptables -N LOG_DROP
iptables -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : ' -m limit --limit 1/min
iptables -A LOG_DROP -j DROP

iptables -N LOG_ACCEPT
iptables -A LOG_ACCEPT -j LOG --log-prefix '[IPTABLES ACCEPT] : '
iptables -A LOG_ACCEPT -j ACCEPT

iptables -N LOG_ACCEPT_WHATSAPP
iptables -A LOG_ACCEPT_WHATSAPP -j LOG --log-prefix '[IPTABLES WHATSAPP] : ' -m limit --limit 1/min
iptables -A LOG_ACCEPT_WHATSAPP -j ACCEPT

# By default everything is refused
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

# Everything is allowed on loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Everything coming from LAN1 is allowed on port 80 (HTTP) and redirected to e2guardian (that listens to
# HTTP connections from port 8080, see option "filterports" into e2guardian.conf)
iptables -A INPUT -i enp0s18 -p tcp --sport 80 -j ACCEPT 
iptables -t nat -A PREROUTING -i enp0s18 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.1:8080

# Everything coming from LAN1 is allowed on port 443 (HTTPS) and redirected to e2guardian (that listens to
# HTTP connections from port 8443, see option "transparenthttpsport" into e2guardian.conf)
iptables -A INPUT -i enp0s18 -p tcp --sport 443 -j ACCEPT 
iptables -t nat -A PREROUTING -i enp0s18 -p tcp --dport 443 -j DNAT --to-destination 192.168.1.1:8443

# Accept SSH to this workstation
iptables -A INPUT -i wlp3s0 -s 192.168.0.0/24 -p tcp --dport 22 -j ACCEPT

# Allow connections to e2guardian
iptables -A INPUT -i enp0s18 -p tcp --dport 8080 -j ACCEPT
iptables -A OUTPUT -o enp0s18 -p tcp --sport 8080 -j ACCEPT
iptables -A INPUT -i enp0s18 -p tcp --dport 8443 -j ACCEPT
iptables -A OUTPUT -o enp0s18 -p tcp --sport 8443 -j ACCEPT

# Allow this workstation to freely access internet
iptables -A OUTPUT -s 192.168.0.10 -o wlp3s0 -j ACCEPT
iptables -A INPUT -d 192.168.0.10 -i wlp3s0 -j ACCEPT

# Bellow are listed protocols we decide to allow between LAN1 computers and internet.
# Accept whatsapp with log
iptables -A FORWARD -i enp0s18 -p tcp --dport 5222 -o wlp3s0 -j LOG_ACCEPT_WHATSAPP
# Accept SSH
iptables -A FORWARD -i enp0s18 -p tcp --dport 22 -o wlp3s0 -j ACCEPT
# Accept DNS requests
iptables -A FORWARD -i enp0s18 -p udp --dport 53 -o wlp3s0 -j ACCEPT
iptables -A FORWARD -i enp0s18 -p tcp --dport 53 -o wlp3s0 -j ACCEPT

# Forward streams from internet to LAN1
iptables -A FORWARD -o enp0s18 -i wlp3s0 -j ACCEPT
# Forward of nat must be done with masquerade
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE
# Everything else is refused and logged
iptables -A FORWARD -j LOG_DROP
iptables -A INPUT -j LOG_DROP
iptables -A OUTPUT -j LOG_DROP
echo " [done]" 

As you can see I redirect Whatsapp connections directly to internet. That means that the content is not checked, I just know (with logs) that one of the device of LAN1 is using Whatsapp.

We want these scripts to be launched at the startup of the system. This is simply done with systemd by adding the following file:

/etc/systemd/system/octopus.service

[Unit]
Description=Octopus iptables settings
After=network.target

[Service]
Type=simple
Restart=no
ExecStartPre=/etc/iptables/flushIptables.sh
ExecStart=/etc/iptables/transparent-proxy.sh

[Install]
WantedBy=multi-user.target

Do not forget to enable it in systemd:

systemctl enable octopus.service
Iptables logs

Configuring iptables logs is very helpful, in particular during debugging sessions of the scripts above.
To redirect all iptables logs into a dedicated file, create the following file: /etc/rsyslog.d/iptables.conf

:msg,contains,"IPTABLES" /var/log/iptables.log & stop

Meaning that every log containing the string “IPTABLES” is written into /var/log/iptables.log.

Restart rsyslog:

systemctl restart rsyslog

That’s all folks! I hope that you won’t struggle too much. To be honest I spent hours on it. But I learned so much things about proxies, NAT, and so on…it’s worth it ! Be patient and persistent. Good luck.

Thanks

The first thank is for my friend Fil that led me to e2guardian. Many thanks to all authors of websites I consulted to setup octopus (some of them are in the text).
And a special thank to disk91 (an old friend !) that accepted to host this article on his website.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.