squid proxy

wall < "Howto: squid"

Broadcast message from spillerm@unixe.de (pts/1) (Sa Sep 13 12:52:59 2008):
4
Diesen Beitrag schrieb ich vor 10 Jahren. Behalte das beim Lesen bitte im Hinterkopf.

Beim Stochern in alten Backups fand ich ein Tutorial zu squid, das ich vor einiger Zeit einmal verfasst, aber nie veröffentlicht habe. Ich hab’s noch ein wenig überarbeitet und ziehe die Veröffentlichung hiermit nach. Bei mir handelt es sich um ein NetBSD-current, auf $LEEENUCKS sind die Pfade anders. Viel Spass damit…

Die grundlegende Inbetriebnahme

Beginnen wir mit einer Grundkonfiguration: das Programm soll auf dem Standard-Port 3128 lauschen, Cache-Manager ist meine Wenigkeit, und Username und Gruppe des Programms sollen squid sein; als Sprache wählen wir deutsch, auch wenn die Übersetzungen grausig sind, und wir setzen den User-Agent-String auf Blödsinn um, was aus diversen Gründen vorteilhaft sein kann, zudem wird es auf den IP-Adressssereich des VPN begrenzt:

http_port 3128
cache_mgr spillerm@localwurst.de
cache_effective_user squid
cache_effective_group squid
error_directory /usr/pkg/share/squid/errors/German
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443 563
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 563 # https, snews
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 CONNECT method CONNECT
acl localwurst-vpn src 10.0.16.0/24
http_access allow localhost
http_access allow localwurst-vpn
http_access deny all
header_access User-Agent deny all
header_replace User-Agent Gozilla/4711.0815 (CP/M; 11-bit; 42 KByte)

Danach lassen wir das Programm seinen Speicher einrichten:

$ /usr/pkg/sbin/squid -z

Anschliessend kann der Dienst ein erstes Mal gestartet werden:

$ /etc/rc.d/squid start

Nun folgt die erste Testphase: den Browser einrichten und beobachten, was die Logfiles des squid beim Surfen so von sich geben — das ist wichtig. Wenn alles funktioniert können wir mit dem Fine-Tuning und einigen Spielereien beginnen.

squid als content filter

Gehen wir mal aus von einem Anschluss, an dem (zumindest temporär) mehrere Leute arbeiten; arbeiten bedeutet in diesem Falle, sich jede verfügbare Form vom Free-, Share- & SpyWare auf den Rechner zu ziehen, bei jedem Wurm und Virus »HIER!« zu schreien und diese solange weiter verteilen, bis die feste IP des Anschlusses auf allen denkbaren Blacklists des Webs zu finden ist. Oder aber die faulen Mitarbeiter sausen den lieben langen Tag auf bildschirmarbeiter.de umher und arbeiten nicht.

Es gibt mehrere Ansätze, diesen Missstand in den Griff zu bekommen, und DAUs den Stecker zu ziehen ist vielleicht nicht einmal der uneleganteste. Per squid geht es jedoch auch anders: beispielsweise, indem man *.zip- und *.exe-Dateien einfach blockt oder eine Blacklist unerwünschter Domains verwaltet.

Als freundlicher Admin (der sich Anrufe à la »Ich kann xyz nicht downloaden!!!11einself« ersparen möchte) weist man die User darauf hin, dass an dieser Stelle Inhalte weggefiltert werden; die benötigten Textfiles sind in /usr/pkg/share/squid/error/German/ (analog zu error_directory in squid.conf) zu erstellen (immer hübsch höflich):

ERR_NO_DOWNLOAD

Sorry!
Wegen sicherheitskritischer Aspekte wurde der angeforderte Inhalt geblockt.
Bei Fragen wenden Sie sich bitte an den zuständigen Mitarbeiter!

Hier bloss nicht angeben, wer der zuständige Mitarbeiter ist. Noch wichtiger: das %w für die Email-Adresse rauslassen! Es sei denn, diese Adresse geht direkt nach /dev/null. Oder möchtet Ihr wirklich im Sekundentakt Mails genervter User erhalten? ;)

ERR_NO_DOMAIN

Sorry!
Es ist nicht erwünscht, dass Sie während Ihrer Arbeitszeit diese Domain aufrufen.
Tun Sie dies bitte von zu Hause aus und nach Feierabend.

Okay, und wie blocken wir die Domains nun? Der Einfachheit halber erstellen wir uns Blacklists, die wir dann nach Belieben füllen. Dazu legen wir uns einen Ordner an, sehen, zu, dass dieser dem User und der Gruppe squid gehört und kreieren eine erste Blacklist:

$ mkdir /usr/pkg/etc/squid/blacklists

/usr/pkg/etc/squid/blacklists/domains

.spiegel.de # der vorausgehende Punkt schliesst Subdomains mit ein
.bildschirmarbeiter.de
.ebay.de

/usr/pkg/etc/squid/blacklists/binary

.exe
.zip
.mp3

Nun muss noch in die Konfiguration eingebaut werden, dass diese beiden Dateien ausgewertet und ihr Inhalt entsprechend geblockt werden soll; das sieht dann in etwa so aus:

acl domain-blacklist url_regex "/usr/pkg/etc/squid/blacklists/domains"
acl binary-blacklist url_regex "/usr/pkg/etc/squid/blacklists/binary"
deny_info ERR_NO_DOMAIN domain-blacklist
deny_info ERR_NO_DOWNLOAD binary-blacklist
http_access deny domain-blacklist
http_access deny binary-blacklist

