Internetfilter für Linux Workstations

Internetfilter für Linux Workstations

© Michael H.G. Schmidt (michael@schmidt2.de)

Bei uns zu Hause wird Linux(und manchmal auch Windows) eingesetzt. In unserer Familie hat jeder seinen eigenen Laptop. Als Router läuft eine Fritzbox. Die Fritzbox hat zwar eine „Kindersicherung“ aber diese begrenzt nur die zur Verfügung stehende Onlinezeit – Webseiten filtern kann man damit leider nicht. Nach einiger Zeit bin ich zu dem Schluss gekommen, daß es besser wäre, wenn der Content gefiltert wird. Für Windows habe ich dann K9 Webprotection gefunden.

„K9 Webprotection“ ist kostenlos für Privatanwender und funktioniert ganz gut (es tut das was es soll und ist zuverlässig). Leider gibt es keine Linux Version und es ist auch keine geplant. Für Familien gibt es (unter WIN7) zwar auch noch eine Lösung von M$, aber leider ist diese nicht besonders performant, da der M$ Filter scheinbar bei jeder(?) Anfrage des Browsers auch eine Anfrage in der Datenbank von M$ vornimmt.

Nach intensiver Suche stellte sich heraus, das es für Linux keine (kostenfreie) Lösung für Workstations/Desktops gibt. Mein erster Gedanke war einen Server zu installieren (z.B. mit IPcop). Ich entschied mich jedoch dagegen, da dies eine weitere Maschine wäre um die ich mich kümmern müsste – von Stromkosten, Lärmbelästigung und Platzbedarf mal ganz abgesehen.

Ich entschied mich dafür selbst eine Lösung zu basteln. Eine Kombination von SQUID,SQUIDguard & Ubuntu Linux 10.04 LTS (Desktop) schien mir geeignet das Problem zu lösen.

Der Plan

Squid wird auf Ubuntu gestartet und wird so eingestellt, dass der Dämon auf Port 3128(localhost) horcht und alle Anfragen des Browsers annehmen soll. Jede Anfrage von Squid wird dann wiederum durch SquidGuard geschickt. Der „schaut“ dann in seinen lokalen Datenbank nach, ob die entsprechende Seite freigegeben oder gesperrt ist. Im Falle der Sperrung wird eine „Access denied“ Seite zurückgegeben oder der Benutzer wird umgeleitet (ich entschied mich für eine Umleitung auf www.google.de). 1x pro Woche (oder 1x pro Monat) werden per Cronjob von der Fa. „Shalla Security Services“ die aktuellen Tabellen der jugendgefährdenden oder sonstigen als schädlich eingestuften Websites heruntergeladen und automatisch als neue Datenbank für SquidGuard im richtigen Verzeichnis installiert.

Nun war nur noch das Problem zu lösen wie man sicherstellt, daß der Browser bei jedem Connect den lokalen Proxy (squid) kontaktiert und nicht das Internet direkt!

  • Lösung 1: Der Browser (in meinem Fall Firefox) wird per Policies angewiesen einen Proxy zu benutzen. Dies hat jedoch mehrere Nachteile: Ein gut geskillter Benutzer kann dies evtl. umgehen und die Policies wieder ändern (dazu benötigt er noch nicht einmal root Rechte). Eine weitere Umgehungsmöglichkeit wäre die Installation eines alternativen Browsers (z.B. Chromium).
  • Lösung 2: Installation einer Firewall und Aktivierung einer Regel, die alle nach Port 80 ausgehenden Requests auf 127.0.0.1:3128 umleitet (=unser lokaler squid Proxy).

Ein genereller Nachteil der Lösung ist – nach jetzigem Stand -, daß alle https Requests (Port 443) nicht von Squid & SquidGuard gefiltert werden. Der Grund ist, daß bei einem https Connect (z.B. zur Hausbank des Benutzers) das Zertifikat der Bank nicht mehr sichtbar wäre. In diesem Fall kommuniziert nämlich der Proxy mit dem Webserver der Bank und man muss sich dann darauf verlassen, daß der Proxy eine Gültigkeitsprüfung des Zertifikats durchgeführt hat.

Im folgenden HOWTO wird Lösung 1 umgesetzt. Ein weiterer Beitrag zu Lösung 2 kommt evtl. in Kürze auf diesem Blog.

NOTE: Das folgende Howto wurde auf Ubuntu 10.04 LTS erstellt und getestet. Auf RHEL oder SLES oder anderen Linux Versionen muss man den einen oder den anderen Step natürlich in abgewandelter Form durchführen ;-).

Installation der Pakete

Shell öffnen und ausführen:

