So baust du dir die ultimative Raspberry Pi – Firewall – die fast alles blockt

Autor: Sergej Kukshaus Veröffentlicht: vor 7 monaten Lesedauer: ca. 10 Minuten

In meinen Augen gehört die Firewall zu den Kategorien „easy to learn, hard to master“.

Oder mit anderen Worten: Das Grundprinzip ist eigentlich sehr schnell verstanden. Aber die perfekte Firewall einzurichten, ist eine Wissenschaft für sich.

Jede Firewall basiert auf dem gleichen System: Wenn ein Paket nicht in das Muster passt, wird es aussortiert.

Dabei gibt es zwei verschiedene Modelle: Whitelist und Blacklist.

Wie funktioniert eine Firewall?

Stell dir mal vor, du möchtest in die Disko gehen um mit deinen Kumpels zu feiern. Vor der Tür wirst du von einem freundlichen Türsteher (nennen wir ihn mal Hakan) zunächst abgecheckt.

Analogie zur Netzwerktechnik:

  • Du bist das Paket
  • Hakan ist die Firewall
  • Die Disko ist das Netzwerk

Blacklist Firewall

Der Disko-Besitzer hat was gegen Turnschuhe und sagt Hakan, dass er alle Leute mit Turnschuhen nicht reinlassen soll.

Wenn du jetzt am Abend Turnschuhe anhast, wirst du direkt an der Tür abgewiesen und wirst nach Hause geschickt!

Dieses Verfahren ist eigentlich so das Standardverhalten bei den meisten Firewalls.

Whitelist Firewall

Der obere Disko-Besitzer plant eine Halloween Party und sagt Hakan, dass er nur verkleidete Leute reinlassen darf (auch mit Turnschuhen wenn es zur Verkleidung passt).

Diesmal bist du schlauer und ziehst dir ein schönes Hemd und ein paar Lackschuhe an.

Trotzdem wirst du nach Hause geschickt da du nicht verkleidet bist und damint damit nicht ins Muster passt.

Die Whitelist Firewall ist etwas schwieriger zu konfigurieren. Man muss von vornherein gut planen und gut Überlegen, welche Dienste erlaubt werden.

Hat man sich aber einmal die Mühe gemacht und alles korrekt eingerichtet ist diese Konfiguration in Punkto Sicherheit der Blacklist weit überlegen.

Warum ist eine Firewall wichtig?

Gäbe es in unserem Netzwerk kein Hakan, ähm keine Firewall, könnten Hinz und Kunz auf unser Netzwerk zugreifen und Daten hin und her schicken.

Auch Software (oder ganze Betriebssysteme), die dich ausspioniert (angeblich um die Software besser zu machen) haben durch solche Paketfilter keine Chance, da die Pakete von vornherein abgewiesen werden.

Anderseits ist es auch keine 100%-tige Sicherheit gegenüber Trojanern etc.

Sehr viele Firewalls haben ein aktiven Port 80 (HTTP). Deine auch. Viele Anwendungen nutzen das aus und versenden über Port 80 irgendwelche Pakete. Daher solltest du dich nicht nur auf deine Firewall verlassen, sondern auch andere Sicherheitsvorkehrungen treffen

iptables – die hauseigene Linux Firewall

Die Firewall werden wir mittels iptables einrichten.

Bevor es jedoch praktisch wird, möchte ich noch auf die Funktionsweise von iptables eingehen.

Die folgende Abbildung soll den Ablauf eines Pakets veranschaulichen.

iptables firewall Ketten

Der eigentliche Aufbau besteht aus Tabellen, Ketten und Regeln.

Regeln

Wie der Name schon sagt, sagt eine Regel aus, was mit einem Paket passieren soll.

Ich habe da noch eine schöne Grafik vorbereitet:

firewall iptables regeln

Also eigentlich nur eine Ansammlung von irgendwelchen Bedingungen.

Die Entscheidung, was mit einem Paket passieren soll, bezeichnet man auch als Policy.

