no entry

pfSense Webfilter – squidGuard für HTTP(S)-Verbindungen

Als Systemadministrator einer Schule steht man immer wieder vor der Frage, inwieweit man Inhalte aus dem Internet filtern soll. Überall da, wo Kinder und Jugendliche Zugriff zum Internet haben, egal ob in der Schule, im Verein, Bibliotheken, zu Hause oder einer anderen öffentlichen Einrichtung, muss diese Frage beantwortet werden. Die Meinungen zu diesem Thema sind sehr vielfältig. Einen 100%igen Schutz gibt es nicht. Viel wichtiger ist es, Kinder und Jugendlichen einen verantwortungsvollem Umgang mit dem Internet beizubringen. Das ist eine sehr große Herausforderung und dauert seine Zeit. Eltern und Pädagogen stehen vor dieser Aufgabe und wissen oft nicht, wie man es am besten angeht. Gerade in Schulen, wo man die Bildschirme nicht immer im Blick behalten kann, ist ein Webfilter eine große Hilfe. In manchen Ländern ist ein Webfilter für Schulen sogar gesetzlich vorgeschrieben. Manchmal geht es aber auch nur darum bestimmte Webseiten, wie Facebook, Netflix & Co zu sperren. Deshalb möchte ich in diesem Tutorial zeigen, wie man einen pfSense Webfilter einrichten kann.

Vorbemerkungen

pfSense ist eine weit verbreitete Open Source Firewall, die wir an unserer Schule einsetzen. Mit Hilfe von Squid (einem Proxy Server) und SquidGuard (dem eigentlichem Webfilter) wollen wir sowohl HTTP als HTTPS – Verbindungen filtern. Für dieses Tutorial brauchen wir zuerst eine aktive pfSense Installation. Die Firewall kann man hier herunterladen und nach dieser Anleitung installieren.

Funktionsweise

HTTP-Verbindungen zu filtern ist sehr einfach und auch schnell eingerichtet. Da diese Verbindungen unverschlüsselt sind, kann man sie gut untersuchen und deshalb ganz oder teilweise sperren. Heutzutage verwenden immer mehr Seiten (auch solche, die man gern sperren möchte) HTTPS, d.h. eine verschlüsselte Verbindung zwischen dem Browser des Benutzers und dem Webserver. Dank Let’s Encrypt kann heute jeder ein kostenloses Zertifikat für seine Website einrichten. Das ist an sich eine gute Sache, weil es die Sicherheit erhöht und viele Attacken unmöglich macht bzw. schwieriger. Es erschwert aber auch das Filtern nach unerwünschten Inhalten.

Diese „Problem“ lässt sich auf zwei Wegen lösen:

1. Man-in-the-Middle Angriff

Ein Weg ist ein bewusster Man-in-the-middle Angriff. Der Proxy-Server entschlüsselt dabei die HTTPS-Verbindung und baut sie neu auf. Dadurch kann er sich die Verbindung anschauen und entsprechend filtern. Dieses Konzept wird von den meisten Anbietern von Filterlösungen angewendet. Das Problem hierbei ist, dass durch diesen tiefen Eingriff in die HTTPS-Verbindung, die eigentliche Sicherheit durch HTTPS nicht mehr gegeben ist. Ein Benutzer kann den Unterschied kaum erkennen, wenn dem Zertifikat des Proxy-Servers vertraut wird. Doch diese Sicherheit ist trügerisch. Auch wenn man nur über diesen Weg von einer echten Inhaltsfilterung sprechen kann, so ist diese Lösung gefährlich, sehr risikobehaftet (die Implementation ist nicht trival) und je nach Land, nicht mit den vorherrschenden Gesetzen vereinbar (Stichwort Datenschutz). Deshalb ist dieser Weg aus sicherheitstechnischen und auch moralischen Gründen nicht zu empfehlen.

2. URL-Filter über SNI

Eine weitere Möglichkeit ist die Filterung über SNI (Server Name Indication). Bevor das Zertifikat zwischen Browser und Webserver abgefragt und somit einen verschlüsselte Verbindung aufgebaut wird, sendet der Browser den Domain Namen (FQDN) mit, den er abfragen möchte. Dieser Teil ist nicht noch nicht verschlüsselt und kann deshalb von einem (transparentem) Proxy gelesen und für die Filterung genutzt werden. Folgende Abbildung macht den TLS-Handshake deutlicher.

TLS Handshake