sudo apt-get install squid squid-common squid-langpack squidguard

Das wars. „Squid“ sollte jetzt bereits laufen. Prüfen kann man das mit:

ps -ef | grep -i "[s]quid$"

Ausgabe:

root      1568     1  0 Jan16 ?        00:00:00 /usr/sbin/squid

Konfiguration von SQUID

Zuerst sichern wir mal die Original Konfig vom Squid:

sudo mv /etc/squid/squid.conf /etc/squid/squid.conf.ORIG

Jetzt erzeugen wir mit folgendem Befehl eine neue Konfig:

sudo cat /etc/squid/squid.conf.ORIG | egrep -iv "^#|^$" >/etc/squid/squid.conf

HINWEIS: (Wem das zu kryptisch ist der kann auch gerne den „vi“ oder den „nano“ nehmen und die Datei von Hand mit „nano /etc/squid/squid.conf“ anlegen. Speichern nicht vergessen !)

Die neue Konfig sieht dann so aus:

acl all src all
acl manager proto cache_object
acl localhost src 127.0.0.1/32
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32
acl localnet src 10.0.0.0/8 # RFC1918 possible internal network
acl localnet src 172.16.0.0/12  # RFC1918 possible internal network
acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
acl SSL_ports port 443      # https
acl SSL_ports port 563      # snews
acl SSL_ports port 873      # rsync
acl Safe_ports port 80      # http
acl Safe_ports port 21      # ftp
acl Safe_ports port 443     # https
acl Safe_ports port 70      # gopher
acl Safe_ports port 210     # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280     # http-mgmt
acl Safe_ports port 488     # gss-http
acl Safe_ports port 591     # filemaker
acl Safe_ports port 777     # multiling http
acl Safe_ports port 631     # cups
acl Safe_ports port 873     # rsync
acl Safe_ports port 901     # SWAT
acl purge method PURGE
acl CONNECT method CONNECT
http_access allow manager localhost
http_access deny manager
http_access allow purge localhost
http_access deny purge
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost
http_access deny all
icp_access allow localnet
icp_access deny all
http_port 127.0.0.1:3128                                              #(1)
hierarchy_stoplist cgi-bin ?
access_log /var/log/squid/access.log squid
refresh_pattern ^ftp:       1440    20% 10080
refresh_pattern ^gopher:    1440    0%  1440
refresh_pattern -i (/cgi-bin/|\?) 0 0%  0
refresh_pattern (Release|Package(.gz)*)$    0   20% 2880
refresh_pattern .       0   20% 4320
acl shoutcast rep_header X-HTTP09-First-Line ^ICY.[0-9]
upgrade_http0.9 deny shoutcast
acl apache rep_header Server ^Apache
broken_vary_encoding allow apache
extension_methods REPORT MERGE MKACTIVITY CHECKOUT
hosts_file /etc/hosts
coredump_dir /var/spool/squid
redirect_program /usr/bin/squidGuard -c /etc/squid/squidGuard.conf    #(2)

Die obige Konfiguration entspricht weitgehend dem Original. Die folgenden Zeilen wurden jedoch angepasst:

(1) Statt „3128“ wird „127.0.0.1:3128“ verwendet. Hiermit wird Squid angewiesen nur lokale Anfragen anzunehmen.
(Wir wollen ja nicht proxy für alle spielen – gelle ? ) 😉

(2) Diese Anweisung leitet den gesamten Verkehr des Squid über den SquidGuard.
Dies ist notwendig, da SquidGuard ansonsten den Traffic ja gar nicht filtern könnte.

Konfiguration SquidGuard

Sichern der Konfig:

sudo mv /etc/squid/squidGuard.conf /etc/squid/squidGuard.conf.ORIG

Mit einem Editor eine neue Konfig (in /etc/squid/squidGuard.conf) erzeugen:

#
# CONFIG FILE FOR SQUIDGUARD
#

dbhome /var/lib/squidguard/BL    #(1)
logdir /var/log/squid            #(2)

dest adv {
        domainlist      adv/domains
        urllist         adv/urls
}
dest porn {
        domainlist      porn/domains
        urllist         porn/urls
}
dest warez {
        domainlist      warez/domains
        urllist         warez/urls
}
dest gamble {
        domainlist      gamble/domains
        urllist         gamble/urls
}
dest alcohol {
    domainlist  alcohol/domains
    urllist     alcohol/urls
}
dest hacking {
    domainlist  hacking/domains
    urllist     hacking/urls
}
dest sex {
    domainlist  sex/lingerie/domains
    urllist     sex/lingerie/urls
}
dest violence {
    domainlist  violence/domains
    urllist     violence/urls
}
dest spyware {
    domainlist  spyware/domains
    urllist     spyware/urls
}
dest redirector {
    domainlist  redirector/domains
    urllist     redirector/urls
}
dest dating {
    domainlist  dating/domains
    urllist     dating/urls
}
dest chat {
    domainlist  chat/domains
    urllist     chat/urls
}
dest costtraps {
    domainlist  costtraps/domains
    urllist     costtraps/urls
}
dest drugs {
    domainlist  drugs/domains
    urllist     drugs/urls
}
dest fortunetelling {
    domainlist  fortunetelling/domains
    urllist     fortunetelling/urls
}

