Debian Iptables
Allgemein
Falls der Debian-Server hinter einem DSL-Router mit aktivierter Firewall hängt, ist dieser bereits relativ gut gegen Angriffe aus dem Internet abgeschirmt. Dennoch sind sog. Brute-Force-Attacken gegen die Serverdienste wie z.B. [Debian_OpenSSH|SSH]], FTP- und Webserver sowie aus dem Internet erreichbare Mailserver möglich. Dabei wird meist per automatisch ablaufenden Scripts versucht, Passwörter mittels Durchprobieren zu ermitteln. Um dies zu unterbinden, wird die Linux-Standardfirewall "iptables" (http://www.netfilter.org) aktiviert. On Top wird Fail2ban (http://fail2ban.org) installiert, mit dessen Hilfe es möglich ist, IP-Adressen von Angreifern, die mehrmals ein Passwort z.B des FTP-Server falsch eingegben haben, komplett auszusperren. Eine erneute Anmeldung ist erst nach einer frei definierbaren Zeit wieder möglich.
Installation von iptables
Iptables ist normalerweise unter Debian bereits installiert. Falls nicht, dies nun nachholen:
apt-get update apt-get install iptables
Zum aktivieren der Firewall wird noch ein Satz von Firewall-Regeln benötigt. Als Startpunkt kann das folgende Script verwendet werden, bei dem Regeln für die in den Howtos beschriebenen Programme enthält, die standardmäßig auskommentiert sind.
vi /etc/init.d/iptables
Folgende Zeilen einfügen:
#!/bin/sh ############################################################################### # # Local Settings # # IPTables Location - adjust if needed IPT="/sbin/iptables" IPTS="/sbin/iptables-save" IPTR="/sbin/iptables-restore" # Internet Interface INET_IFACE="eth0" # CHANGE THIS TO MATCH YOUR SERVER IP ADDRESS # currently not used INET_ADDRESS="192.168.0.219" # Localhost Interface LO_IFACE="lo" LO_IP="127.0.0.1" # Save and Restore arguments handled here if [ "$1" = "save" ] then echo -n "Saving firewall to /etc/iptables ... " $IPTS > /etc/iptables echo "done" exit 0 elif [ "$1" = "restore" ] then echo -n "Restoring firewall from /etc/iptables ... " $IPTR < /etc/iptables echo "done" exit 0 fi # Flush Any Existing Rules or Chains echo "Flushing Tables ..." # Reset Default Policies $IPT -P INPUT ACCEPT $IPT -P FORWARD ACCEPT $IPT -P OUTPUT ACCEPT # Flush all rules $IPT -F # Erase all non-default chains $IPT -X if [ "$1" = "stop" ] then echo "Firewall completely flushed! Now running with no firewall." exit 0 fi ############################################################################### # Rules Configuration # Filter Table # Set Policies $IPT -P INPUT DROP $IPT -P OUTPUT DROP $IPT -P FORWARD DROP # User-Specified Chains echo "Create and populate custom rule chains ..." # Create a chain to filter INVALID packets $IPT -N bad_packets # Create another chain to filter bad tcp packets $IPT -N bad_tcp_packets # Create separate chains for icmp, tcp (incoming and outgoing), # and incoming udp packets. $IPT -N icmp_packets # Used for UDP packets inbound from the Internet $IPT -N udp_inbound # Used to block outbound UDP services from internal network # Default to allow all $IPT -N udp_outbound # Used to allow inbound services if desired # Default fail except for established sessions $IPT -N tcp_inbound # Used to block outbound services from internal network # Default to allow all $IPT -N tcp_outbound # Populate User Chains # bad_packets chain # Drop INVALID packets immediately # needs conntrack #$IPT -A bad_packets -p ALL -m state --state INVALID -j DROP # Then check the tcp packets for additional problems $IPT -A bad_packets -p tcp -j bad_tcp_packets # All good, so return $IPT -A bad_packets -p ALL -j RETURN # bad_tcp_packets chain # # All tcp packets will traverse this chain. # Every new connection attempt should begin with # a syn packet. If it doesn't, it is likely a # port scan. This drops packets in state # NEW that are not flagged as syn packets. # needs conntrack #$IPT -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \ #--log-prefix "New not syn: " #$IPT -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP # Stealth scans $IPT -A bad_tcp_packets -p tcp --tcp-flags ALL NONE -j DROP $IPT -A bad_tcp_packets -p tcp --tcp-flags ALL ALL -j DROP $IPT -A bad_tcp_packets -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP $IPT -A bad_tcp_packets -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP $IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,RST SYN,RST -j DROP $IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP # All good, so return $IPT -A bad_tcp_packets -p tcp -j RETURN # icmp_packets chain # ICMP packets should fit in a Layer 2 frame, thus they should # never be fragmented. Fragmented ICMP packets are a typical sign # of a denial of service attack. #$IPT -A icmp_packets --fragment -p ICMP -j LOG \ #--log-prefix "ICMP Fragment: " $IPT -A icmp_packets --fragment -p ICMP -j DROP # Echo - uncomment to allow your system to be pinged. # Uncomment the LOG command if you also want to log PING attempts # # $IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j LOG \ # --log-prefix "Ping detected: " $IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT # comment out above and uncomment below to drop pings without logging. #$IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j DROP # see ping reply packets $IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 0 -j ACCEPT # Time Exceeded $IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT # Not matched, so return so it will be logged $IPT -A icmp_packets -p ICMP -j RETURN # TCP & UDP # Identify ports at: # http://www.chebucto.ns.ca/~rakerman/port-table.html # http://www.iana.org/assignments/port-numbers # # ADD UDP-based services here # # udp_inbound chain # ports you want to accept udp packets on # netbios/samba $IPT -A udp_inbound -p UDP -s 0/0 --destination-port 137 -j ACCEPT $IPT -A udp_inbound -p UDP -s 0/0 --destination-port 138 -j ACCEPT # Network Time Protocol (NTP) Server $IPT -A udp_inbound -p UDP -s 0/0 --destination-port 123 -j ACCEPT # External DHCP Server # Allow DHCP client request packets inbound from external network $IPT -A udp_inbound -p UDP -s 0/0 --source-port 68 --destination-port 67 -j ACCEPT # DNS in #$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 53 -j ACCEPT $IPT -A udp_inbound -p UDP -s 0/0 --source-port 53 -j ACCEPT # Not matched, so return for logging $IPT -A udp_inbound -p UDP -j RETURN # udp_outbound chain # all udp outbound traffic will be accepted $IPT -A udp_outbound -p UDP -s 0/0 -j ACCEPT # tcp_inbound chain # # This chain is used to allow inbound connections to the SLUG # smb $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 137 -j ACCEPT $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 139 -j ACCEPT $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 445 -j ACCEPT # HTTP #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 80 -j ACCEPT #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 443 -j ACCEPT # Webmin #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 10000 -j ACCEPT # Funambol #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 8080 -j ACCEPT #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 8443 -j ACCEPT # FTP #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port ftp -j ACCEPT # Passive FTP #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 60019:60049 -j ACCEPT # DNS $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 53 -j ACCEPT # sshd $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 22 -j ACCEPT #smtp #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 25 -j ACCEPT #IMAPd #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 143 -j ACCEPT #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 993 -j ACCEPT #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 406 -j ACCEPT #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 674 -j ACCEPT #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 2000 -j ACCEPT #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 2003 -j ACCEPT #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 4201 -j ACCEPT #CUPS #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 631 -j ACCEPT #SIS-PM #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 2638 -j ACCEPT # Not matched, so return so it will be logged $IPT -A tcp_inbound -p TCP -j RETURN # tcp_outbound chain # all outbound traffic will be accepted $IPT -A tcp_outbound -p TCP -s 0/0 -j ACCEPT ############################################################################### # INPUT Chain echo "process INPUT chain ..." # Allow all on localhost interface $IPT -A INPUT -p ALL -i $LO_IFACE -j ACCEPT # Drop bad packets $IPT -A INPUT -p ALL -j bad_packets # ****************************** # Inbound Internet Packet Rules # Accept Established Connections # Needs conntrack module # $IPT -A INPUT -p ALL -i $INET_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT # packet filter accepts inbound packets that are replies to an outbound connection # use until conntrack is available # this blocks all new connection attempts except to those allowed below $IPT -A INPUT -p TCP -i $INET_IFACE ! --syn -j ACCEPT # Route the rest to the appropriate user chain $IPT -A INPUT -p TCP -i $INET_IFACE -j tcp_inbound $IPT -A INPUT -p UDP -i $INET_IFACE -j udp_inbound $IPT -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets # Drop without logging broadcasts that get this far. # Comment this line if testing new rules that impact # broadcast protocols. #$IPT -A INPUT -m pkttype --pkt-type broadcast -j DROP ############################################################################### # # OUTPUT Chain # echo "Process OUTPUT chain ..." # Generally trust the firewall on output # However, invalid icmp packets need to be dropped # to prevent a possible exploit. # needs conntrack #$IPT -A OUTPUT -m state -p icmp --state INVALID -j DROP # Localhost $IPT -A OUTPUT -p ALL -s $LO_IP -j ACCEPT $IPT -A OUTPUT -p ALL -o $LO_IFACE -j ACCEPT # If you want to block outbound connections, uncomment first section below, comment # out second section, and add rules to tcp_outbound/udp_outbound # To internet - filtered #$IPT -A OUTPUT -p TCP -o $INET_IFACE -j tcp_outbound #$IPT -A OUTPUT -p UDP -o $INET_IFACE -j udp_outbound # To internet (unfiltered) $IPT -A OUTPUT -p ALL -o $INET_IFACE -j ACCEPT
Firewall-Script ausführbar machen:
chmod +x /etc/init.d(iptables
Konfiguration iptables
Oben angeführtes Script enthält bereits eine Menge an Firewall-Regeln. Einige sind bereits aktiviert, die anderen sind auskommentiert. Standardmäßgi werden alle ausgehenden Datenpakete erlaubt, eingehende nur diejenigen, die explizit freigegeben wurden.
Mailserver
Mailserver arbeiten Standardmäßig mit den Ports 25 (SMTP), 143 (IMAP) und 993 (IMAPS). Zur Freigabe dieser Ports die Kommentarzeichen vor folgenden Zeilen entfernen, die mit #$IPT beginnen:
#smtp #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 25 -j ACCEPT #IMAPd #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 143 -j ACCEPT #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 993 -j ACCEPT #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 406 -j ACCEPT #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 674 -j ACCEPT #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 2000 -j ACCEPT #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 2003 -j ACCEPT #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 4201 -j ACCEPT
Freigabe der Ports je nach Bedarf (z.B. Port 993 nur nötig für SSL-Zugriff auf Cyrus Imap, die anderen Service-ports sollten erlaubt werden:
#smtp $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 25 -j ACCEPT #IMAPd $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 143 -j ACCEPT $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 993 -j ACCEPT $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 406 -j ACCEPT $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 674 -j ACCEPT $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 2000 -j ACCEPT $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 2003 -j ACCEPT $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 4201 -j ACCEPT
Webserver
Die Weboberfläche der NSLU wurde gemäß Anleitung uNSLUng auf Port 8282 gesetzt. Dieser Port wird bereits standardmäßig freigegeben. Falls dem internen Webserver ein anderer Port zugewiesen wurde, bitte den Port entsrechend anpassen. Falls →Webserver installiert wurde, den Port 80 durch auskommentieren der Zeile freigeben:
# HTTP #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 80 -j ACCEPT
Freigeben Port 80 für Webserver:
# HTTP $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 80 -j ACCEPT
FTP-server
FTP verwendet Standardmäßig Port 21 für aktives FTP und einen beliebigen Port >1024 für passives FTP. Hier werden die Ports aus dem Bereich 60019 bis 60049 freigegeben, aus dem sich der FTP-Server einen für die passive Verbindung auswählen kann.
# FTP #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port ftp -j ACCEPT # Passive FTP #$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 60019:60049 -j ACCEPT
FTP-Server freigeben:
# FTP $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port ftp -j ACCEPT # Passive $IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 60019:60049 -j ACCEPT
Funktionscheck
Starten der Firewall-Regeln:
/etc/init.d/iptables start
Es sollte kein Fehler ausgegeben werden und weiterhin Zugriff auf den Server bestehen. Den Zugriff via ssh und alle anderen konfigurierten Services und Server wie Web-, FTP- und Mailserver.
Firewall Autostart
Nachdem im vorhergehenden Schritt sichergestellt wurde, dass alle gewünschten und nötigen Services erreichbar sind, kann die Firewall eingerichtet werden, dass diese bei jedem Neustart des Servers mitstartet.
- Sollte die Firewall automatisch starten, und SSH nicht erreichbar sein, ist keinerlei Zugriff mehr auf die Server möglich, außer es steht lokal Maus- und Tastatur zur Verfügung. D.h. um wieder Zugriff zu erhalten, kann unter Umständen eine komplette Neuinstallation nötig werden. Deshalb unbedingt sicher stellen, dass der Server mindestens via SSH erreichbar ist, BEVOR der folgende Befehl ausgeführt wird.
update-rc.d /etc/init.d/iptables
Installation Fail2ban
apt-get install fail2ban apt-get install whois
Konfiguration fail2ban
TBD