Man kann gut erkennen, dass der SNI vor dem Schlüsselaustausch und der eigentlichen sicheren Verbindung gesendet wird. Dieses Prinzip machen wir uns zunutze und können neben dem Webfilter für HTTP-Verbindungen auch einen URL-Filter für HTTPS-Verbindungen einrichten, ohne dabei HTTPS durch einen Man-in-the-Middle Angriff kaputt zu machen.

Safe-Search für Suchmaschienen

Firewall Regeln für DNS erstellen

Da wir nicht in eine HTTPS-Verbindung hinein schauen können, können z.B. in einer Google-Suche unerwünschte Bilder und Videos auftauchen. Google und auch andere Suchmaschinen bieten deshalb einen sicheren Modus (Safe-Search) an, denn wir erzwingen wollen.

Zuerst müssen wir dazu den DNS-Resolver in pfSense aktivieren (unter Services → DNS Resolver) und danach Speichern (Save) und die Änderungen übernehmen (Apply).

DNS Resolver

Damit später die Rechner im Netzwerk auch den DNS-Server der Firewall verwenden, brauchen wir eine Regel, welche alle anderen DNS-Anfragen an die Firewall weiterleitet. Dazu erstellen wir eine neue Regel unter Firewall → NAT im Reiter Port Forward mit einem Klick auf einen der beiden Add Buttons. Dabei geben wir folgendes ein:

  1. Interface: LAN
  2. Protocol: TCP/UDP
  3. Destination: Any
  4. Destination Port Range: DNS (53)
  5. Redirect Traget IP: 127.0.0.1
  6. Redirect Target Port: DNS (53)
  7. Description: Kann frei gewählt werden

NAT DNS Redirect

Nun müssen wir sicher stellen, dass unsere eben erstellte Firewall-Regel an der richtigen Stelle ist. Sie muss über der standardmäßigen „Default allow LAN to any rule“ sein! Dazu öffnen wir die Firewall Regeln unter Firewall → Rules und verschieben die Regeln nach oben. Danach mit Save speichern und mit Apply die Änderungen übernehmen.

LAN Rules

Host Overrides für Bing und Youtube

Als nächstes erstellen wir einige DNS-Einträge, die dafür sorgen, dass sowohl für Google und Bing deren Safe-Search verwendet wird. Dazu öffnen wir erneut den DNS-Resolver unter Services → DNS-Resolver und fügen unten im Abschnitt „Host Overrides“ mit Add folgende Einträge hinzu.

Bing:

  • Host: www
  • Domain: bing.com
  • IP Address: 204.79.197.220
  • Description: Bing
  • Dann mit Save speichern

Dann noch der Eintrag für Youtube:

  • Host: www
  • Domain: youtube.com
  • IP Address: 216.239.38.120
  • Description: Youtube
  • Wieder mit Save speichern

Host Override

Nun die Änderungen wieder mit Apply übernehmen.

Host Overrides für Google

Google verwendet sehr viele verschiedene Domains und es würde ziemlich lang dauern, diese von Hand einzugeben. Deshalb wählen wir für Google einen anderen Weg. Zuerst müssen wir uns per SSH in pfSense anmelden (oder einen Bildschirm + Tastatur anschließen, falls der pfSense auf einem Computer mit Grafikkarte installiert ist). Vorher muss SSH noch im Webinterface und System → Advanced im Abschnitt Secure Shell aktiviert werden.

pfSense SSH

Nun können wir uns mit folgendem Befehl per SSH anmelden (IP Adresse anpassen!):

$ ssh admin@192.168.0.1

Im folgenden Menü wählen wir „8“ (Shell).

pfSense Shell

Nun legen wir eine Datei an, in die wir später unsere DNS Einträge für Google eintragen. Das können wir mit folgendem Befehl machen:

$ vi /var/unbound/google.conf

Um den Editor wieder zu verlassen, müssen wir :wq eingeben (der Doppelpunkt ist wichtig!). Mehr brauchen wir nicht auf der Kommandozeile machen.

Wir können nun die eben angelegte Datei über Diagnostics → Edit File bearbeiten. Dazu geben wir den Pfad /var/unbound/google.conf ein und drücken dann auf Load.

Edit File

Nun kopieren wir folgenden Inhalt in die Datei:

local-data: "www.google.ad A 216.239.38.120"
local-data: "www.google.ae A 216.239.38.120"
local-data: "www.google.com A 216.239.38.120"
local-data: "www.google.com.af A 216.239.38.120"
local-data: "www.google.com.ag A 216.239.38.120"
local-data: "www.google.com.ai A 216.239.38.120"
local-data: "www.google.al A 216.239.38.120"
local-data: "www.google.am A 216.239.38.120"
local-data: "www.google.co.ao A 216.239.38.120"
local-data: "www.google.com.ar A 216.239.38.120"
local-data: "www.google.as A 216.239.38.120"
local-data: "www.google.at A 216.239.38.120"
local-data: "www.google.com.au A 216.239.38.120"
local-data: "www.google.az A 216.239.38.120"
local-data: "www.google.ba A 216.239.38.120"
local-data: "www.google.com.bd A 216.239.38.120"
local-data: "www.google.be A 216.239.38.120"
local-data: "www.google.bf A 216.239.38.120"
local-data: "www.google.bg A 216.239.38.120"
local-data: "www.google.com.bh A 216.239.38.120"
local-data: "www.google.bi A 216.239.38.120"
local-data: "www.google.bj A 216.239.38.120"
local-data: "www.google.com.bn A 216.239.38.120"
local-data: "www.google.com.bo A 216.239.38.120"
local-data: "www.google.com.br A 216.239.38.120"
local-data: "www.google.bs A 216.239.38.120"
local-data: "www.google.bt A 216.239.38.120"
local-data: "www.google.co.bw A 216.239.38.120"
local-data: "www.google.by A 216.239.38.120"
local-data: "www.google.com.bz A 216.239.38.120"
local-data: "www.google.ca A 216.239.38.120"
local-data: "www.google.cd A 216.239.38.120"
local-data: "www.google.cf A 216.239.38.120"
local-data: "www.google.cg A 216.239.38.120"
local-data: "www.google.ch A 216.239.38.120"
local-data: "www.google.ci A 216.239.38.120"
local-data: "www.google.co.ck A 216.239.38.120"
local-data: "www.google.cl A 216.239.38.120"
local-data: "www.google.cm A 216.239.38.120"
local-data: "www.google.cn A 216.239.38.120"
local-data: "www.google.com.co A 216.239.38.120"
local-data: "www.google.co.cr A 216.239.38.120"
local-data: "www.google.com.cu A 216.239.38.120"
local-data: "www.google.cv A 216.239.38.120"
local-data: "www.google.com.cy A 216.239.38.120"
local-data: "www.google.cz A 216.239.38.120"
local-data: "www.google.de A 216.239.38.120"
local-data: "www.google.dj A 216.239.38.120"
local-data: "www.google.dk A 216.239.38.120"
local-data: "www.google.dm A 216.239.38.120"
local-data: "www.google.com.do A 216.239.38.120"
local-data: "www.google.dz A 216.239.38.120"
local-data: "www.google.com.ec A 216.239.38.120"
local-data: "www.google.ee A 216.239.38.120"
local-data: "www.google.com.eg A 216.239.38.120"
local-data: "www.google.com.et A 216.239.38.120"
local-data: "www.google.fi A 216.239.38.120"
local-data: "www.google.com.fj A 216.239.38.120"
local-data: "www.google.fm A 216.239.38.120"
local-data: "www.google.fr A 216.239.38.120"
local-data: "www.google.ga A 216.239.38.120"
local-data: "www.google.ge A 216.239.38.120"
local-data: "www.google.gg A 216.239.38.120"
local-data: "www.google.com.gh A 216.239.38.120"
local-data: "www.google.com.gi A 216.239.38.120"
local-data: "www.google.gl A 216.239.38.120"
local-data: "www.google.gm A 216.239.38.120"
local-data: "www.google.gp A 216.239.38.120"
local-data: "www.google.gr A 216.239.38.120"
local-data: "www.google.com.gt A 216.239.38.120"
local-data: "www.google.gy A 216.239.38.120"
local-data: "www.google.com.hk A 216.239.38.120"
local-data: "www.google.hn A 216.239.38.120"
local-data: "www.google.hr A 216.239.38.120"
local-data: "www.google.ht A 216.239.38.120"
local-data: "www.google.hu A 216.239.38.120"
local-data: "www.google.co.id A 216.239.38.120"
local-data: "www.google.ie A 216.239.38.120"
local-data: "www.google.co.il A 216.239.38.120"
local-data: "www.google.im A 216.239.38.120"
local-data: "www.google.co.in A 216.239.38.120"
local-data: "www.google.iq A 216.239.38.120"
local-data: "www.google.is A 216.239.38.120"
local-data: "www.google.it A 216.239.38.120"
local-data: "www.google.je A 216.239.38.120"
local-data: "www.google.com.jm A 216.239.38.120"
local-data: "www.google.jo A 216.239.38.120"
local-data: "www.google.co.jp A 216.239.38.120"
local-data: "www.google.co.ke A 216.239.38.120"
local-data: "www.google.com.kh A 216.239.38.120"
local-data: "www.google.ki A 216.239.38.120"
local-data: "www.google.kg A 216.239.38.120"
local-data: "www.google.co.kr A 216.239.38.120"
local-data: "www.google.com.kw A 216.239.38.120"
local-data: "www.google.kz A 216.239.38.120"
local-data: "www.google.la A 216.239.38.120"
local-data: "www.google.com.lb A 216.239.38.120"
local-data: "www.google.li A 216.239.38.120"
local-data: "www.google.lk A 216.239.38.120"
local-data: "www.google.co.ls A 216.239.38.120"
local-data: "www.google.lt A 216.239.38.120"
local-data: "www.google.lu A 216.239.38.120"
local-data: "www.google.lv A 216.239.38.120"
local-data: "www.google.com.ly A 216.239.38.120"
local-data: "www.google.co.ma A 216.239.38.120"
local-data: "www.google.md A 216.239.38.120"
local-data: "www.google.me A 216.239.38.120"
local-data: "www.google.mg A 216.239.38.120"
local-data: "www.google.mk A 216.239.38.120"
local-data: "www.google.ml A 216.239.38.120"
local-data: "www.google.com.mm A 216.239.38.120"
local-data: "www.google.mn A 216.239.38.120"
local-data: "www.google.ms A 216.239.38.120"
local-data: "www.google.com.mt A 216.239.38.120"
local-data: "www.google.mu A 216.239.38.120"
local-data: "www.google.mv A 216.239.38.120"
local-data: "www.google.mw A 216.239.38.120"
local-data: "www.google.com.mx A 216.239.38.120"
local-data: "www.google.com.my A 216.239.38.120"
local-data: "www.google.co.mz A 216.239.38.120"
local-data: "www.google.com.na A 216.239.38.120"
local-data: "www.google.com.nf A 216.239.38.120"
local-data: "www.google.com.ng A 216.239.38.120"
local-data: "www.google.com.ni A 216.239.38.120"
local-data: "www.google.ne A 216.239.38.120"
local-data: "www.google.nl A 216.239.38.120"
local-data: "www.google.no A 216.239.38.120"
local-data: "www.google.com.np A 216.239.38.120"
local-data: "www.google.nr A 216.239.38.120"
local-data: "www.google.nu A 216.239.38.120"
local-data: "www.google.co.nz A 216.239.38.120"
local-data: "www.google.com.om A 216.239.38.120"
local-data: "www.google.com.pa A 216.239.38.120"
local-data: "www.google.com.pe A 216.239.38.120"
local-data: "www.google.com.pg A 216.239.38.120"
local-data: "www.google.com.ph A 216.239.38.120"
local-data: "www.google.com.pk A 216.239.38.120"
local-data: "www.google.pl A 216.239.38.120"
local-data: "www.google.pn A 216.239.38.120"
local-data: "www.google.com.pr A 216.239.38.120"
local-data: "www.google.ps A 216.239.38.120"
local-data: "www.google.pt A 216.239.38.120"
local-data: "www.google.com.py A 216.239.38.120"
local-data: "www.google.com.qa A 216.239.38.120"
local-data: "www.google.ro A 216.239.38.120"
local-data: "www.google.ru A 216.239.38.120"
local-data: "www.google.rw A 216.239.38.120"
local-data: "www.google.com.sa A 216.239.38.120"
local-data: "www.google.com.sb A 216.239.38.120"
local-data: "www.google.sc A 216.239.38.120"
local-data: "www.google.se A 216.239.38.120"
local-data: "www.google.com.sg A 216.239.38.120"
local-data: "www.google.sh A 216.239.38.120"
local-data: "www.google.si A 216.239.38.120"
local-data: "www.google.sk A 216.239.38.120"
local-data: "www.google.com.sl A 216.239.38.120"
local-data: "www.google.sn A 216.239.38.120"
local-data: "www.google.so A 216.239.38.120"
local-data: "www.google.sm A 216.239.38.120"
local-data: "www.google.sr A 216.239.38.120"
local-data: "www.google.st A 216.239.38.120"
local-data: "www.google.com.sv A 216.239.38.120"
local-data: "www.google.td A 216.239.38.120"
local-data: "www.google.tg A 216.239.38.120"
local-data: "www.google.co.th A 216.239.38.120"
local-data: "www.google.com.tj A 216.239.38.120"
local-data: "www.google.tk A 216.239.38.120"
local-data: "www.google.tl A 216.239.38.120"
local-data: "www.google.tm A 216.239.38.120"
local-data: "www.google.tn A 216.239.38.120"
local-data: "www.google.to A 216.239.38.120"
local-data: "www.google.com.tr A 216.239.38.120"
local-data: "www.google.tt A 216.239.38.120"
local-data: "www.google.com.tw A 216.239.38.120"
local-data: "www.google.co.tz A 216.239.38.120"
local-data: "www.google.com.ua A 216.239.38.120"
local-data: "www.google.co.ug A 216.239.38.120"
local-data: "www.google.co.uk A 216.239.38.120"
local-data: "www.google.com.uy A 216.239.38.120"
local-data: "www.google.co.uz A 216.239.38.120"
local-data: "www.google.com.vc A 216.239.38.120"
local-data: "www.google.co.ve A 216.239.38.120"
local-data: "www.google.vg A 216.239.38.120"
local-data: "www.google.co.vi A 216.239.38.120"
local-data: "www.google.com.vn A 216.239.38.120"
local-data: "www.google.vu A 216.239.38.120"
local-data: "www.google.ws A 216.239.38.120"
local-data: "www.google.rs A 216.239.38.120"
local-data: "www.google.co.za A 216.239.38.120"
local-data: "www.google.co.zm A 216.239.38.120"
local-data: "www.google.co.zw A 216.239.38.120"
local-data: "www.google.cat A 216.239.38.120"