acl {
    default {
      pass !adv !porn !warez !gamble !alcohol !hacking !sex !violence !spyware !redirector !dating !chat !costtraps !drugs !fortunetelling all  #(3)
      redirect 302:http://www.google.com    #(4)
    }
}

(1) Standort der SquidGuard Datenbank.

(2) Standort der SquidGuard Protokolldatei.

(3) Diese Zeile besagt, daß grundsätzlich erstmal jeder Request erlaubt ist. Mit !porn wird z.B. jeglicher Zugriff auf nacktes Fleisch geblockt. Das Prinzip ist also demzufolge zuerst einmal alles, was verboten ist mit „!“ zu blocken. Das Wörtchen all am Ende der Zeile sorgt dafür, daß alle Webseiten die dann noch übrig sind den Filter passieren können.

(4) „redirect“ bewirkt, daß all geblockten Zugriffe auf die Google Hauptseite umgeleitet werden. (Der verdutzte Benutzer bekommt statt der gewünschten Seite die Google Suchmaske…)

Funktionsweise SquidGuard

Squid gibt vor dem Fetch jeder Webseite die Anfrage an SquidGuard weiter. Dieser holt dann die Seite für Squid. Wenn die gewünschte Seite zur Liste der verbotenen Seiten gehört, liefert SquidGuard statt dessen eine andere Seite (meistens eine sog. Blockpage) zurück.

SquidGuard ist ein Listenbasierter Webfilter. Das heisst: Es wird nicht via regulärer Ausdrücke gefiltert, sondern jede fragliche Website wird auf eine Liste gepackt und dann in ein Datenbankformat konvertiert.

Diese Listen muss man aber nicht selbst pflegen. Es gibt professionelle Anbieter, die diese Listen für ihre Kunden pflegen und zum Download anbieten. als Privatanwender darf man diese Listen meist kostenlos nutzen. Ein Anbieter solcher Listen ist z.B. die Firma Shalla Secure Services.

Diese Firmen bieten diese Listen z.B. als gepackte Dateien an. Natürlich wäre es ziemlich mühsam jedesmal eine Liste aus dem Web zu laden, diese auszupacken und von Hand zu installieren. Weil wir faul sind brauchen wir deshalb 2 Dinge:

  • 1x Skript (updateDB.sh)
  • 1x Cronjob

Installation Skript „updateDB.sh“

Editor öffnen und Datei unter „/etc/squid/updateDB.sh“ speichern:

#!/bin/bash
#
#

DBROOT=/var/lib/squidguard

wget http://www.shallalist.de/Downloads/shallalist.tar.gz -O $DBROOT/BLACKLIST_NEW.tgz
if [ $? -eq 0 ] ; then                                                  #(1)
  rm -f $DBROOT/BLACKLIST.tgz
  mv $DBROOT/BLACKLIST_NEW.tgz $DBROOT/BLACKLIST.tgz
else
  echo "ERROR: could not get \"http://www.shallalist.de/Downloads/shallalist.tar.gz\" ---> EXIT !"
  exit 1
fi

rm -rf $DBROOT/BL                                                       #(2)
tar -xvzf $DBROOT/BLACKLIST.tgz -C $DBROOT                              #(2)

/usr/bin/squidGuard -c /etc/squid/squidGuard.conf -C all                #(3)
chown -R proxy.proxy $DBROOT/BL                                         #(4)

/usr/bin/killall -HUP squid                                             #(5)

(1) Prüfung ob ein File geholt werden konnte. Falls nicht -> Abbruch mit Fehler.

(2) Aufräumen und auspacken der neuen Listen…

(3) SquidGuard aufrufen und neue Datenbank erzeugen…

(4) Rechte setzen…

(5) Am Schluss Squid nochmal durchstarten.

Installation CronJob

Ausführen:

sudo crontab -u root -e

Folgendes eintragen:

# m h dom mon dow command
0 15 1 * * /etc/squid/updateDB.sh