Wem das zu viel Aufwand ist und wer nur einige wenige Dinge sperren will, der kann sich auch so behelfen:

acl faul dstdomain .bildschirmarbeiter.de
acl binary url_regex -i \\. (exe|zip)($|\\?)
deny_info ERR_NO_DOMAIN faul
deny_info ERR_NO_DOWNLOAD binary
http_access deny faul
http_access deny binary

So oder so muss der squid anschliessend rekonfiguriert werden:

$ /usr/pkg/sbin/squid -k reconfigure

Achtet auf Fehlermeldungen! Prüft die Funktionsweise, prüft alles, was euch einfällt, stresst das Ding mal ein bisschen — und seid begeistert wie ich darüber, wie schnell sich so manches realisieren lässt.

Downloadgeschwindigkeit per squid konfigurieren

/usr/pkg/etc/squid/blacklists/huge-data

.flv
.watch?
.view?
.get_video?

Mit den huge-data haben wir etwas anderes vor: die werden wir nicht vollständig blocken, sondern lediglich in der Geschwindigkeit drosseln. Dazu erweitern wir unsere Konfiguration an den entsprechenden Stellen um diese Zeilen:

acl huge-data url_regex "/usr/pkg/etc/squid/blacklists/huge-data"
delay_pools 1
delay_class 1 2
delay_parameters 1 5000/150000 5000/120000
delay_access 1 allow huge-data

Diese Konfiguration kann noch in alle Richtungen angepasst werden, beispielsweise könnte die Bandbreite nur tagsüber beschränkt werden, nachts hingegen Download mit voller Geschwindigkeit erlaubt sein usw. Der Phantasie sind erst einmal wenige Grenzen gesetzt.

Header manipulieren per squid

Zuletzt können wir noch die Header ein wenig manipulieren (und dabei den HTTP-Standard verletzen, aber das nur so am Rande):

header_access From deny all
header_access Referer deny all
header_access Server deny all
header_access User-Agent deny all
header_access WWW-Authenticate deny all
header_access Link deny all

Nutzung des squid über SSH-Tunnel

Da dieser Squid ohnehin nur im Bereich des VPN lauschen darf, ist hier keinerlei User-Authentifizierung vorgesehen — einbauen lässt sich die natürlich schon. Schickerweise nutze ich den Proxy nun über einen SSH-Tunnel — und umgehe damit so einiges, auf das ich hier nicht näher eingehen darf… ;-)

$ ssh -L 3128:localhost:3128 <$VPN>

Anschliessend im Browser den Proxy angeben mit Host localhost und Port 3128. Mittels MRTG oder webalizer (oder diversen anderen) kann man sich entsprechende Graphiken bzgl. der Nutzung aufmalen lassen — beachtet rechtliche Hintergründe gesondert!

squid als transparenter Proxy

Baut ihr einen transparenten Proxy, so müsst ihr das zum einen beim Kompilieren mit angeben (echo "PKG_OPTIONS.squid = ipf-transparent" >> /etc/mk.conf); üblicherweise müssen dem Client-Programm, also beispielsweise dem Browser, die genauen Proxy-Einstellungen mitgegeben werden, was mehrere Nachteile mit sich bringt:

  • Jeder Client muss manuell angepasst werden.
  • Es liegt im Ermessen des jeweiligen Users, was genau er eingibt; in aller Regel ist das etwas Falsches.
  • Auch die Erstellung einer *.pac-Datei bringt einen da nicht unbedingt weiter, weil es immer wieder User gibt, die diese nicht finden können bzw. nicht wissen, wo sie diese einzufüttern haben.

Der transparente Proxy umgeht dieses Problem, indem einfach alle Anfragen von Port 80 auf Port 3128 umgelenkt werden; hierzu ist ein Eintrag in der /etc/ipnat.conf nötig:

rdr sq0 0/0 port 80 -> 127.0.0.1 port 3128 tcp/udp

Diese Änderungen sollten dann auch entsprechend eingelesen werden:

$ ipnat -CF -f /etc/ipnat.conf

Fehlerbehebung

Fällt das Ding mit Fehlermeldungen wie diesen hier um, so checkt die Logfiles — eines davon ist zu gross geworden und muss wegrotiert werden:

Jul 26 13:08:45 xxxx squid[20523]: Squid Parent: child process 20539 started
Jul 26 13:08:45 xxxx squid[20523]: Squid Parent: child process 20539 exited due to signal 25
Jul 26 13:08:48 xxxx squid[20523]: Squid Parent: child process 20576 started
Jul 26 13:08:47 xxxx squid[20523]: Squid Parent: child process 20576 exited due to signal 25
Jul 26 13:08:47 xxxx squid[20523]: Exiting due to repeated, frequent failures
4
  1. Danke für diese kleine howto, man richtet ja nicht jeden tag ne blacklist ein. nach einem jahr wars einfach raus aus dem kopf. hat sehr geholfen, das ganze flott wieder einzubinden.

  2. Hmmm… für squid >= 2.5 sollte das aber eigentlich gehen, nur probiert hab ich’s noch nie. Müsste doch eigentlich reichen, wenn Du in der nsswitch.conf die Reihenfolge auf „files dns“ änderst? Nur mal so eine Idee…

  3. Was mich interessieren würde, ich aber bisher nicht gefunden hab: Wie bring ich dem Ding bei, dass er Namen in /etc/hosts nachschauen soll, weil ich besser weiss, welche IPs die haben?

Keine weitere Reaktionen mehr möglich.