Mit einem Klick auf Save speichern wir die Datei.

Der letzte Schritt ist, dass wir unserem DNS Server noch mitteilen müssen, wo er diese DNS-Einträge finden kann. Dazu öffnen wir wieder die Einstellungen des DNS Servers unter Services → DNS Resolver und klicken auf Display Custom Options. Dort fügen wir folgende Zeilen ein, speichern mit Save und übernehmen die Änderungen mit Apply.

server:
include: /var/unbound/google.conf

DNS Custom Options

Unsere Suchmaschinen sind konfiguriert. Im nächsten Schritt richten wir den Inhaltsfilter für HTTP und den URL-Filter für HTTPS ein.

Squid Proxy und SquidGuard

Installation

Damit pfSense die URLs filtern kann, brauchen wir einen Proxy-Server, durch den alle Anfragen aus unserem Netzwerk geleitet werden. Dazu verwenden wir Squid. SquidGuard ist, wie der Name schon vermuten lässt, der eigentliche Filter. Unter System → Package Manager im Reiter Available Packages installieren wir Squid und SquidGuard.

Package Manager

Transparenter Proxy für HTTP einrichten

Unter Services → Squid Proxy Server richten wir nun den transparenten Proxy für HTTP ein. Ein transparenter Proxy hat den Vorteil, dass wir keine Konfiguration an den einzelnen Rechner in unserem Netzwerk vornehmen müssen. Im Reiter General aktivieren wir folgende Punkte:

  1. Enable Squid Proxy ✔
  2. Proxy Interface(s): LAN
  3. Allow users on Interface ✔
  4. Transparent HTTP Proxy ✔
  5. Transparent Proxy Interface(s): LAN