Das sind die am meisten verwendeten Policies:

  • ACCEPT: alles gut, das Paket darf weiter
  • REJECT: Paket wird abgewiesen. Der Absender bekommt eine Rückmeldung
  • LOG: Schreibt ein Eintrag in das syslog (und geht zur nächsten Regel weiter).
  • DROP: Das Paket wird ignoriert. Der Absender wird nicht Benachrichtigt.
  • REDIRECT: Das Paket wird modifiziert und an eine andere IP oder anderen Port weitergeleitet
  • MASQUERADE: Bei einem maskierten Paket wird die IP abgeändert indem die Quell-Adresse auf die eigene IP-Adresse geändert wird.

Ketten

Ketten sind eine Ansammlung von Regeln. Es kann aber auch sein, dass keine Regel in einer Kette vorhanden ist.

Ein Paket durchläuft also alle Regeln einer Kette solange bis eine Bedingung zutrifft. Wenn es soweit ist, wird dann die Ausführung der Kette abgebrochen. Ansonsten wird die Standard Policy der Kette angewendet.

Diese Standardketten gibt es:

  • PREROUTING: Alle frischen Pakete
  • FORWARD: Alle Pakete, die zwischen den Netzwerkschnittstellen hin und her gereicht werden
  • INPUT: Alle eingehenden Pakete
  • OUTPUT: Alle herausgehende Pakete
  • POSTROUTING: Alle verarbeiteten Pakete

Tabellen

Last, but not least gibt es noch die Tabellen. iptables kennt dabei drei Tabellen:

  • mangle: Erlaubt das Verändern der Pakete. Beinhaltet alle Ketten
  • nat: steht führ Network Adress Translation und wird verwendet um interne und externe IP-Adressen zu übersetzen. Beinhaltet die PREROUTING, OUTPUT und POSTROUTING Ketten.
  • filter: Der Paketfilter beinhaltet die FORWARD, INPUT und OUTPUT Ketten wird dafür verwendet um Pakete abzuweisen oder durchzulassen.

Von der Theorie, in die Praxis

Wenn du bis hierhin alles durchgelesen hast: Herzlichen Glückwunsch, du kennst jetzt die Theorie von iptables! Wenn nicht, schreibe bitte den Grund in die Kommentare 🙂

Best Practice – Firewall im Autostart ausführen

iptables ist ein Konsolenbefehl und lässt sich eigentlich ganz normal ausführen. Allerdings finde ich unpraktisch. Wenn du den Rechner neu startest, ist die ganze Konfiguration pfutsch.

Ich habe mir angewöhnt für die komplette Konfiguration ein Script zu erstellen und es beim Systemstart auszuführen.

$ nano /etc/init.d/firewall

Diese Datei wird zunächst mit dem folgenden Inhalt erstellt:

#!/bin/sh

case "$1" in
	start)
	;;
	stop)
	;;
esac
exit 0

Damit die Datei ausgeführt werden kann, musst du ihr noch die passenden Rechte verpassen:

$ chmod +x /etc/init.d/firewall

Der nächste Befehl sorgt dafür, dass die das Script beim nächsten Start mit ausgeführt wird.

$ update-rc.d firewall defaults

Zwar kannst du es auch sofort ausführen, jedoch würde ich bis zum Ende der Konfiguration damit warten. Mir ist es passiert, dass ich aus versehen den SSH Port gesperrt habe und mich nicht mehr auf dem PI einloggen konnte. Ein Reset hat die Einstellungen dann verworfen.

Best Practice – Whitelist Firewall

Ich habe bereits weiter oben den den Unterschied zwischen einer Black- und Whitelist Firewall erklärt.

Ich verwende immer eine Whitelist Firewall, da ich gerne die Kontrolle über alle Pakete haben möchte.

Best Practice – Drop vs. Reject

Ich habe viele Firewalls gesehen, die alle Pakete verwerfen. Das ist zwar legitim, aber in meinen Augen nicht die beste Wahl.

Die Diskussion um das Thema ist wohl schon so alt wie es die Firewall gibt.

Meine Meinung dazu: Alles was aus dem LAN kommt, oder nach draußen möchte, sollte abgewiesen werden. Alles was ins Netzwerk möchte, sollte verworfen werden.

Warum? Ganz einfach!

Ich möchte schnell benachrichtigt werden, wenn ein Port blockiert wird und nicht unnötig lange warten. Wenn ich beispielsweise Port 80 sperre, vergehen bis zu 10 Sekunden bis der Browser eine Rückmeldung gibt. Bei ‚Reject‘ kommt die Antwort sofort.

