# # Konfigurationsscript eines Firewalls auf einem Rechner # der als Router mit NAT Unterstuetzung arbeitet # # Gestartet wird diese Datei mit Hilfe der /etc/rc.d/init.d/firewall # Description: Script zum Konfigurieren einer IPTABLES Firewall # Autor: Sven Neukirchner # mit Hilfe von Newsgroups und Beispielen aus dem Internet # Date 01.09.2004 # Version: 1.1 # Lizenz: GPL # # Inhalt aller Chains loeschen ist nicht notwendig da das schon im Startscript # /etc/rc.d/init.d/firewall durchgefuehrt wird # ################################################################################# #--- Hier werden ein paar Einstellungen vorgenommen ----------------------------# ################################################################################# # meine beiden Netzwerkkarten EXTERN="ppp0" INTERN="eth0" #--- Aktivierung der verwendeten Dienste ------------------------------ # TCP Dienste die auf dem Gateway laufen TCP_SERVICES_IN="22 " # UDP Dienste die auf dem Gateway laufen UDP_SERVICES_IN="" # erlaubte ICMP Typen zum Gateway ICMP_IN="8" # TCP Dienste die das Gateway im Internet nutzt TCP_SERVICES_OUT="20 21 22 25 53 80 110" # UDP Dienste die das Gateway im Internet nutzt UDP_SERVICES_OUT="53" # TCP Dienste die Netwerkclients im Internet nutzen TCP_SNAT="20 21 22 25 53 80 110 443 " # UDP Dienste die Netwerkclients im Internet nutzen UDP_SNAT="53 " # ICMP darf mein Netzwerk verlassen # ICMP Antworen von ausserhalb sind erlaubt # DNAT zu einen CLIENT im Netzwerk DNAT=0 # DNAT zu einem Rechner aktivieren? (1 = an; 0 = aus) LOG_DNAT=0 # Protokollierung an/aus DNAT_IP=192.168.255.89 # IP Adresse des CLIENT TCP_DNAT="80" # TCP PORTS UDP_DNAT="" # UDP PORTS # gesamten TCP und UDP Verkehr nach aussen zulassen OUT_SNAT=0 #--- Protokollierung ein oder auschalten (1 = an; 0 = aus) ------------- LOG_INVALID=0 # ungültige Packete (von aussen) LOG_STEALTH=0 # versteckte Scans (von aussen) LOG_SPOOFING=0 # gespoofte Packete (von aussen) LOG_ICMP=0 # nicht erwuenschte ICMP Packete (von aussen) LOG_UDP=0 # nicht erwuenschte UDP Packete (von aussen) LOG_TCP=0 # nicht erwuenschte TCP Packete (von aussen) # diese Protokollierung nur zur Fehlersuche verwenden da hohes LOG aufkommen LOG_FORWARD=0 # Verkehr auf FORWARD Kette protokollieren (wenn mal was nicht geht) LOG_INTERN=0 # Verkehr auf internen Interface protokollieren (wenn mal was nicht geht) LOG_EXTERN=0 # Verkehr auf externen Interface protokollieren (wenn mal was nicht geht) # Verkehr zwischen eines Clients im Netzwerk und Gateway beobachten (wenn mal was nicht geht) LOG_CLIENT_INT=0 # 0 = aus; 1 = an CLIENT_IP_INT="192.168.0.5" # IP Adresse des Clients # Internetverkehr (FORWARD) eines Clients im Netzwerk beobachten (wenn mal was nicht geht) LOG_CLIENT_FW=0 # 0 = aus; 1 = an CLIENT_IP_FW="192.168.255.19" # IP Adresse des Clients ####################################################################################### #--- Ab hier bitte keine Aenderungen mehr vornehmen - oder Du weisst was Du machst ---# ####################################################################################### #------------------------------------------------------------------------# #---POLICY setzen--------------------------------------------------------# #------------------------------------------------------------------------# echo " Schliesse Firewall..." # erst mal alles dicht machen iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP #------------------------------------------------------------------------# #--- KERNEL Schutzmechanismen aktivieren---------------------------------# #------------------------------------------------------------------------# echo " Aktiviere Kernel Schutzmechanismen..." # IP Forwarding einschalten echo 1 > /proc/sys/net/ipv4/ip_forward #--- ICMP Schutz ---------------------------------------# # ICMP Echo-Broadcasts ignorieren echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts 2> /dev/null # Ungültige ICMP-Antworten ignorieren echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses 2> /dev/null #--- TCP Verbindungs Schutz ---------------------------------------# # max Anzahl von nicht mehr verbunden Sockets die im Kernel verbleiben #echo 0 > /proc/sys/net/ipv4/tcp_max_orphans # max Wiederholungen fuer Verbindungen die ich geschlossen aber kein ACK bekommen habe #echo 15 > /proc/sys/net/ipv4/tcp_orphan_retries # Zeit wie lange Sockets die geschlossen sind erhalten bleiben echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout # max Antworten auf ein TCP-SYN echo 3 > /proc/sys/net/ipv4/tcp_retries1 # max Wiederholungen fuer bekannte Verbindungen bevor abgebrochen wird echo 15 > /proc/sys/net/ipv4/tcp_retries2 # Schutz vor SYN-flood echo 1 > /proc/sys/net/ipv4/tcp_syncookies 2> /dev/null #--- Fragmentierung ---------------------------------------# # max Speichergroesse fuer IP-Defragmentierung (max 256kb min 192kb) echo 262144 > /proc/sys/net/ipv4/ipfrag_high_thresh echo 196608 > /proc/sys/net/ipv4/ipfrag_low_thresh # max Zeit in s wie lange IP Fragmente im Speicher bleiben echo 30 > /proc/sys/net/ipv4/ipfrag_time #--- TCP Spoofing Schutz ---------------------------------------# # Stop Source-Routing (Absender kann Route eines Packets nicht vorgeben) echo 0 > /proc/sys/net/ipv4/conf/$EXTERN/accept_source_route # Reverse-Path-Filter (Antwortpacket muss durch selbe Schnittstelle wie # Senderpacket nur bei mehereren Schnittstellen notwendig) echo 2 > /proc/sys/net/ipv4/conf/$EXTERN/rp_filter # Stop Redirecting (Router kann mir keine anderer Route fuer ein Packet vorgeben) echo 0 > /proc/sys/net/ipv4/conf/$EXTERN/accept_redirects #--- ARP Schutz ------------------------------------------------# # ARP Adressen werden nicht geaendert wenn ein existierender Eintrag juenger als # Jiffie Wert ist (100 jiffie = 1 Sekunde) echo 1000 > /proc/sys/net/ipv4/neigh/$EXTERN/locktime # Proxy-ARP ausschalten (Rechner liefert keine Hardwareadressen von anderen Rechner) echo 0 > /proc/sys/net/ipv4/conf/$EXTERN/proxy_arp #--- sonstiges -------------------------------------------------# # Log Martians (Packete deren Route nicht ermittelt werden kann werden Protokolliert) echo 1 > /proc/sys/net/ipv4/conf/$EXTERN/log_martians # BOOTP-Relaying ausschalten echo 0 > /proc/sys/net/ipv4/conf/$EXTERN/bootp_relay #------------------------------------------------------------------------# #--- wenn LOG Optionen gesetzt sind -------------------------------------# #------------------------------------------------------------------------# if [ $LOG_INTERN = 1 ] then iptables -A INPUT -i $INTERN -p TCP -j LOG --log-tcp-options --log-prefix "von INTERN " iptables -A OUTPUT -o $INTERN -p TCP -j LOG --log-tcp-options --log-prefix "zu INTERN " fi if [ $LOG_EXTERN = 1 ] then iptables -A INPUT -i $EXTERN -p TCP -j LOG --log-tcp-options --log-prefix "von EXTERN " iptables -A OUTPUT -o $EXTERN -p TCP -j LOG --log-tcp-options --log-prefix "zu EXTERN " fi if [ $LOG_FORWARD = 1 ] then iptables -A FORWARD -i $INTERN -p TCP -j LOG --log-tcp-options --log-prefix "FORWARD vom INTERN " iptables -A FORWARD -i $EXTERN -p TCP -j LOG --log-tcp-options --log-prefix "FORWARD von EXTERN " fi if [ $LOG_CLIENT_INT = 1 ] then iptables -A INPUT -i $INTERN -p TCP -s $CLIENT_IP_INT -j LOG --log-tcp-options --log-prefix "INT zu CLIENT " iptables -A OUTPUT -o $INTERN -p TCP -d $CLIENT_IP_INT -j LOG --log-tcp-options --log-prefix "INT von CLIENT " iptables -A INPUT -i $INTERN -p UDP -s $CLIENT_IP_INT -j LOG --log-tcp-options --log-prefix "INT zu CLIENT " iptables -A OUTPUT -o $INTERN -p UDP -d $CLIENT_IP_INT -j LOG --log-tcp-options --log-prefix "INT von CLIENT " iptables -A INPUT -i $INTERN -p ICMP -s $CLIENT_IP_INT -j LOG --log-tcp-options --log-prefix "INT zu CLIENT " iptables -A OUTPUT -o $INTERN -p ICMP -d $CLIENT_IP_INT -j LOG --log-tcp-options --log-prefix "INT von CLIENT " fi if [ $LOG_CLIENT_FW = 1 ] then iptables -A FORWARD -i $EXTERN -p TCP -d $CLIENT_IP_FW -j LOG --log-tcp-options --log-prefix "FW zu CLIENT " iptables -A FORWARD -i $EXTERN -p UDP -d $CLIENT_IP_FW -j LOG --log-tcp-options --log-prefix "FW zu CLIENT " iptables -A FORWARD -i $EXTERN -p ICMP -d $CLIENT_IP_FW -j LOG --log-tcp-options --log-prefix "FW zu CLIENT " iptables -A FORWARD -i $INTERN -p TCP -s $CLIENT_IP_FW -j LOG --log-tcp-options --log-prefix "FW von CLIENT " iptables -A FORWARD -i $INTERN -p UDP -s $CLIENT_IP_FW -j LOG --log-tcp-options --log-prefix "FW von CLIENT " iptables -A FORWARD -i $INTERN -p ICMP -s $CLIENT_IP_FW -j LOG --log-tcp-options --log-prefix "FW von CLIENT " fi #------------------------------------------------------------------------# #--- eigene Ketten erstellen --------------------------------------------# #------------------------------------------------------------------------# echo " Erstelle eigene Ketten..." #--- LOG-DROP Ketten erstellen ---------------------------------------# # Kette fuer ungueltige Packete iptables -N INVALID_DROP if [ $LOG_INVALID = 1 ] then iptables -A INVALID_DROP -j LOG --log-tcp-options --log-prefix "INVALID " fi iptables -A INVALID_DROP -j DROP # Kette fuer Stealth Scans iptables -N STEALTH_DROP if [ $LOG_STEALTH = 1 ] then iptables -A STEALTH_DROP -j LOG --log-tcp-options --log-prefix "STEALTH " fi iptables -A STEALTH_DROP -j DROP # Kette fuer Spoofing Packete iptables -N SPOOFING_DROP if [ $LOG_SPOOFING = 1 ] then iptables -A SPOOFING_DROP -j LOG --log-tcp-options --log-prefix "SPOOF " fi iptables -A SPOOFING_DROP -j DROP # Kette fuer ICMP iptables -N ICMP_DROP if [ $LOG_ICMP = 1 ] then iptables -A ICMP_DROP -j LOG --log-tcp-options --log-prefix "ICMP " fi iptables -A ICMP_DROP -j DROP # Kette fuer UDP iptables -N UDP_DROP if [ $LOG_UDP = 1 ] then iptables -A UDP_DROP -j LOG --log-tcp-options --log-prefix "UDP " fi iptables -A UDP_DROP -j DROP # Kette fuer neue Verbindung iptables -N TCP_DROP if [ $LOG_TCP = 1 ] then iptables -A TCP_DROP -j LOG --log-tcp-options --log-prefix "TCP " fi iptables -A TCP_DROP -j DROP #--- Schutz Ketten erstellen ------------------------------------------# # Korrupte Pakete zurueckweisen iptables -A INPUT -m state --state INVALID -j INVALID_DROP iptables -A OUTPUT -m state --state INVALID -j INVALID_DROP iptables -A FORWARD -m state --state INVALID -j INVALID_DROP # Schutz vor IP Spoofing ( Senderadresse ist privat) iptables -N PRIVAT iptables -F PRIVAT iptables -A PRIVAT -s 127.0.0.0/8 -j SPOOFING_DROP # Loopback iptables -A PRIVAT -s 10.0.0.0/8 -j SPOOFING_DROP # privates Klasse A Netz iptables -A PRIVAT -s 172.16.0.0/12 -j SPOOFING_DROP # privates Klasse B Netz iptables -A PRIVAT -s 192.168.0.0/16 -j SPOOFING_DROP # privates Klasse V Netz iptables -A PRIVAT -s 224.0.0.0/4 -j SPOOFING_DROP # reservierte Multicastadressen iptables -A PRIVAT -s 240.0.0.0/4 -j SPOOFING_DROP # reservierte Adressen # Schutz vor IP Stealth Scans iptables -N STEALTH iptables -F STEALTH iptables -A STEALTH -p tcp --tcp-flags ALL NONE -j STEALTH_DROP # kein Flag gesetzt iptables -A STEALTH -p tcp --tcp-flags SYN,FIN SYN,FIN -j STEALTH_DROP # SYN und FIN gesetzt iptables -A STEALTH -p tcp --tcp-flags FIN,RST FIN,RST -j STEALTH_DROP # FIN und RST gesetzt iptables -A STEALTH -p tcp --tcp-flags ACK,FIN FIN -j STEALTH_DROP # FIN ohne ACK iptables -A STEALTH -p tcp --tcp-flags ACK,PSH PSH -j STEALTH_DROP # PSH ohne ACK iptables -A STEALTH -p tcp --tcp-flags ACK,URG URG -j STEALTH_DROP # URG ohne ACK # Allgemeine Regeln fuer TCP iptables -N TCP_CHAIN iptables -F TCP_CHAIN iptables -A TCP_CHAIN -p TCP --syn -j TCP_DROP # TCP Status SYN (Verbindungsanfrage) iptables -A TCP_CHAIN -p TCP -m state --state NEW -j TCP_DROP # Verbindungsstatus neues Packet iptables -A TCP_CHAIN -p TCP ! --syn -m state --state NEW -j TCP_DROP # nicht SYN aber neu ???? Sachen gibts... #Allgemeine Regeln fuer UDP iptables -N UDP_CHAIN iptables -F UDP_CHAIN iptables -A UDP_CHAIN -p UDP -j UDP_DROP # alles andere weg # Allgemeine Regeln fuer ICMP iptables -N ICMP_CHAIN iptables -F ICMP_CHAIN iptables -A ICMP_CHAIN -p ICMP -m state --state ESTABLISHED -j ACCEPT # bekannte Verbindungen sind OK iptables -A ICMP_CHAIN -p ICMP -j ICMP_DROP # alles andere weg #--- Schutz Ketten aktivieren -----------------------------------------# # Weitergabe an Spoofing Regel iptables -A INPUT -i $EXTERN -j PRIVAT iptables -A FORWARD -i $EXTERN -j PRIVAT # Weitergabe an Stealth Regel iptables -A INPUT -i $EXTERN -j STEALTH iptables -A FORWARD -i $EXTERN -j STEALTH #------------------------------------------------------------------------# #--- INTERNER NETZVERKEHR------------------------------------------------# #------------------------------------------------------------------------# echo " Konfiguriere Interface $INTERN..." # Kommunikation Auf Loopback iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # Kommunikation interner Netzwerkkarte iptables -A INPUT -i $INTERN -j ACCEPT iptables -A OUTPUT -o $INTERN -j ACCEPT #------------------------------------------------------------------------# #--- EXTERNER NETZVERKEHR------------------------------------------------# #------------------------------------------------------------------------# echo " Konfiguriere Interface $EXTERN..." #--- Verbindungen die rein duerfen ------------------------------------ # erlaubte TCP Nachrichten zum Gateway for port_range in $TCP_SERVICES_IN ; do iptables -A INPUT -i $EXTERN -p tcp --dport $port_range -j LOG --log-prefix "IN GATEWAY " --log-level 6 -m limit --limit 3/m iptables -A INPUT -i $EXTERN -p tcp --dport $port_range -j ACCEPT iptables -A OUTPUT -o $EXTERN -p tcp --sport $port_range -m state --state ESTABLISHED -j ACCEPT done # erlaubte UDP Nachrichten zum Gateway for port_range in $UDP_SERVICES_IN ; do iptables -A INPUT -i $EXTERN -p udp --dport $port_range -j LOG --log-prefix "IN GATEWAY " --log-level 6 -m limit --limit 3/m iptables -A INPUT -i $EXTERN -p udp --dport $port_range -j ACCEPT iptables -A OUTPUT -o $EXTERN -p udp --sport $port_range -m state --state ESTABLISHED -j ACCEPT done # erlaubte ICMP Nachrichten zum Gateway for icmp_type in $ICMP_IN ; do iptables -A INPUT -i $EXTERN -p icmp --icmp-type $icmp_type -j ACCEPT iptables -A OUTPUT -o $EXTERN -p icmp --icmp-type $icmp_type -m state --state ESTABLISHED -j ACCEPT done #--- Dienste das Gateway im Internet nutzen -------------------# # definierte TCP Dienste im Internet for port_range in $TCP_SERVICES_OUT ; do iptables -A OUTPUT -o $EXTERN -p tcp --dport $port_range -j ACCEPT iptables -A INPUT -i $EXTERN -p tcp --sport $port_range -m state --state ESTABLISHED -j ACCEPT done # definierte UDP Dienste im Internet for port_range in $UDP_SERVICES_OUT ; do iptables -A OUTPUT -o $EXTERN -p udp --dport $port_range -j ACCEPT iptables -A INPUT -i $EXTERN -p udp --sport $port_range -m state --state ESTABLISHED -j ACCEPT done # ICMP darf raus iptables -A OUTPUT -o $EXTERN -p ICMP -j ACCEPT #--- FTP nach aussen ermoeglichen ------------------------------------- # aktives FTP iptables -A INPUT -i $EXTERN -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -o $EXTERN -p tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT # passives FTP iptables -A INPUT -i $EXTERN -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED -j ACCEPT iptables -A OUTPUT -o $EXTERN -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT #--- Regeln fuer den restlichen Verkehr ------------------------------ # Weitergabe an TCP UDP und ICMP Kette iptables -A INPUT -i $EXTERN -j TCP_CHAIN iptables -A INPUT -i $EXTERN -j UDP_CHAIN iptables -A INPUT -i $EXTERN -j ICMP_CHAIN #------------------------------------------------------------------------# #--- FORWARD KETTE-------------------------------------------------------# #------------------------------------------------------------------------# echo " Konfiguriere NAT..." # wichtig bei T-DSL iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # Packete fuer Detination NAT maskieren iptables -t nat -A POSTROUTING -o $EXTERN -j MASQUERADE #--- Dienste die Netzwerkclients im Internet nutzen -------------------# # definierte TCP Dienste im Internet for port_range in $TCP_SNAT ; do iptables -A FORWARD -i $INTERN -p tcp --dport $port_range -j ACCEPT iptables -A FORWARD -i $EXTERN -p tcp --sport $port_range -m state --state ESTABLISHED -j ACCEPT done # definierte UDP Dienste im Internet for port_range in $UDP_SNAT ; do iptables -A FORWARD -i $INTERN -p udp --dport $port_range -j ACCEPT iptables -A FORWARD -i $EXTERN -p udp --sport $port_range -m state --state ESTABLISHED -j ACCEPT done # ICMP darf raus iptables -A FORWARD -i $INTERN -p ICMP -j ACCEPT # gesamter TCP und UDP Verkehr nach aussen if [ $OUT_SNAT = 1 ] then iptables -A FORWARD -i $INTERN -j ACCEPT iptables -A FORWARD -i $EXTERN -p tcp -m state --state ESTABLISHED -j ACCEPT iptables -A FORWARD -i $EXTERN -p udp -m state --state ESTABLISHED -j ACCEPT fi #--- FTP nach aussen ermoeglichen -------------------------------------- # aktives FTP iptables -A FORWARD -i $EXTERN -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -i $EXTERN -p tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT # passives FTP iptables -A FORWARD -i $EXTERN -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED -j ACCEPT iptables -A FORWARD -i $INTERN -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT #--- DNAT zu einem CLIENT --------------------------------- if [ $DNAT = 1 ] then if [ $LOG_DNAT = 1 ] then for port_range in $TCP_DNAT ; do iptables -t nat -A PREROUTING -i $EXTERN -p TCP --dport $port_range -j LOG --log-prefix "DNAT " --log-level 6 iptables -A FORWARD -i $EXTERN -d $DNAT_IP -p TCP --dport $port_range -j LOG --log-prefix "DNAT " --log-level 6 iptables -A FORWARD -i $INTERN -s $DNAT_IP -p TCP --sport $port_range -j LOG --log-prefix "DNAT " --log-level 6 done for port_range in $UDP_DNAT ; do iptables -t nat -A PREROUTING -i $EXTERN -p UDP --dport $port_range -j LOG --log-prefix "DNAT " --log-level 6 iptables -A FORWARD -i $EXTERN -d $DNAT_IP -p UDP --dport $port_range -j LOG --log-prefix "DNAT " --log-level 6 iptables -A FORWARD -i $INTERN -s $DNAT_IP -p UDP --sport $port_range -j LOG --log-prefix "DNAT " --log-level 6 done fi for port_range in $TCP_DNAT ; do iptables -t nat -A PREROUTING -i $EXTERN -p TCP --dport $port_range -j DNAT --to $DNAT_IP iptables -A FORWARD -i $EXTERN -d $DNAT_IP -p TCP --dport $port_range -j ACCEPT iptables -A FORWARD -i $INTERN -s $DNAT_IP -p TCP --sport $port_range -j ACCEPT done for port_range in $UDP_DNAT ; do iptables -t nat -A PREROUTING -i $EXTERN -p UDP --dport $port_range -j DNAT --to $DNAT_IP iptables -A FORWARD -i $EXTERN -d $DNAT_IP -p UDP --dport $port_range -j ACCEPT iptables -A FORWARD -i $INTERN -s $DNAT_IP -p UDP --sport $port_range -j ACCEPT done fi #--- Regeln fuer den restlichen Verkehr ------------------------------- if [ $OUT_SNAT = 1 ] then iptables -A FORWARD -i $INTERN -p udp -j ACCEPT iptables -A FORWARD -i $INTERN -p tcp -j ACCEPT fi # Weitergabe an TCP UDP und ICMP Kette iptables -A FORWARD -i $EXTERN -j TCP_CHAIN iptables -A FORWARD -i $EXTERN -j UDP_CHAIN iptables -A FORWARD -i $EXTERN -j ICMP_CHAIN ################## ENDE FIREWALL ########################################