Squid Proxy General

Nach dem Speichern mit Save legen wir im Reiter Local Cache fest, wie viel Festplattenplatz für den Cache verwendet werden soll (hier 500MB):

Squid Proxy Cache

Auch hier müssen die Einstellungen wieder mit Save gespeichert werden. Der Transparente Proxy für HTTP-Verbindungen ist jetzt fertig eingerichtet.

SquidGuard konfigurieren

SquidGuard ist die Komponente, die sich um die Filterung der Inhalte kümmert. Jede Anfrage wir von SquidGuard untersucht und dann entschieden, ob die Anfrage bzw. die Website geblockt werden soll oder nicht. Dazu verwenden wir eine Blacklist, die wir später konfigurieren. Davor legen wir ein paar allgemeine Einstellungen unter Services → SquidGuard Proxy Filter fest.

  1. Enable ✔ (nicht im Screenshot zu sehen)
  2. Enable Log  ✔
  3. Enable Log Rotation ✔
  4. Enable Blacklist ✔
  5. Blacklist URL: http://www.shallalist.de/Downloads/shallalist.tar.gz

Squid Proxy Filter General

Unten speichern wir wieder alles mit Save.

Beim SquidGuard müssen wir beachten, dass Änderungen in der Konfiguration erst dann aktiv werden, wenn wir Save und Apply (oben im Reiter General Settings) geklickt haben!

