System: SuSE Linux 9.1
Der Rechner, auf dem diese Regeln laufen, hat einen DSL-Zugang ins Internet und eine Netzwerkkarte zum lokalen Netz. Das lokale Netz soll gegen das Internet abgeschirmt werden, der Zugriff ins Internet erfolgt nur über Proxies, ssh ins Internet beispielsweise mit Hilfe von Socks. Wenn IPSec gestartet ist, ist der Zugriff vom Notebook auf Ressourcen im lokalen Netz möglich.
Ich habe verschiedene benutzerdefinierte Chains verwendet:
Außerdem habe ich soweit möglich das multiport-Modul verwendet, was die Pflege des Skripts sehr vereinfacht. Neue Dienste müssen nur bei den Ports eingetragen werden. In den einzelnen Chains ist jeweils nur das erste IP-Paket aufgeführt, um die weiteren IP-Pakete kümmert sich das state-Modul.
Da es beim Kernel 2.6.x bei IPSec kein Interface ipsec0 mehr gibt, sind auch die Regeln für IPSec geändert, dort kommt jetzt das mangle-Modul zum Einsatz, das Pakete markiert. Die Markierung wird ausgewertet, um Pakete zu erkennen, die zum IPSec-Tunnel gehören.
#!/bin/bash # Copyright (c) 2004 Björn Lotz # # Author: Björn Lotz # # /etc/init.d/ipt_rules # # and symbolic its link # # /sbin/rcipt_rules # # System startup script for the packet filter # ### BEGIN INIT INFO # Provides: packetfilter # Required-Start: $network $syslog # Required-Stop: $network $syslog # Default-Start: 3 5 # Default-Stop: 0 1 2 4 6 # Description: Start iptables-Firewall ### END INIT INFO . /etc/rc.status # First reset status of this service rc_reset case "$1" in start|restart|reload) echo "Die Packet-Filter-Regeln werden gesetzt ..." ######### Variablen: # Interfaces DSL=ppp0 LAN=eth0 # Adressen LOKALE_IP=192.168.0.15 LOKALES_NETZ=192.168.0.0/24 # Nameserver NS1=194.25.2.129 NS2=212.185.252.201 # Zeitserver # T-Online, ntp1.t-online.de #TIME1=195.145.119.188 # Braunschweig TIME1=192.53.103.103 TIME2=192.53.103.104 # Ports UNPRIV="1024:65535" TRACEROUTE="33434:33999" # Private Adressbereiche CLASSA=10.0.0.0/8 CLASSB=172.16.0.0/12 CLASSC=192.168.0.0/16 ######### Kernelparameter (Barth, Firewall-Buch p209) # Routing erforderlich für IPSec und für die Port-Umleitung, # da aufgrund einer Änderung am SuSE-Kernel 2.6.5, # diese nur funktioniert, wenn Routing eingeschaltet ist |-( echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv4/tcp_syncookies echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses # Schutz vor ICMP-Redirect-Paketen aktivieren for f in /proc/sys/net/ipv4/conf/*/accept_redirects do echo 0 > $f done # Blocken von Source-Routed-Paketen for f in /proc/sys/net/ipv4/conf/*/accept_source_route do echo 0 > $f done # Loggen von gespooften Paketen, Source-Routed-Paketen und Redirect-Paketen # geht nicht mit IP-Sec #for f in /proc/sys/net/ipv4/conf/*/log_martians; do # echo 1 > $f #done # Schutz vor IP-Spoofing aktivieren # geht nicht mit IP-Sec #for f in /proc/sys/net/ipv4/conf/*/rp_filter; do # echo 1 > $f #done ######### Default-Policy setzen und vorhandene Regeln l�chen iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP iptables -F iptables -t nat -F iptables -X ######### fr Stateful Inspection von ftp: modprobe ip_conntrack_ftp ######### Lokale Prozesse iptables -A OUTPUT -o lo -j ACCEPT iptables -A INPUT -i lo -j ACCEPT #################################################################################### # # # Eigene Chains # # # #################################################################################### ######### Logging ####################################### # Log und Reject, bzw Drop, wenn's viele Pakete sind iptables -N my_drop # zuerst mal die e-donkey-Pakete und die von verschiedenen Würmern verwerfen, # die anscheinend nicht auf tcp-reset reagieren iptables -A my_drop -p TCP --syn --dport 135:137 \ -m limit --limit 10/hour --limit-burst 2 -j LOG --log-prefix "DROP-TCP-SYN " iptables -A my_drop -p TCP --syn --dport 135:137 \ -m limit --limit 1/s -j REJECT --reject-with tcp-reset iptables -A my_drop -p TCP --syn --dport 135:137 -j DROP iptables -A my_drop -p TCP --syn --dport 445 \ -m limit --limit 10/hour --limit-burst 2 -j LOG --log-prefix "DROP-TCP-SYN " iptables -A my_drop -p TCP --syn --dport 445 \ -m limit --limit 1/s -j REJECT --reject-with tcp-reset iptables -A my_drop -p TCP --syn --dport 445 -j DROP iptables -A my_drop -p TCP --syn --dport 4662 \ -m limit --limit 10/hour --limit-burst 2 -j LOG --log-prefix "DROP-TCP-SYN " iptables -A my_drop -p TCP --syn --dport 4662 \ -m limit --limit 1/s -j REJECT --reject-with tcp-reset iptables -A my_drop -p TCP --syn --dport 4662 -j DROP iptables -A my_drop -p TCP --syn -j LOG --log-prefix "DROP-TCP-SYN " iptables -A my_drop -p TCP --syn \ -m limit --limit 5/s -j REJECT --reject-with tcp-reset iptables -A my_drop -p TCP --syn -j DROP iptables -A my_drop -p TCP -j LOG --log-prefix "DROP-TCP " iptables -A my_drop -p TCP \ -m limit --limit 5/s -j REJECT --reject-with tcp-reset iptables -A my_drop -p TCP -j DROP iptables -A my_drop -p UDP -j LOG --log-prefix "DROP-UDP " iptables -A my_drop -p UDP \ -m limit --limit 5/s -j REJECT --reject-with icmp-port-unreachable iptables -A my_drop -p UDP -j DROP iptables -A my_drop -p ICMP -j LOG --log-prefix "DROP-ICMP " iptables -A my_drop -p ICMP -j DROP iptables -A my_drop -j LOG --log-prefix "DROP-PROTO-ETC " iptables -A my_drop \ -m limit --limit 5/s -j REJECT --reject-with icmp-proto-unreachable iptables -A my_drop -j DROP #################################################################################### # # # EXTERNE Verbindungen INTERNET --> Rechner (INPUT-Interface $DSL) # # # #################################################################################### # In diese Chain kommt alles mit INPUT-Interface $DSL iptables -N internet_in # TCP, Internet --> Rechner: ### #iptables -A internet_in -m mark --mark 10 -j LOG --log-prefix "MARKIERT--- " # ssh - 22 (auch via 443), mit Logging iptables -A internet_in -p TCP --syn --dport 22 -j LOG --log-prefix ">>> Zugriff iptables -A internet_in -p TCP --syn --sport $UNPRIV -m multiport --dports 22 \ -j ACCEPT # Nicht erforderlich als eigene Regel, aber der Deutlichkeit halber: # Jeglicher sonstige TCP-Verbindungsaufbau von außen ist verboten. iptables -A internet_in -p TCP -i $DSL --syn -j my_drop # Ebenso: Schutz vor IP-Spoofing iptables -A internet_in -s $CLASSA -j my_drop iptables -A internet_in -s $CLASSB -j my_drop #iptables -A internet_in -s $CLASSC -j my_drop # UDP, Internet --> Rechner: ### # isakmp - 500 iptables -A internet_in -p UDP --sport 500 --dport 500 -j ACCEPT iptables -A internet_in -j my_drop #################################################################################### # # # EXTERNE Verbindungen Rechner --> INTERNET (OUTPUT-Interface $DSL) # # # #################################################################################### # In diese chain kommt alles mit OUTPUT-Interface $DSL iptables -N internet_out ### TCP, Rechner --> Internet: ### # ftp - 21 # smtp - 25 iptables -A internet_out -p TCP --syn -m multiport --dports 21,25 --sport $UNPRIV \ -j ACCEPT # FTP-Proxy-Datenkanal, passiv, von hohen Ports zu hohen Ports (von hier ins I-Net) # Für FTP bräuchte es das nicht, das wrde ftp-conntrack übernehmen, # aber so sind auch Verbindungen von hier z.B. zu pgp-Keyservern möglich. iptables -A internet_out -p TCP --syn --sport $UNPRIV --dport $UNPRIV -j ACCEPT ### UDP, Rechner --> Internet: ### # time - 37, nur zu bestimmten Servern, deshalb eigene Regeln # dns - 53 # isakmp - 500 # traceroute - Portrange, deshalb eigene Regel iptables -A internet_out -p UDP --sport $UNPRIV -m multiport --dports 53 -j ACCEPT iptables -A internet_out -p UDP -d $TIME1 --sport $UNPRIV --dport 37 -j ACCEPT iptables -A internet_out -p UDP -d $TIME2 --sport $UNPRIV --dport 37 -j ACCEPT iptables -A internet_out -p UDP --dport $TRACEROUTE -j ACCEPT iptables -A internet_out -p UDP --sport 500 --dport 500 -j ACCEPT iptables -A internet_out -j my_drop #################################################################################### # # # INTERNE Verbindungen INTRA --> Rechner (INPUT-Interface $LAN) # # # #################################################################################### # In diese chain kommt alles mit INPUT-Interface $LAN iptables -N intra_in # TCP, Internes Netz --> Rechner: # ftp - 21 # smtp - 25 # dns - 53 # http - 80 # http-proxy - 3128 iptables -A intra_in -p TCP --dport 1080 -j my_counter iptables -A intra_in -p TCP --syn --sport $UNPRIV \ -m multiport --dports 21,22,25,53,80,3128 -j ACCEPT ######### UDP, Intranet --> Rechner: # time - 37 # dns - 53 # dhcp - 67 iptables -A intra_in -p UDP --sport $UNPRIV -m multiport --dports 37,53,67 \ -j ACCEPT iptables -A intra_in -j my_drop #################################################################################### # # # INTERNE Verbindungen Rechner --> INTRA (OUTPUT Interface $LAN) # # # #################################################################################### # In diese Chain kommt alles mit OUTPUT-Interface $LAN iptables -N intra_out ### TCP, Rechner --> Internes Netz: ### # ssh - 22 # ident - 113 iptables -A intra_out -p TCP --syn --sport $UNPRIV -m multiport --dports 22,113 \ -j ACCEPT ### UDP, Rechner --> Internes Netz: ### # dhcp - 67 # syslog - 514, zum Loghost iptables -A intra_out -p UDP -d 192.168.0.1 --sport 514 --dport 514 -j ACCEPT # anscheinend funktioniert bei DHCP das Connection Tracking nicht richtig, # da das erste Packet von 0.0.0.0 kommt, die Antwort aber an eine # bestimmte IP-Nummer geht. Daher noch folgende Regel: iptables -A intra_out -p UDP --sport 67 -j ACCEPT iptables -A intra_out -j my_drop #################################################################################### # # # IPSec # # # #################################################################################### iptables -N ipsec_for # forwarding von Paketen aus dem Tunnel und zurück iptables -A ipsec_for -i $DSL -o $LAN -m mark --mark 10 -j ACCEPT # Oder mit dem Policy-Modul, was den Vorteil hat, dass man auch den # Traffic in den Tunnel kontrollieren kann, d.h. Verbindungen vom # Gateway zum Roadwarrior möglich sind: # iptables -A FORWARD -i $DSL -m policy --dir in --pol ipsec \ # --mode tunnel --proto esp -j ACCEPT # iptables -A FORWARD -o $DSL -m policy --dir out --pol ipsec \ # --mode tunnel --proto esp -j ACCEPT iptables -A ipsec_for -j my_drop #################################################################################### # # ### --- Ende benutzerdefinierte Chains --- ### # # #################################################################################### #################################################################################### # # # Allgemeine Regeln # # # #################################################################################### # Umleitung auf ftp-Proxy: # FTP iptables -A PREROUTING -t nat -p tcp -i $LAN -d 0/0 --dport 21 -j REDIRECT # IPSec-Pakete markieren: # (Kann auch entfallen, siehe bei ipsec-Abschnitt) iptables -t mangle -A PREROUTING -p 50 -i $DSL -j MARK --set-mark 10 ######### Generelle Regeln für Folgepakete (2. und alle weiteren) ################## # INPUT-Chain iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # OUTPUT-Chain iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # FORWARD-Chain iptables -A FORWARD -i $DSL -o $LAN -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -o $DSL -i $LAN -m state --state ESTABLISHED,RELATED -j ACCEPT #################################################################################### # # # ICMP # # # #################################################################################### ######### ICMP # ICMP ping: 8 und 0 ausgehend erlaubt, alle Interfaces iptables -A OUTPUT -p ICMP --icmp-type echo-request -j ACCEPT iptables -A INPUT -p ICMP --icmp-type echo-reply -j ACCEPT # ICMP ping: 8 und 0 eingehend auf eth+ erlaubt iptables -A INPUT -p ICMP -i $LAN --icmp-type echo-request -j ACCEPT iptables -A OUTPUT -p ICMP -o $LAN --icmp-type echo-reply -j ACCEPT # ICMP ping: 8 und 0 eingehend auf DSL-Karte in Grenzen erlaubt iptables -A INPUT -p ICMP -i $DSL \ -m limit --limit 5/s --icmp-type echo-request -j ACCEPT iptables -A INPUT -p ICMP -i $DSL --icmp-type echo-request -j my_drop iptables -A OUTPUT -p ICMP -o $DSL --icmp-type echo-reply -j ACCEPT ######### Die folgenden Typen sollten eigentlich durch den Parameter RELATED # des Modules state abgedeckt sein: # ICMP source quench 4 #iptables -A OUTPUT -p ICMP --icmp-type source-quench -j ACCEPT #iptables -A INPUT -p ICMP --icmp-type source-quench -j my_drop # ICMP time exceeded 11 #iptables -A OUTPUT -p ICMP --icmp-type time-exceeded -j ACCEPT #iptables -A INPUT -p ICMP --icmp-type time-exceeded -j ACCEPT # ICMP parameter problem 12 #iptables -A OUTPUT -p ICMP --icmp-type parameter-problem -j ACCEPT #iptables -A INPUT -p ICMP --icmp-type parameter-problem -j ACCEPT # ICMP destination unreachable 3 #iptables -A OUTPUT -p ICMP --icmp-type fragmentation-needed -j ACCEPT #iptables -A INPUT -p ICMP --icmp-type fragmentation-needed -j ACCEPT #iptables -A OUTPUT -p ICMP --icmp-type port-unreachable -j ACCEPT #iptables -A INPUT -p ICMP --icmp-type port-unreachable -j ACCEPT #################################################################################### # # # Verteilung auf die jeweiligen benutzerdefinierten Chains # # # #################################################################################### iptables -A INPUT -i $LAN -j intra_in iptables -A INPUT -i $DSL -p 50 -j ACCEPT iptables -A INPUT -i $DSL -j internet_in iptables -A OUTPUT -o $DSL -j internet_out iptables -A OUTPUT -o $LAN -j intra_out iptables -A FORWARD -i $DSL -m mark --mark 10 -j ipsec_for # oder, falls im ipsec-Abschnitt mit -m policy gearbeitet wird: # iptables -A FORWARD -i $DSL -j ipsec_for # iptables -A FORWARD -o $DSL -j ipsec_for ######### Alles was bis hierher kam wird gelogged und dann verworfen bzw. nur zurckgewiesen. iptables -A INPUT -j my_drop iptables -A FORWARD -j my_drop iptables -A OUTPUT -j my_drop echo -n "Die Packet-Filter-Regeln sind jetzt gesetzt." # Remember status and be verbose rc_status -v ;; stop) echo "Die Packet-Filter-Regeln werden gelöscht ... " iptables -F iptables -t nat -F iptables -X iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT echo -n "Die Packet-Filter-Regeln erlauben jetzt wieder alles." echo 0 > /proc/sys/net/ipv4/ip_forward echo -n "Routing ist ausgeschaltet." # Remember status and be verbose rc_status -v ;; status) echo "Die Filterregeln: " iptables -v -n -L iptables -v -n -t nat -L POSTROUTING iptables -v -n -t nat -L PREROUTING # Status has a slightly different for the status command: # 0 - service running # 1 - service dead, but /var/run/ pid file exists # 2 - service dead, but /var/lock/ lock file exists # 3 - service not running # NOTE: checkproc returns LSB compliant status values. #checkproc $FOO_BIN #rc_status -v ;; *) echo "Usage: $0 {start|restart|reload|stop|status}" exit 1 ;; esac rc_exit