Installation - alexium/internet-filter GitHub Wiki

Cabinet

You need a locked cabinet to hold the routers in order to prevent anyone from connecting a cable directly to your ISP's router and getting unfiltered internet access.

Router

This installation was tested on an Ubiquiti EdgeRouter ER-X running EdgeOS v2.0.6.

Policy Based Routing

Configure Policy Based Routing to route traffic to the Squid intercept proxy:

configure
set protocols static table 90 route 0.0.0.0/0 next-hop 192.168.1.254
set protocols static table 100 route 0.0.0.0/0 next-hop 192.168.3.11
set firewall modify SQUID rule 90 action modify
set firewall modify SQUID rule 90 description 'Redirect HTTP to squid'
set firewall modify SQUID rule 90 destination port 80
set firewall modify SQUID rule 90 modify table 100
set firewall modify SQUID rule 90 protocol tcp
set firewall modify SQUID rule 90 source address 192.168.2.1/24
set firewall modify SQUID rule 91 action modify
set firewall modify SQUID rule 91 description 'Redirect HTTPS to squid'
set firewall modify SQUID rule 91 destination port 443
set firewall modify SQUID rule 91 modify table 100
set firewall modify SQUID rule 91 protocol tcp
set firewall modify SQUID rule 91 source address 192.168.2.1/24
set interfaces switch switch0 firewall in modify SQUID
commit; save; exit

Portal

The Captive Portal installation was tested on a Raspberry Pi running Raspbian GNU/Linux 10 (buster).

Flask

sudo pip3 install flask-sqlalchemy flask-login pylint-flask
git clone https://github.com/alexium/internet-filter.git
cd internet-filter
FLASK_APP=portal
FLASK_ENV=development
flask init-db

Set up the production environment, to override Flask environment variables in portal/__init__.py:

$ cat instance/prod.cfg
SECRET_KEY = b'xxxxxx'
SQLALCHEMY_DATABASE_URI='sqlite:////home/pi/internet-filter/instance/prod.db'
SERVER_NAME='192.168.3.10'

Gunicorn

Install and test:

sudo adduser --group gunicorn
sudo adduser --no-create-home --disabled-login --ingroup gunicorn gunicorn
sudo pip3 install gunicorn
sudo chown -R gunicorn instance

Set up the production database:

python3
from portal import create_app
from portal.database import DB, User
from werkzeug.security import generate_password_hash
app=create_app()
app.app_context().push()
DB.create_all(app=app)
password=generate_password_hash('xxxx', method='sha256')
new_user = User(username='john', password=password)
DB.session.add(new_user)
DB.session.commit()
^D
sudo chown gunicorn instance/prod.db

Configure systemd so that Gunicorn runs automatically:

$ sudo cp conf/gunicorn.socket /etc/systemd/system/gunicorn.socket
$ sudo cp conf/gunicorn.service /etc/systemd/system/gunicorn.service

Start:

systemctl enable --now gunicorn.socket

Nginx

sudo apt-get install nginx
sudo cp conf/nginx.conf /etc/nginx/
sudo systemctl restart nginx
cd /var/www
sudo mkdir css
cd css
sudo wget https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css

Squid

The Squid installation was tested on a Raspberry Pi running Raspbian GNU/Linux 10 (buster).

Compiling

The default version of Squid on Raspbian supports default intercept mode but does not support bump or splice. I initially got the following error:

FATAL: Bungled /etc/squid/squid.conf line 1929: https_port 3129 ssl-bump

For bump or splice intercept mode, you need to compile Squid with the following options:

--enable-ssl \
--enable-ssl-crtd \
--with-openssl

You can run squid -v to determine whether your Squid was compiled with those options.

The normal Squid compile instructions did not work on a Raspberry Pi. Diladele provides instructions for compiling on the Raspberry Pi. I had to make some small modifications to get these instructions to work.

First, I had to install version 4.9-1. I could no longer find version 4.6 in the Debian repository. I could not get version 4.8 to compile on ARM. I think that this is expected per https://packages.debian.org/search?keywords=squid.

The architecture that I am running is armhf. I got the following error when trying to compile 4.9:

gpg: dpkg-sign.lPLeFf2v/squid_4.9-1_armhf.buildinfo: clear-sign failed: No secret key

I applied the fix in here and ran the following compile command:

dpkg-buildpackage -rfakeroot -b -uc -us

I removed the existing squid installation:

sudo apt-get remove squid

Then I installed following Diladele's installation instructions.

Install the squid.conf file:

sudo cp conf/squid.conf /etc/squid/squid.conf

The /etc/init.d/squid script that starts squid after a system reboot was in place, likely from the original install of squid using apt-get.

sudo /etc/init.d/squid start

Packet forwarding

Set up iptables on the Squid host to forward HTTP and HTTPS packets to Squid:

sudo /sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.3.11:3128 ! -d portal.ubnt.local
sudo /sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128 ! -d portal.ubnt.local
sudo /sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to 192.168.3.11:3129 ! -d portal.ubnt.local
sudo /sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 3129 ! -d portal.ubnt.local

Ensure that iptables settings survive a reboot:

$ sudo apt-get install iptables-persistent
$ sudo iptables-save > /etc/iptables/rules.v4

Clients

You do not need to do any client configuration if you are filtering at the DNS layer or if you are filtering at the network layer using a transparent proxy.

However, you may need to close some security loopholes on clients to ensure that they can only connect to your network. Otherwise they could get unfiltered internet access by connecting to other networks from their devices.

The only type of client with which I am familiar are Chromebooks.

Chromebooks

You cannot disable wireless on a Chromebook unless you have a Chrome Enterprise plan. If there are any open wireless networks around your home then your children can get unfiltered network access. If your child takes their Chromebook to a public space with an open wifi network then they can get unfiltered internet access.

Your children's Chromebooks may be managed by their school using a Chrome Enterprise plan. In this case, their school may have some options to prevent unfiltered internet access when off campus. You can talk to your school's network administrator to figure out options. They may be able to lock down network settings or configure their web filter when the student is off campus.