Linux-Firewall iptables unter Raspbian konfigurieren

  • Wenn Sie auf Ihrem Raspberry Pi das momentan aktuelle Raspbian Image vom 09.02.2013 (2013-02-09-wheezy-raspbian.zip) einsetzen, dann ist die Linux-Firewall iptables bereits installiert. In der Grundkonfiguration von Raspbian erlaubt iptables jedoch den Zugriff auf jeden Port für jede beliebige IP-Adresse. Dies ist oft nicht erwünscht weil Dienste nur für bestimmte Netzwerkbereiche verfügbar sein sollen oder generell alle Zugriffe auf das Linux-System und dessen Dienste durch eine Firewall gefiltert werden sollen.


    Die folgende Anleitung soll zeigen, wie Sie iptables unter Raspbian konfigurieren und den SSH-Zugriff erlauben. Es soll anhand des SSH-Ports auch gezeigt werden, wie Sie diesen nur für das lokale Netzwerk freigeben können.


    Standardmäßig gibt es im aktuellen Raspbian Image noch keine Konfigurationsdatei für die Firewall-Regeln. Daher erstellen Sie einfach die Datei /etc/network/iptables mit einem Editor.


    Code
    pi@raspberrypi ~ $ sudo vi /etc/network/iptables


    Fügen Sie hier zum Beispiel die folgende Konfiguration ein. Die einzelnen Regeln werden im Anschluss erklärt.


    Code
    *filter
    :INPUT DROP [159:12505]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [140:13492]
    -A INPUT -i lo -j ACCEPT
    -A INPUT -p icmp -j ACCEPT
    -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
    -A INPUT -j REJECT --reject-with icmp-host-prohibited
    COMMIT


    Die folgende Regel erlaubt alle Zugriffe welche über die Loopback-Schnittstelle lo ankommen. Dies können nur Zugriffe vom eigenen Linux-System sein.


    Code
    -A INPUT -i lo -j ACCEPT


    Über die nächste Firewall-Regel werden ICMP-Anfragen wie zum Beispiel der ICMP Echo Request, auch bekannt als Ping, erlaubt.


    Code
    -A INPUT -p icmp -j ACCEPT


    Damit bereits aufgebaute eingehende Verbindungen generell erlaubt werden sorgt die folgende Regel.


    Code
    -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT


    Die nächste Firewall-Regel erlaubt den Zugriff auf den TCP-Port 22 welcher normalerweise vom SSH-Daemon genutzt wird. Hierbei erfolgt keine Unterscheidung ob die Verbindungsanfrage vom internen Netzwerk oder von einem anderen Netzwerk wie zum Beispiel dem Internet kommt.


    Code
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT


    Wenn Sie den Zugriff auf den SSH-Daemon nur aus dem internen Netzwerk erlauben wollen, können Sie die Regel wie folgt erweitern. Es wird hier angenommen, dass Sie sich im Netzwerk 192.168.10.0/24 befinden.


    Code
    -A INPUT -s 192.168.10.0/24 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT


    Wenn Sie zwei Netzerkschnittstellen verwenden, wie zum Beispiel LAN und WLAN, können Sie den SSH-Port auch nur auf einem Interface freigeben. Die folgende Regel erlaubt nur den Zugriff über die LAN-Schnittstelle eth0.


    Code
    -A INPUT -i eth0 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT


    Die letzte Firewall-Regel in der hier gezeigten Beispielkonfiguration weist alle eingehenden Pakete ab, welche nicht durch eine der vorhergehenden Firewall-Regeln explizit erlaubt wurde. Aus diesem Grund muss diese Regel auch immer die letzte Regel in der sogenannten Firewall-Chain sein.


    Code
    -A INPUT -j REJECT --reject-with icmp-host-prohibited


    Wenn Sie die Konfigurationsdatei /etc/network/iptables erstellt haben, sollten Sie diese jetzt mit dem folgenden Befehl laden.


    Code
    pi@raspberrypi ~ $ sudo iptables-restore /etc/network/iptables


    Ob die Firewall-Regeln geladen wurden können Sie wie folgt überprüfen.



    Bevor Sie mit dem nächsten Schritt fortfahren, sollten Sie sicherstellen, dass der Zugriff über SSH und gegebenenfalls auf weitere freigegebene Ports funktioniert.


    Damit die Firewall-Regeln bei einem Neustart des Systems oder des Netzwerkdienstes automatisch geladen werden, müssen Sie noch ein Pre-Up Skript erstellen.


    Code
    pi@raspberrypi ~ $ sudo vi /etc/network/if-pre-up.d/iptables


    Fügen Sie in die Datei /etc/network/if-pre-up.d/iptables die folgenden Zeilen ein.


    Bash
    #!/bin/sh
    /sbin/iptables-restore /etc/network/iptables


    Damit das Skript ausgeführt werden kann müssen Sie die Zugriffsrechte entsprechend anpassen.


    Code
    pi@raspberrypi ~ $ sudo chmod +x /etc/network/if-pre-up.d/iptables


    Wenn Sie testen wollen ob die Firewall-Regeln auch nach dem Neustart geladen werden, können Sie jetzt einen Neustart des Systems durchführen.


    Code
    pi@raspberrypi ~ $ sudo shutdown -r now


    Nach dem Neustart können Sie die Firewall-Regeln wieder mit dem folgenden Befehl auslesen.



    Hinweis: Dieses und viele weitere Tutorials finden Sie auf meiner Webseite.


    ---------------------------------------------------------------------------------------------------------------------------------------------


    Erweiterung vom 30.06.2013


    Bisher wurde nur auf den TCP-Port 22, welcher vom SSH-Daemon genutzt wird, eingegangen. In dieser Vortsetzung der obigen Anleitung möchte ich noch weitere Firewall-Regeln aufzeigen, welche Sie verwenden können, wenn Sie die jeweiligen Server-Dienste auf Ihrem Raspberry Pi betreiben.


    Wichtiger Hinweis


    Beachten Sie beim Einfügen einer der folgenden Firewall-Regeln in die /etc/network/iptables, dass sich die Firewall-Regel vor der folgenden Zeile befindet. Andernfalls werden die eingehenden Pakete abgewiesen bevor die gewünschte Firewall-Regel angewendet wird.


    Code
    -A INPUT -j REJECT --reject-with icmp-host-prohibited


    FTP-Server


    Für einen FTP-Server welcher im passiven Modus erreichbar sein soll, wird die folgende Firewall-Regel benötigt. Dadurch wird der TCP-Port 21 für FTP freigegeben.


    Code
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT


    Samba-Server


    Bei einem Samba-Server müssen mehrere Ports in der Firewall geöffnet werden damit dieser ordnungsgemäß funktionieren kann.


    Code
    -A INPUT -p udp -m state --state NEW -m udp --dport 137 -j ACCEPT
    -A INPUT -p udp -m state --state NEW -m udp --dport 138 -j ACCEPT
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 139 -j ACCEPT
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 445 -j ACCEPT


    Webserver


    Wird ein Webserver betrieben muss der TCP-Port 80 für HTTP in der Firewall geöffnet werden.


    Code
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT


    Ist der Webserver auch über HTTPS erreichbar, muss auch der TCP-Port 443 in der Firewall geöffnet sein.


    Code
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT


    Mailserver


    Bei einem Mailserver werden wie bei Samba verschiedene Protokolle eingesetzt. Zum Empfangen von Mails muss der Mailserver über SMTP (TCP-Port 25) erreichbar sein.


    Code
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 25 -j ACCEPT


    Zum Abrufen von E-Mails kann man POP3 oder IMAP verwenden. Wird POP3 verwendet, muss man den TCP-Port 110 in der Firewall öffnen.


    Code
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 110 -j ACCEPT


    Das mit SSL abgesicherte POP3s nutzt hingegen den TCP-Port 995.


    Code
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 995 -j ACCEPT


    IMAP lauscht in der Regel auf dem TCP-Port 143.


    Code
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 143 -j ACCEPT


    Bei IMAPs handelt es sich ebenfalls um eine mit SSL abgesicherte IMAP-Verbindung welche den TCP-Port 993 nutzt.


    Code
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 993 -j ACCEPT


    DNS-Server


    Beim Domain Name Service (DNS) müssen der TCP-Port 53 und der UDP-Port 53 in der Firewall geöffnet werden.


    Code
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 53 -j ACCEPT
    -A INPUT -p udp -m state --state NEW -m udp --dport 53 -j ACCEPT


    DHCP-Server


    Wenn Sie einen DHCP-Server betreiben, sollten Sie den TCP-Port 68 öffnen damit Anfragen aus dem Netzwerk beim DHCP-Daemon ankommen können.


    Code
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 68 -j ACCEPT


    TFTP-Server


    Das Trivial File Transfer Protocol (TFTP) wird zum Beispiel bei einem PXE-Server verwendet und nutzt den UDP-Port 69.


    Code
    -A INPUT -p udp -m state --state NEW -m udp --dport 69 -j ACCEPT


    NTP-Server


    Betreibt man einen Zeitserver welcher das Network Time Protocol (NTP) nutzt, muss man den UDP-Port 123 in der Firewall öffnen.


    Code
    -A INPUT -p udp -m state --state NEW -m udp --dport 123 -j ACCEPT


    Druckserver


    Das Internet Printing Protocol (IPP) verwendet den TCP-Port 631 sowie den UDP-Port 631 und wird zum Beispiel von CUPS verwendet um Drucker im Netzwerk zur Verfügung zu stellen.


    Code
    -A INPUT -p tcp -m tcp --dport 631 -j ACCEPT
    -A INPUT -p udp -m udp --dport 631 -j ACCEPT


    Rsync-Server


    Rsync ist ein Protokoll zur Datensynchronisation und nutzt den TCP-Port 873.


    Code
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 873 -j ACCEPT


    OpenVPN-Server


    Falls Sie einen OpenVPN-Server betreiben müssen Sie den TCP-Port 1194 öffnen. Beachten Sie hierbei, dass OpenVPN auch den UDP-Port 1194 nutzen kann wenn dies in der Konfigurationsdatei entsprechend definiert wurde.


    Code
    -A INPUT -p udp -m state --state NEW -m udp --dport 1194 -j ACCEPT


    Hinweis: Dieses und viele weitere Tutorials finden Sie auf meiner Webseite.

  • Hallo,
    ich wollte noch mehr Sicherheit und wollte mal fragen, ob meine Ergänzungen so richtig sind.
    Habe deine beiden Anleitungen durchgearbeitet (+ noch etwas gegoogelt) und gehe auch davon aus, dass alles so funktioniert aber sicher ist sicher. ;)



    PS: Was bedeutet eigentlich die Zahlen am Anfang in den Klammern also z.B. bei :INPUT DROP [0:0]?



    Hier meine Datei, die zusätzlich nur Port 80/443 erlaubt:


  • Hallo vidarx,


    Quote

    PS: Was bedeutet eigentlich die Zahlen am Anfang in den Klammern also z.B. bei :INPUT DROP [0:0]?


    Eine Firewall-Chain ist wie folgt aufgebaut:


    Code
    chain-name chain-policy [packet-counter:byte-counter]


    Die beiden Zahlen sind also Zähler wie viele Pakete bzw. Bytes bereits die Regel passiert haben. Ich habe die Firewall-Regeln mit "iptables" erstellt und anschließend mit "iptables-save" exportiert und für das Tutorial verwendet. Daher sind hier bereits einige Werte gespeichert. Du kannst diese aber auch ohne Probleme auf "[0:0]" ändern.


    Siehe auch: http://www.faqs.org/docs/iptables/iptables-save.html


    Quote

    Hier meine Datei, die zusätzlich nur Port 80/443 erlaubt:


    Deine zusätzlichen Regeln werden nicht funktionieren. Wenn man Firewall-Regeln mit "-A" hinzufügt, werden diese an das Ende der Firewall-Chain gehängt. Am Ende sollte aber die folgende Regel stehen.


    Code
    -A INPUT -j REJECT --reject-with icmp-host-prohibited


    Diese Regel sorgt dafür, dass alle Pakete, welche nicht vorher auf eine andere Regel gepasst haben, abgelehnt werden. Bei dir würden alle Pakete abgelehnt werden bevor die zusätzlichen Regeln den gewünschten Effekt erzielen könnten. Daher solltest du die Konfiguration wie folgt anpassen.



    Die folgende Regel habe ich entfernt weil diese bereits durch eine andere abgedeckt wird.


    Code
    -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT


    Gruß Georg

  • Sehr gut erklärt !
    Sollte bei den Tut's immer ganz oben stehen.
    Oder unter Wichtige Themen einen Thread : "Den PI härten" mit Links zu den einzelnen Tutorials und noch ein oder zwei Tips.

    Offizieller Schmier und Schmutzfink des Forum.
    Warum einfach wenn's auch schwer geht ?


    Kein Support per PN !
    Fragen bitte hier im Forum stellen. So hat jeder etwas davon.

  • Hallo Georg,


    ich bin nach Deiner Anleitung vorgegangen. Jedoch siehen bei mir die Firewall-Regeln nach einem Neustart anders aus.


    Code
    pi@raspbmc:~$ sudo iptables -L
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination
    ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
    ACCEPT     all  --  192.168.132.0/24     anywhere
    DROP       all  --  anywhere             anywhere


    Hast Du eine Idee an was es liegen kann?


    So sieht meine Konfiguration aus:


    Code
    pi@raspbmc:~$ ls -l /etc/network/iptables
    -rw-r--r-- 1 root root 422 May 11 13:30 /etc/network/iptables



    Code
    pi@raspbmc:~$ ls -l /etc/network/if-pre-up.d/iptables
    -rwxr-xr-x 1 root root 57 May 11 13:33 /etc/network/if-pre-up.d/iptables



    Wenn ich die Firewall-Regel wieder lade:


    Code
    pi@raspbmc:~$ sudo iptables-restore /etc/network/iptables



    Sieht es "richtig" aus:


    Code
    pi@raspbmc:~$ sudo iptables -L
    Chain INPUT (policy DROP)
    target     prot opt source               destination
    ACCEPT     all  --  anywhere             anywhere
    ACCEPT     icmp --  anywhere             anywhere
    ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
    ACCEPT     tcp  --  192.168.132.0/24     anywhere             state NEW tcp dpt:ssh
    ACCEPT     tcp  --  192.168.132.0/24     anywhere             state NEW tcp dpt:8001
    REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited



    Gruß, Alex

  • Hallo Alex,


    bereits mit der folgenden Information ist das Problem erklärbar.


    Quote

    pi@raspbmc:~$


    Die Anleitung ist für Raspbian - steht auch bereits im ersten Satz. Bei Raspbmc - was du verwendest - funktioniert die Anleitung nicht. Der Grund hierfür liegt ganz einfach an Raspbmc. Die Netzwerkeinstellungen sind bei Raspbmc ganz anders als bei Raspbian und den meisten anderen Linux-Distributionen.


    Wenn du bei Raspbmc an den Firewall-Einstellungen drehen willst, dann musst du dies in der "/etc/network/if-up.d/secure-rmc" machen. Du kannst dir mal die folgende Anleitung durchlesen. Dort wird nur die Regel für den SSH-Port geändert. Im Grunde kannst du an dieser Stelle aber auch weitere Ports freigeben oder feinere Einstellungen machen.


    http://www.gtkdb.de/index_7_2108.html


    Beachte aber, dass eventuell bei einem Raspbmc-Update auch diese Datei überschrieben werden kann. Raspbmc ist einfach nicht dafür gedacht damit man da selber Änderungen vornehmen kann/sollte.


    Gruß Georg

  • Ok, danke! Ich habe meine Pi erst seit ein paar Tagen und dachte, dass Raspbmc auf Raspbian aufsetzt.
    Werde es dann entsprechend anpassen.


    Gruß, Alex

  • Hallo Alex,


    Raspbmc basiert auch auf Raspbian, allerdings wurde Raspbmc sehr stark modifiziert. Die ganze Netzwerkkonfiguration ist bei Raspbmc leider ganz anders und lässt sich auch nicht so leicht anpassen wie bei Raspbian. Raspbmc wurde nunmal für die grafische Oberfläche von XBMC angepasst und kann auch nur darüber wirklich konfiguriert werden. Sobald man selber Raspbmc erweitern will kommt man schnell zu dem Punkt, an welchem man sich das System zerschießt.


    Für deine zwei zusätzlichen Firewall-Regeln musst du eigentlich in der "/etc/network/if-up.d/secure-rmc" nur die folgende Änderung vornehmen.


    Code
    if [ "$IFACE" != "lo" ]; then
        NETMASK=$(get_subnet $IFACE)
        iptables -A INPUT -s $NETMASK -i $IFACE -j ACCEPT
        iptables -A INPUT -s 192.168.132.0/24 -p tcp --dport 22 -j ACCEPT
        iptables -A INPUT -s 192.168.132.0/24 -p tcp --dport 8001 -j ACCEPT
        iptables -A INPUT -i $IFACE -j DROP
    fi


    Nach einem Neustart sollten diese dann auch aktiv sein.


    Gruß Georg

  • Hallo,


    ich bekomme beim Einrichten der iptables folgende Fehlermeldung_

    Quote


    root@raspberrypi:~# iptables-restore /etc/network/iptables
    'ptables-restore v1.4.14: iptables-restore: unable to initialize table 'filter


    Error occurred at line: 1
    Try `iptables-restore -h' or 'iptables-restore --help' for more information.


    Woran könnte das liegen?

  • In "/etc/network/iptables" steht


    *filter
    :INPUT DROP [159:12505]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [140:13492]
    -A INPUT -i lo -j ACCEPT
    -A INPUT -p icmp -j ACCEPT
    -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
    -A INPUT -j REJECT --reject-with icmp-host-prohibited
    COMMIT


    Die Datei ist nicht von vi, sondern von der Internetseite in WinSCP kopiert und anschließend von WinSCP in den Raspi
    kopiert worden. Am vi bin ich gescheitert, der nvi wäre kein Problem gewesen.
    Vielleicht hat es mit der Formatierung der Datei zu tun.


    Grüße Henry

  • Hallo Henry,


    wenn du mit vi nicht zurecht kommst, dann versuch es doch einfach mal mit nano.
    Es kann durchaus sein, dass die Formatierung nicht passt wenn du die Datei unter Windows editiert hast. Am Besten du erstellst die Datei auf dem Raspberry Pi nochmals mit nano.


    Gruß Georg

  • Hey!
    Tolles Tutorial um iptables zu konfigurieren. Die hier erwähnten Regeln klappen wunderbar, allerdings scheitere ich an FTP.


    Ich habe die Regel für SSH an Port 21 angewandt, mit FileZilla klappt dann die FTP Verbindung, allerdings wird kein Verzeichnisinhalt empfangen und auch sonst passiert nichts mehr.


    Beim Googeln bin ich auf verschiedenste, (für mich) total komplizierte Regeln (teilweise nur eine Zeile, manchmal bis zu 6) gestoßen, doch selbst die brachten mich nicht weiter als den erfolgreichen Verbindungsaufbau.


    Wie müssen korrekte Regeln für FTP aussehen?
    Ich verwende FileZilla in seiner Standardconfig.


    LG Monoxid


  • ...Wie müssen korrekte Regeln für FTP aussehen?...


    Bei ftp gibt es sog. active und passive mode. Ersterer ist unbrauchbar wenn Du einen FW zu überwinden hast. Prüfe mal welchen ftp Mode Du eingestellt hast und ändere ihn auf passive.

    "Really, I'm not out to destroy Microsoft. That will just be a completely unintentional side effect."

    Linus Benedict Torvalds, 28.9.2003


    Hast Du die Woche schon Deine Raspberry gesichert :fies: Bei mir tut das raspiBackup automatisch :shy:

  • Hallo zusammen,


    ich habe das Tutorial etwas erweitert und Firewall-Regeln für die gängigsten Serverdienste hinzugefügt. Sollte ein Service fehlen, dann bitte kurz bescheid geben dann kann ich diesen auch noch aufnehmen.


    Gruß Georg

  • Super Erweiterung im ersten Post!


    Nur die Regel

    Code
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT


    alleine half nur den FTP Server zu erreichen, jedoch bekam ich nach wie vor keinen Verzeichnisinhalt o.Ä.


    Hab in den Einstellungen von ProFTPD gestöbert und die passiven Ports auf die Range 55000-55500 eingestellt und die Ports mit folgender Regel noch zusätzlich freigegeben:


    Code
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 55000:55500 -j ACCEPT


    In FileZilla musste ich eigentlich garnichts umstellen. Hatte da erst explizit passiven Modus eingestellt, klappt aber auch mit Standard, FZ wählt automatisch den passiven Modus.


    Mit den beiden Regeln gemeinsam klappt es nun perfekt.


    Frage zum Schluss:
    Ist die zweite Regel jetzt totaler humbug weil wieder so viele Ports offen sind bzw kann man das geschickter lösen?


    LG Monoxid

  • Hallo habe irgendwie noch Probleme. Seit ich die Whitelist und das BruteForce eingebaut habe komme ich von außerhalb nicht mehr auf mein Raspberry.


    Meine iptables:


    hier die Ausgabe von [font="Helvetica"]sudo cat /proc/net/xt_recent/ssh[/font]


    Code
    src=xx.xxx.xx.xxx ttl: 62 last_seen: 736616368 oldest_pkt: 3 736606066, 736609207, 736616368
    src=xxx.xx.xxx.xx ttl: 48 last_seen: 736629309 oldest_pkt: 14 736613621, 736616810, 736620655, 736620762, 736620863, 736620963, 736621064, 736621165, 736621367, 736621818, 736622762, 736624405, 736627672, 736629309, 736610206, 736610306, 736610407, 736610608, 736611060, 736611985



    [font="Helvetica"]Sieht soweit doch alles ganz gut aus oder? [/font]

  • Hallo aplaceformyhead,


    Danke für deinen Hinweis per PM. Dein Post ist bei mir wohl in der Menge an Posts untergegangen.
    Dein Problem bezieht sich eigentlich auf das Tutorial SSH-Server unter Raspbian vor Brute-Force-Angriffen schützen. Bist du nach dem Tutorial vorgegangen? Wenn ja, wundert mich der Fehler ein wenig.


    Der Fehler ist in der folgenden Zeile zu finden. Du hast in allen anderen Zeilen als Namen für die Whitelist-Datei "ssh" angegeben. Nur in der folgenden Zeile schreibst du auf einmal "DEFAULT".


    Quote

    -A SSH-BruteForce -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 600 --hitcount 3 --name DEFAULT --rsource


    Gruß Georg