Black- und Whitelisten einrichten

Nachdem wir nun mit den grundlegenden Einstellungen fertig sind, fehlen noch die Black- und Whitelisten. Die URL für die Blackliste haben wir ja bereits angegeben. Nun müssen wir sie noch herunterladen im Reiter „Blacklist„.

Blacklist

Damit unser Filter auch funktioniert, legen wir nun einige Zielkategorien fest. Dazu öffnen wir den Reiter „Target Kategories“ und klicken auf Add. Wir erstellen eine Whitelist, in der alle Domainnamen kommen, die wir explizit erlauben. Das wären z.B. alle Google-Domain, da wir ja alle weiteren Suchmaschinen blocken werden, um dem Benutzer keine Möglichkeit zu geben, die weiter oben eingerichtet Safe-Search zu umgehen.

Folgendes geben wir ein:

  1. Name: Whitelist
  2. Domain List:
    google.ac google.ad google.ae google.al google.am google.as google.at google.az google.ba google.be google.bf google.bg google.bi google.bj google.bs google.bt google.by google.ca google.cat google.cd google.cf google.cg google.ch google.ci google.cl google.cm google.cn google.co.ao google.co.bw google.co.ck google.co.cr google.co.hu google.co.id google.co.il google.co.in google.co.je google.co.jp google.co.ke google.co.kr google.co.ls google.com google.co.ma google.com.af google.com.ag google.com.ai google.com.ar google.com.au google.com.bd google.com.bh google.com.bn google.com.bo google.com.br google.com.bz google.com.co google.com.cu google.com.cy google.com.do google.com.ec google.com.eg google.com.et google.com.fj google.com.gh google.com.gi google.com.gr google.com.gt google.com.hk google.com.jm google.com.kh google.com.kw google.com.lb google.com.ly google.com.mm google.com.mt google.com.mx google.com.my google.com.na google.com.nf google.com.ng google.com.ni google.com.np google.com.om google.com.pa google.com.pe google.com.pg google.com.ph google.com.pk google.com.pr google.com.py google.com.qa google.com.sa google.com.sb google.com.sg google.com.sl google.com.sv google.com.tj google.com.tr google.com.tw google.com.ua google.com.uy google.com.vc google.com.vn google.co.mz google.co.nz google.co.th google.co.tz google.co.ug google.co.uk google.co.uz google.co.ve google.co.vi google.co.za google.co.zm google.co.zw google.cv google.cz google.de google-directory.co.uk google.dj google.dk google.dm google.dz google.ee google.es google.fi google.fm google.fr google.ga google.ge google.gg google.gl google.gm google.gp google.gr google.gy google.hn google.hr google.ht google.hu google.ie google.im google.iq google.is google.it google.je google.jo google.kg google.ki google.kz google.la google.li google.lk google.lt google.lu google.lv google.md google.me google.mg google.mk google.ml google.mn google.ms google.mu google.mv google.mw google.ne google.nl google.no google.nr google.nu google.off.ai googlepirate.com google.pl google.pn google.ps google.pt google.ro google.rs google.ru google.rw google.sc google.se google.sh google.si google.sk google.sm google.sn google.so google.sr google.st google.td google.tg google.tk google.tl google.tm google.tn google.to google.tt google.uz google.vg google.vu google.ws bing.com
  3. Description: Whitelist
  4. Mit Save speichern.

Whitelist

Der vorerst letzte Schritt ist die Einrichtung einiger Regeln. Das machen wir im Reiter Common ACL. Dann bei „Target Rules List“ auf das „+“ – Zeichen klicken, um eine Liste mit den verschiedenen Regelsätzen zu öffnen. Hier gibt es nun verschiedene Kategorien und auch unsere Whitelist taucht hier auf. Folgende Einstellungen nehmen wir nun vor:

  • Whitelist: access whitelist
  • Default access [all]: access allow

Common ACL

Die anderen Kategorien können je nach Bedarf eingestellt werden. Hier einige Beispiele:

  • Werbung blocken: [blk_BL_adv] access deny
  • Pornographie blocken: [blk_BL_porn] access deny
  • usw.

Damit ein Benutzer unseren URL-Filter nicht durch die Eingabe der IP-Adresse einer Seite umgehen kann, aktivieren wir noch Do not allow IP-Addresses in URL. Falls diese Einstellung Probleme macht, sollte man sie wieder deaktivieren.