Mit diesem Eintrag in der Crontab des Benutzers „root“ werden jetzt 1x im Monat um 15:00 die Listen für SquidGuard aus dem Web geholt und lokal aktualisiert. Mit „sudo crontab -u root -l“ kann man nochmal eben kontrollieren, ob der Job richtig eingetragen und aktiviert ist.

Rechte setzen:

sudo chmod 0755 /etc/squid/updateDB.sh

Neustart SQUID & SquidGuard

Ubuntu 10.04 LTS verwendet „upstart“. Deshalb macht man das am besten wie folgt:

sudo service squid stop
sudo service squid start

Nach erfolgreichem Neustart sollte die Prozessliste wie folgt aussehen:

ps -ef | grep [s]quid

Ausgabe:

proxy     1570     1  0 Jan16 ?        00:00:13 (squid)
proxy     9542  1570  0 17:56 ?        00:00:00 (squidGuard) -c /etc/squid/squidGuard.conf
proxy     9543  1570  0 17:56 ?        00:00:00 (squidGuard) -c /etc/squid/squidGuard.conf
proxy     9544  1570  0 17:56 ?        00:00:00 (squidGuard) -c /etc/squid/squidGuard.conf
proxy     9545  1570  0 17:56 ?        00:00:00 (squidGuard) -c /etc/squid/squidGuard.conf
proxy     9546  1570  0 17:56 ?        00:00:00 (squidGuard) -c /etc/squid/squidGuard.conf

Proxyeinstellungen im Firefox vorgeben

Wie oben beschrieben müssen wir jetzt noch erzwingen, daß der Benutzer den Proxy (squid) auch benutzt. Dazu wählen wir eine Lösung mit Firefox Policies. Am einfachsten und sichersten ist es die Firefox Regeln über Konfigurationsdateien im Systembereich festzulegen. Das hat zwei Vorteile:

  1. Jeder Benutzer, der auf der Workstation arbeitet hat die gleichen Policies im Firefox und benutzt automatisch den lokalen Proxy.
  2. So lange die Benutzer keine root Rechte auf der lokalen Workstation haben und auch keine Software installieren können ist es relativ schwierig unsere Firefox Policies auszuhebeln. (Allerdings kann ein schlauer User immer noch einen Browser in seinem lokalen Home installieren. In dem Fall gelten die global festgelegten Policies natürlich nicht mehr für seine lokale Browserkopie).

Die Umgehung unseres Proxies mit einem anderen (anonymen) Proxy im inet wird übrigens durch den Abschnitt dest redirector { … } im SquidGuard Konfig File verhindert. Sollte aber ein Proxy verwendet werden, der nicht in der (SquidGuard) Liste steht ist auch das wieder ausgehebelt.

Datei „all.js“ mit editor öffnen:

sudo nano /usr/lib/firefox-3.6.13/greprefs/all.js

WICHTIG: Je nach Linux Version und Firefox Version kann der Pfad „/usr/lib/firefox-3.6.13/greprefs“ variieren. I.d.R. sollte es aber irgendetwas in der Form /usr/lib/firefox*/greprefs sein !

Die folgenden Zeilen (am besten am Ende) eintragen:

//
lockPref("network.proxy.type", 1);
lockPref("network.proxy.http", "127.0.0.1");  #(1)
lockPref("network.proxy.http_port", 3128);    #(2)

(1) IP Addresse unseres lokalen Proxies (=localhost)

(2) Portnummer unseres lokalen Proxies (=3128)

Nach dieser Änderung Firefox neu starten. Danach sieht das Menu unter -> Bearbeiten -> Einstellungen -> Netzwerk -> Einstellungen wie folgt aus:

Firefox Netzwerkeinstellungen

Wie man sehr schön sehen kann sind die Buttons und Felder für die Proxyeinstellung ausgegraut und können nicht mehr verändert werden.

Nun sind die lokalen Benutzer des gerade gepimpten Desktop Rechners relativ gut geschützt gegen Webseiten mit Malware oder Pron. Wer möchte kann natürlich die Regeln etwas lockern. Möchte man z.B. Chat- und Dating-Seiten wieder freigeben so reicht es, wenn man in der SquidGuard Konfig die Zeile

pass !adv !porn !warez !gamble !alcohol !hacking !sex !violence !spyware !redirector !dating !chat !costtraps !drugs !fortunetelling all

ersetzt durch:

pass !adv !porn !warez !gamble !alcohol !hacking !sex !violence !spyware !redirector !costtraps !drugs !fortunetelling all

Wie man leicht erkennen kann, habe ich die beiden Anweisungen !chat & !dating entfernt.


Quellennachweis:


// @(#) $Id: $

Keine Kommentare möglich.