Ich möchte aber nicht unbedingt von außen direkt sichtbar sein. Ist zwar auch nicht so schlimm, aber wozu unnötige Sicherheitslücken ins Haus holen 🙂

Requirements Engineering – firewall

Heißt nichts anderes als: Anforderungsanalyse.

Vor dem Aufbau der Firewall, muss ich zunächst ganz genau wissen, was ich erreichen möchte.

Ich gebe mich mit relativ wenig zufrieden und beschränke mich auf folgende Punkte:

  • Als Netzwerkadministrator möchte ich die Pakete kennen, die in mein Netzwerk reingehen.
  • Als Netzwerkadministrator möchte ich abgewiesene Pakete kennen um ggf. darauf reagieren zu können.
  • Als Benutzer möchte ich in Internet surfen können und meine tägliche Arbeit erledigen können (Email, Web, etc.)

Schritt für Schritt zum perfekten Script

Vorhandene Regeln löschen

Bevor du mit der Konfiguration loslegst, musst du sicherstellen, dass alle Ketten leer sind:

do_flush() {
	iptables -F
	iptables -F -t mangle
	iptables -F -t nat

	iptables -F INPUT
	iptables -F FORWARD
	iptables -F OUTPUT

	iptables -P INPUT ACCEPT
	iptables -P FORWARD ACCEPT
	iptables -P OUTPUT ACCEPT

	iptables -X ROUTER
}

MASQUERADE – IP Adressen maskieren

enable_masquerade() {
	iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
}

INPUT – Paketfilter am Raspberry

Als nächstes werden alle benötigten Ports am Router geöffnet.

Der wohl wichtigste Port ist 22 (SSH). Ohne diesen Port, können wir uns nicht mehr auf den Raspberry aufschalten.

Da ich nicht jedem den Zugriff gewähren möchte, schalte ich es nur für eth1 frei. Also in meinem Fall für alle, die direkt an meinem Router hängen. Endgeräte, die per WLAN ins Netz kommen, werden abgewiesen.

pass_ports() {
	iptables -A INPUT -i eth1 -p tcp --dport 22 -j ACCEPT
	iptables -A INPUT -p icmp -j ACCEPT
	iptables -A INPUT -p tcp -m multiport --dport 139,445 -j ACCEPT
	iptables -A INPUT -p udp -m multiport --dport 137,138 -j ACCEPT
	iptables -A INPUT -p tcp -m multiport --dport 80,443 -j ACCEPT
	iptables -A INPUT -p tcp --dport 68 -j ACCEPT
	iptables -A INPUT -j LOG --log-prefix "[FW] DENY-RPI-ACCESS "
	iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited
	iptables -P INPUT DROP
}

OUTPUT – Bleibst du wohl hier?

Pakete, die aus dem internen Netzwerk kommen, werden auch ordnungsgemäß beantwortet.

Alles andere kommt bei uns nichts ins Haus. Warum auch? 🙂

enable_intranet() {
	iptables -A OUTPUT -o eth1 -j ACCEPT
	iptables -A OUTPUT -o wlan0 -j ACCEPT
	iptables -A OUTPUT -j LOG --log-prefix "[FW] WARNING-CALL-HOME "
	iptables -A OUTPUT -j REJECT
	iptables -P OUTPUT DROP
}

FORWARD – Intranet Paketfilter

Das ist eigentlich das Kernstück des ganzen Artikels.

Hier öffne ich also sukzessiv alle benötigten Ports frei. Aber auch nur die, die wirklich benötigt werden.