Do not allow IP Addresses

Dann speichern wir mit Save, wechseln in den Reiter General Settings und müssen dort noch einmal auf Apply drücken, damit unsere Änderungen auch angewendet werden.

Bisheriges Setup testen

Für HTTP-Verbindungen ist alles eingerichtet und wir können das Setup testen. Auf einem Rechner im LAN muss nichts weiter eingerichtet werden. Der Filter sollte bereits funktionieren. Falls wir eine Seite aufrufen, die in eine unserer Blacklisten auftaucht erscheint diese Seite:

Blocked Sites

Transparenter Proxy für HTTPS-Verbindungen

Bisher ist der transparente Proxy nur für HTTP, d.h. unverschlüsselte Anfragen aktiv.  Zu Beginn dieses Artikels habe ich bereits auf die Schwierigkeiten beim Filtern von verschlüsselten, also HTTPS-Verbindungen hingewiesen. In unserem Fall werden wir einen transparenten Proxy für HTTPS aktivieren, der es uns erlaubt einen URL-Filter für alle Anfragen auf Port 443 (HTTPS) zu aktivieren, allerdings mit dem Nachteil, dass wir nicht den Inhalt analysieren können (und auch nicht wollen!) sowie keine schöne Fehlerseite möglich ist. Stattdessen wird uns der Browser eine Zertifikatsfehlermeldung anzeigen. Doch dazu gleich mehr.

Wir aktivieren zuerst den transparenten Proxy auch für HTTPS. Dazu öffnen wir die Proxyeinstellungen unter Services → Squid Proxy Server und wählen im Abschnitt SSL Man in the Middle Filtering folgende Einstellungen:

  • HTTPS / SSL Interception ✔
  • SSL/MITM Method: Splice All
  • SSL Intercept Interfaces: LAN
  • CA: Ein Certificat Authority Zertifkat auswählen. Eventuell müssen wir erst noch eines erstellen. (Unter System → Cert. Manager).
  • Alles mit Save speichern.

SSL MITM

Nun ist wirklich alles eingerichtet und wir können auch HTTPS-Verbindungen testen. Wie bereits geschrieben, bekommen wir diesmal nicht so eine aussagekräftige Fehlermeldung wie für HTTP-Verbindungen, sondern eine Warnung des Browsers zu sehen:

Cert Error

Auch wenn diese Fehlermeldung nicht sehr aussagekräftig ist, haben wir unser eigentliches Ziel erreicht, nämlich das unerwünschte Seiten geblockt werden.

Fazit

Wir haben nun ein System eingerichtet, welches allen Netzwerkverkehr in unserem LAN (oder WLAN) filtert. Dabei werden Seiten, die über die Blacklisten festgelegt wurden, geblockt.

Über das Für und Wider von solchen Sperren gibt es unterschiedliche Positionen. Es ist auf jeden Fall ein Problem, welches sich technisch nicht zu 100% lösen lässt und auch nicht sollte, da es vielmehr darum geht, (junge) Menschen dahingehend zu erziehen, dass sie verantwortungsvoll mit dem Medium „Internet“ umgehen können. Dieses Ziel allein durch solche Filtermaßnahmen zu erreichen, ist sicher nicht der richtige Weg. Auch das man Kinder und Jugendliche an Zensur und Filter „gewöhnt“ wird von einigen kritisch gesehen.

Auf der anderen Seite ist es gerade für Schulen, Bibliotheken oder auch zu Hause eine Hilfe, wenn man die Fülle an nicht altersgemäßen Inhalten etwas einschränken kann. Manche Länder schreiben so einen Filter auch gesetzlich vor!