enable_routing() {
	# HTTP(s)
	iptables -A FORWARD -p tcp -m multiport --dport 80,443 -j ACCEPT
	iptables -A FORWARD -p udp -m multiport --dport 80,443 -j ACCEPT
	# POP3(s)
	iptables -A FORWARD -p tcp -m multiport --dport 110,995 -j ACCEPT
	iptables -A FORWARD -p udp -m multiport --dport 110,995 -j ACCEPT
	# IMAP(s)
	iptables -A FORWARD -p tcp -m multiport --dport 143,993 -j ACCEPT
	iptables -A FORWARD -p udp -m multiport --dport 143,993 -j ACCEPT
	# SMTP
	iptables -A FORWARD -p tcp --dport 25 -j ACCEPT
	iptables -A FORWARD -p udp --dport 25 -j ACCEPT
	# DNS
	iptables -A FORWARD -p tcp --dport 53 -j ACCEPT
	iptables -A FORWARD -p udp --dport 53 -j ACCEPT
	# NTP (Network Time Protocol)
	iptables -A FORWARD -p udp --dport 123  -j ACCEPT 
	# Google Play (für Androids und so)
	iptables -A FORWARD -p tcp --dport 9000 -j ACCEPT
	iptables -A FORWARD -p tcp --dport 9300 -j ACCEPT
	iptables -A FORWARD -p tcp --dport 9339 -j ACCEPT
	iptables -A FORWARD -p tcp --dport 4234 -j ACCEPT
	iptables -A FORWARD -p tcp --dport 9050 -j ACCEPT
	# WhatsApp
	iptables -A FORWARD -p tcp --dport 5222 -j ACCEPT
	
	iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
	
	iptables -A FORWARD -j LOG --log-prefix "[FW-F] LAN-ACCESS "
	iptables -A FORWARD -j REJECT --reject-with icmp-host-prohibited
}

Dem aufmerksamen Leser wird auffallen, dass ich beispielsweise kein FTP erlaube.

Das mag zwar einige wundern, aber Port 21 wird tatsächlich für einige Trojaner etc. verwendet. Dieses Sicherheitsrisiko möchte ich nicht eingehen.

Falls ich ein neuen Port freischalten muss, schaue mich mir den Port ganz genau an ob dieser Port irgendwelche Gefahren bergen könnte und entscheide dann individuell.

Dazu verwende ich die Tools von adminsub.net oder speedguide.net.

Put it all together

Dieser Anglizismus mal wieder 🙂

So, nachdem du die Funktionen zum Script hinzugefügt hast, kannst du die dann in deine Ausführungsroutine integrieren.

case "$1" in
	start)
		do_flush
		pass_ports
		enable_intranet
		enable_masquerade
		enable_routing
		echo "firewall started";
	;;
	stop)
		do_flush
		echo "firewall stopped";
	;;
esac

Die Firewall kannst du jetzt also mit dem ’start‘ Parameter starten und mit ’stop‘ komplett abschalten.

/etc/init.d/firewall start

Troubleshooting

Es kann schnell passieren, dass ein Port gesperrt wurde, der eigentlich nicht gesperrt werden sollte.

Wenn es nicht gerade Port 22 ist, kann man das schnell beheben:

Mit diesem Befehl listest du alle aktuellen Regeln und Ketten auf:

iptables -L -v

Wenn du deine Firewall so konfiguriert hast, wie oben beschrieben, wird relativ viel geloggt.

Schau als erstes in das log rein und überprüfe welchen Port die Applikation haben könnte.

tail /var/log/syslog

Schaue anschließend ob es sich um ein potentiell gefährlichen Port handelt. Wäge immer den Nutzen und das Risiko ab bevor du ein Port freischaltest.

Weiterführende Links

Zu guter Letzt möchte ich noch ein paar Links aufführen, die mir während meiner Recherche geholfen haben 🙂

Und wenn du nicht alle Schnipsel per Hand zusammenfügen möchtest, habe ich die komplette Datei noch einmal auf github hochgeladen 🙂

github | jupiter | firewall

Fazit

In meinen Augen ist das Thema Firewall am ganzen Projekt am kompliziertesten.

Es gibt viele Konfigurationsmöglichkeiten. Gerade deswegen kann man auch sehr viel falsch machen.

Manchmal vergisst man ein Port zu öffnen und dann funktioniert das halbe Netzwerk nicht mehr. Natürlich sucht man den Fehler zunächst bei genau diese Applikation und nicht bei der Firewall.

Nicht umsonst gibt es ganze Unternehmen, die sich einzig und allein mit dem Thema Firewall beschäftigen und dafür bezahlte Software auf die Beine stellen.

So geht es weiter

Im nächsten Artikel wird es wieder etwas leichter. Da schauen wir uns dann ein Proxy Server an 🙂

Das könnte dir auch gefallen
5 Kommentare
8. August 2019 13:42

Ich musste die Regeln auch umschreiben, da Anwendungsfälle sich stark unterscheiden (rbp nur über wlan erreichbar, soll auch extern erreichbar sein, intern ist mir ziemlich egal).

„Der ftp-port wird oft für trojaner verwendet“ ist gefährliches halbwissen. Ein altes (unsicheres) ftp Programm, das auf diesem Port läuft, wie uralte Versionen von Filezilla, können exploited werden. Ein Trojaner an sich Kommuniziert erstmal nicht, und Malware (wie ein Rootkit) kann im Prinzip jeden Port nutzen und sich selbst auch Berechtigungen freischalten…

17. Oktober 2019 20:53

Hallo Lizard Kind,

Zum Thema RDP:

Extern für den privaten Bereich halte ich persönlich für gefährlich. Sollte jemand das Password rausfinden, hat der Angreifer Vollzugriff auf den kompletten Rechner und allem, was damit zusammenhängt. Wenn den unbedingt RDP notwendig ist, solltest du trotzdem den Port 3389 sperren und dafür ein anderen Port verwenden (z.B. 37419).

Zum Thema FTP:

Stimmt, hier herrscht wirklich „ein gefährliches Halbwissen“ 🙂
Erst einmal zur Begriffserklärung:

  • Trojaner: Ein scheinbar hilfreiches Programm bringt Malware mit und infiziert damit den Rechner. An und für sich ist es auch egal welche Malware.
  • Malware: Ist der Oberbegriff für Viren, Würmer, Trojaner, etc. pp.
  • Exploit: Im Prinzip keine Malware an sich. Hier nutz jemand (z.B. ein Hacker) die Schwachstelle im System aus. Das bekannteste Beispiel hierfür ist eine DDoS-Attacke.

Frag mal einige Administratoren, was die so mit Port 21 machen. Mindestens 95% von denen werden sagen: Sperren! Die anderen 5% werden sagen: Am liebsten Sperren, brauch ich aber. Und dann Frag diese Personen mal warum der Zugang gesperrt wird.

Pauschal zu sagen, dass ein gefährliches Halbwissen vorherrscht, wenn man ein „beliebten“ Port sperrt und einem „alten Programm“ die Schuld in die Schuhe schiebt, halte ich schon für sehr bedenklich.

Gruß
Sergej

9. Oktober 2019 22:20

Hey

Super Artikel, vielen Dank. Ich konnte mit der Hilfe meinen Raspberry in einen kleinen Router verwandeln.

Ich habe auch den Proxy-Server installiert, und würde diesen auch gerne von aussen mit IP-Auth benutzen. Das konnte ich alles einrichten, nur macht mir die Firewall mühe.
Wenn die Firewall gestartet ist, dann bekomme ich keine Verbindung. Sobald ich sie ausschalte, kann ich problemlos darüber von aussen her surfen.

Natürlich kann ich das ohne Firewall nicht verantworten. Und ich habe jetzt schon ein paar Stunden mit der iptables Konfiguration im Firewall-Script verbracht. Bekomme es aber nicht hin.. 🙁
Hast Du evtl. ein Beispiel oder Rat, wie ich die Firewall soweit öffnen kann, so dass ich von aussen den Proxy-Server auch verwenden kann?

Grüsse

17. Oktober 2019 21:03

Hi ChiOne,

für mich klingt das so, als ob ein bestimmter Port blockiert wird.

Versuch mal folgendes:

  • Aktiviere die Firewall
  • Versuch dich zu Verbinden
  • Schau mal in der Datei: /var/log/syslog nach was drin steht. Hier sollte sowas stehen wie: Zugriff über Port XXX gesperrt.
  • Schalte den Port frei und probiere es noch einmal

Grüße
Sergej

26. Oktober 2019 11:58

Hallo, ich finde deine Anleitung super und es macht echt Freude dein Projekt nachzubauen.
Bei der Firewall erhalte ich immer folgenden Fehler…
# /etc/init.d/firewall start
firewall started
iptables: No chain/target/match by that name.

Nach einiger Recherche stellt sich raus, das ein Modul fehlt, aber ich finde nirgends eine Lösung, wie ich es nachinstallieren/laden kann 🙁

# modprobe netfilter
modprobe: FATAL: Module netfilter not found in directory /lib/modules/4.19.75-v7l+

... und was meinst du dazu?
Deine E-Mail-Adresse wird nicht veröffentlicht.