(Quelle: https://forum.pfsense.org/index.php?topic=112335.0)

14 Comments:

  1. Edi

    Hi,

    danke für diesen Artikel.
    Ich setze privat eine IpFire ein aber so ähnlich wird es da auch aussehen. Bisher habe ich den Web-Filter nicht aktiv.

    Funktioniert die konfigurierte Option der Https-Filterung über SNI (Punkt 2) oder MITM ?

    Safe-Search-Umleitung habe ich nicht verstanden.
    Bedeutet das, dass ein bestimmter Server (216.239.38.120) nur Safe-Search verarbeitet ?

    LG

  2. zefanja

    @Edi: Die Filterung geht über SNI, d.h. keine MITM der HTTPS-Verbindung. Die Abfrage der SNI erfolgt vor dem Aufbau der eigentlichen HTTPS Verbindung.

    Wegen Safe-Search: Genau, über diese IP wird Safe-Search forciert. Mit nslookup forcesafesearch.google.com kannst du IP in deiner Region herausfinden.

  3. Fidelu

    Hallo!

    Vielen Dank für diese ausführliche und hilfreiche Beschreibung. Ich war aufgrund der Fülle an Einstellmöglichkeiten von Squid bzw. SquidGuard zunächst etwas überfordert, aber im Grunde benötigt man für einfaches Black-/Whitelisting nur einen Bruchteil davon. Daher vielen Dank fürs Augenöffnen/Lichtinsdunkelbringen! 🙂

    PS: Ich beneide dich ein wenig um die Ferien. Wir sind gezwungen IT-Projekte im laufenden Betrieb und/oder an Feiertagen bzw. Sonntagen umzusetzen.

  4. Tim

    Moin,
    wie viele gleichzeitige clients laufen denn bei euch über die Firewall?

    Ich muss für unsere Schule auch eine neue suchen und tue mich aber mit der Auswahl der Hardware etwas schwer.

    Wir haben aktuell um die 25 Clients, in der Zukunft vielleicht um die 100.

    Meinst du eine SG-5100 von Netgate reicht aus?

    Darüber soll lediglich der Webfilter laufen, muss auch nicht als transparenter Proxy, da das ganze für eine Grundschule ist und es kein BYOD gibt.

    Vielen Dank für deinen Blog und deine Bemühungen.

  5. zefanja

    @Tim: Gleichzeitig haben wir zw. 20-50 Clients laufen. Wir sind keine große Schule. Wir haben der Ausstattung eine ähnliche Firewall wie die SG-5100. Von der Leistung sollte das mehr als ausreichen. Es hängt aber auch sehr davon ab, was du noch so vorhast (NIDS, DPI, …).

  6. zefanja

    Ja, es wird nicht leichter. Ohne MITM-Geschichten wird es kaum noch möglich sein. Bin gespannt wo die Reise hingeht. Auf der einen Seite begrüße ich die Entwicklungen, da sie den User schützen, auf der anderen Seite muss man als Schule in manchen Ländern Webfilter haben.

  7. Jan

    Ich behelfe mir nun folgendermaßen:
    Per DHCP bekommen erst mal alle Clients unseren (filternden) DNS-Server zugewiesen, was für die meisten Fälle ausreichen sollte. Die Ports 53 und 853 werden nicht nach draußen gelassen. Somit hat man aktuell wohl >95% der Clients reguliert.
    Sollte die Namensauflösung umgangen werden, spare ich mir den Weg mit (transparenten) Proxies und blockiere direkt eine größere Liste „verbotener“ FQDNs über Aliases in der Firewall.

    Das wichtigste bleibt ohnehin, dass alle Benutzer (nicht nur Schüler) vernünftigt unterrichtet werden, wie das Internet zu benutzen ist.
    Danke in jedem Fall für all die informativen Beiträge.

  8. Daniel

    Hallo

    An sich finde ich die Idee gut.
    Wir haben es jetzt einmal so versucht und leider hat es bei uns nicht funktioniert. Die Filterung lief zwar, dafür konnten sich aus unerklärlichen Gründen die Domänencontroller nicht mehr untereinander verständigen.
    Das Backup der Firewall hat leider auch nichts gebracht, so dass wir jetzt wieder die alten Zyxel anwerfen mussten.

  9. felsenstadt

    hallo danke für die Anleitung, ich habe die Pfsense genau nach der Beschreibung eingerichtet; bekomme jedoch bei jeder Webseite die letzte beschrieben Fehlermeldung.

  10. frank

    Die Blacklist und die URL Filterung greift sehr gut, auch bei https. Das aus 2 Gründen.
    1. Ein großer Teil der Server viele Domains abdecken, deshalb wird die Domain(Adresszeile) unverschlüsselt übermittelt, ansonsten wüßte der Server nicht, welches Zertifikat er anbieten soll.
    2. Der Benutzer gibt in die Adresszeile nicht expliziet https an, zunächst ist es http und wird dann vom Server auf https umgeleitet, das geht so schnell, dass der User das nicht wahrnimmt. Da hier dann schon bei http die Blackliste greift, kommt es gar nicht erst zur umleitung auf https.

  11. Auch in 2023 benutzen wir die hier vorgestellte Lösung zur Web Seitenfilterung.

    Ich frage mich allerdings, ob das heute noch eine richtige und gute Lösung in Verbindung mit pfSense ist?

Leave a Reply:

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert