{"id":25,"date":"2019-01-04T15:33:02","date_gmt":"2019-01-04T14:33:02","guid":{"rendered":"https:\/\/blog.steiner.systems\/?p=25"},"modified":"2019-01-04T15:57:14","modified_gmt":"2019-01-04T14:57:14","slug":"simple-firewall-mittels-iptables","status":"publish","type":"post","link":"https:\/\/blog.steiner.systems\/?p=25","title":{"rendered":"Simple Firewall mittels IPtables"},"content":{"rendered":"\n<p>Ein Server ohne Firewall &#8211; kann man mal machen, aber dann ist es halt &#8230;. \ud83d\ude09<\/p>\n\n\n\n<p>Zugegeben, der Grundstock dieses Scripts stammt nicht aus meiner Feder. Ich habe es vor Jahren mal irgendwo gefunden und dann immer wieder angepasst mittlerweile schlummert bei mir auf nahezu jedem Server das folgende Script in einem &#171;script-Verzeichnis&#187; als iptables.sh:<\/p>\n\n\n\n<!--more-->\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\n\n### BEGIN INIT INFO\n# Provides:          iptables-firewall\n# Required-Start:    $local_fs $network\n# Required-Stop:     $local_fs\n# Default-Start:     2 3 4 5\n# Default-Stop:      0 1 6\n# Short-Description: iptables-firewall\n# Description:       iptables-firewall\n### END INIT INFO\n\n#Ports: Hier eintragen welche Ports ge\u00f6ffnet werden sollen\nSERVICES_UDP=\"\"                 #freigegebene UDP-Ports\nSERVICES_TCP=\"22 80 443\"        #freigegebene TCP-Ports (Hier sshd und http\/https)\n\n#Alle vorhandenen Regeln l\u00f6schen\niptables -F\niptables -t nat -F\niptables -t mangle -F\niptables -X\niptables -t nat -X\niptables -t mangle -X\n\n#Grundregeln\niptables -P OUTPUT  ACCEPT\niptables -P INPUT   DROP\niptables -P FORWARD DROP\n\n#Sicherheit\niptables -N other_packets                                                               #Tabelle \"other_packets\" erzeugen\niptables -A other_packets -p ALL -m state --state INVALID -j DROP                       #Kaputte Pakete verwerfen\niptables -A other_packets -p icmp -m limit --limit 1\/s -j ACCEPT                        #ICMP auf max. 1 Paket\/Sekunde limitieren\niptables -A other_packets -p ALL -j RETURN                                              #Tabelle \"other_packets\" verlassen\n\niptables -N service_sec                                                                 #Tabelle \"services_sec\" erzeugen\niptables -A service_sec -p tcp --syn -m limit --limit 2\/s -j ACCEPT                     #SYN-Flood Attacken\niptables -A service_sec -p tcp ! --syn -m state --state NEW -j DROP                     #TCP-SYN-Pakete ohne Status NEW verwerfen\niptables -A service_sec -p tcp --tcp-flags ALL NONE -m limit --limit 1\/h -j ACCEPT      #Portscanner ausschalten\niptables -A service_sec -p tcp --tcp-flags ALL ALL -m limit --limit 1\/h -j ACCEPT       #Portscanner ausschalten\niptables -A service_sec -p ALL -j RETURN                                                #Tabelle \"services\" verlassen\n\niptables -N reject_packets                                                                                                                      #Tabelle \"reject_packets\" erzeugen\niptables -A reject_packets -p tcp -j REJECT --reject-with tcp-reset                     #TCP Pakete(Protokoll) zur\u00fcckweisen\niptables -A reject_packets -p udp -j REJECT --reject-with icmp-port-unreachable         #UDP Pakete(Protokoll) zur\u00fcckweisen\niptables -A reject_packets -p icmp -j REJECT --reject-with icmp-host-unreachable        #ICMP Pakete(Protokoll) zur\u00fcckweisen (bei mehr als 1Paket\/Sekunde [s.o.])\niptables -A reject_packets -j REJECT --reject-with icmp-proto-unreachable               #Alle anderen Pakete(Protokolle) zur\u00fcckweisen\niptables -A reject_packets -p ALL -j RETURN                                             #Tabelle \"reject_packets\" verlassen\n\n#Dienste\niptables -N services                                                                    #Tabelle f\u00fcr die Dienste erzeugen\nfor port in $SERVICES_TCP ; do                                                          #F\u00fcr jeden TCP Port (oben definiert) folgendes tun:\n       iptables -A services -p tcp --dport $port -j service_sec                         #Bei Verbindungen auf TCP Port \"$port in die Tabelle \"services_sec\" springen\n       iptables -A services -p tcp --dport $port -j ACCEPT                              #Bei Verbindungen auf TCP Port \"$port Verbindung zulassen\ndone\nfor port in $SERVICES_UDP ; do                                                          #F\u00fcr jeden UDP Port (oben definiert) folgendes tun:\n       iptables -A services -p udp --dport $port -j service_sec                         #Bei Verbindungen auf UDP Port \"$port\" in die Tabelle \"services_sec\" springen\n       iptables -A services -p udp --dport $port -j ACCEPT                              #Bei Verbindungen auf UDP Port \"$port Verbindung zulassen\ndone\niptables -A services -p ALL -j RETURN                                                   #Tabelle \"services\" verlassen\n\n#INPUT\niptables -A INPUT -p ALL -i lo -j ACCEPT                                                #Alle Pakete vom Loopback Interface zulassen\niptables -A INPUT -p ALL -m state --state ESTABLISHED,RELATED -j ACCEPT                 #Bereits vorhandene Verbindungen zulassen\niptables -A INPUT -p ALL -j other_packets                                               #In die Tabelle \"other_packets\" springen\niptables -A INPUT -p ALL -j services                                                    #In die Tabelle \"services\" gehen\niptables -A INPUT -p ALL -m limit --limit 10\/s -j reject_packets                        #Nicht erlaubte Pakete zur\u00fcckweisen, max 10Pakete\/Sekunde (Tabelle \"reject_Packets\")\niptables -A INPUT -p ALL -j DROP                                                        #Alles andere verwerfen\n\n#OUTPUT:\niptables -A OUTPUT -p ALL -j ACCEPT\n\n\n<\/code><\/pre>\n\n\n\n<p>Ich habe (schon damals) versucht, es mit Kommentaren einigermassen verst\u00e4ndlich zu machen. Versucht \ud83d\ude09 <\/p>\n\n\n\n<p>Damit das Script beim Starten direkt ausgef\u00fchrt wird, muss es noch nach init.d verlinkt werden (oder direkt dort abgespeichert) und dann noch als Service hinzugef\u00fcgt werden. An dieser Stelle aber erstmal ein dickes<\/p>\n\n\n\n<p style=\"color:#a30000\" class=\"has-text-color has-large-font-size\">Achtung!!<\/p>\n\n\n\n<p>Ab dem Punkt, wo die Datei verlinkt ist und als Service eingetragen ist, wird sie bei jedem Start ausgef\u00fchrt. Sprich: Wenn ihr wichtige Ports darin vergesst (wie z.B. SSH bei einem remote-Server), schiesst ihr euch selbst in&#8217;s Knie und sperrt euch aus. Daher vor dem Eintrag am Besten das Script direkt ausf\u00fchren und testen. Wenn ihr danach nicht mehr auf den Server kommt: Reboot und neuer Versuch.<\/p>\n\n\n\n<p>Wenn alles eingerichtet ist, dann noch folgende beiden Befehle auf der Konsole absetzen und schon kommt die Firewall nach jedem Neustart automatisch:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ln -s \/pfad\/zu\/iptables.sh \/etc\/init.d\/iptables\nupdate-rc.d iptables defaults<\/code><\/pre>\n\n\n\n<p>Danach neustarten und mittels<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>iptables -L<\/code><\/pre>\n\n\n\n<p>Testen, ob das Script gezogen hat. Die Ausgabe sollte wie folgt aussehen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Chain INPUT (policy DROP)\ntarget     prot opt source               destination\nACCEPT     all  --  anywhere             anywhere\nACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED\nother_packets  all  --  anywhere             anywhere\nservices   all  --  anywhere             anywhere\nreject_packets  all  --  anywhere             anywhere             limit: avg 10\/sec burst 5\nDROP       all  --  anywhere             anywhere\n\nChain FORWARD (policy DROP)\ntarget     prot opt source               destination\n\nChain OUTPUT (policy ACCEPT)\ntarget     prot opt source               destination\nACCEPT     all  --  anywhere             anywhere\n\nChain other_packets (1 references)\ntarget     prot opt source               destination\nDROP       all  --  anywhere             anywhere             state INVALID\nACCEPT     icmp --  anywhere             anywhere             limit: avg 1\/sec burst 5\nRETURN     all  --  anywhere             anywhere\n\nChain reject_packets (1 references)\ntarget     prot opt source               destination\nREJECT     tcp  --  anywhere             anywhere             reject-with tcp-reset\nREJECT     udp  --  anywhere             anywhere             reject-with icmp-port-unreachable\nREJECT     icmp --  anywhere             anywhere             reject-with icmp-host-unreachable\nREJECT     all  --  anywhere             anywhere             reject-with icmp-proto-unreachable\nRETURN     all  --  anywhere             anywhere\n\nChain service_sec (3 references)\ntarget     prot opt source               destination\nACCEPT     tcp  --  anywhere             anywhere             tcp flags:FIN,SYN,RST,ACK\/SYN limit: avg 2\/sec burst 5\nDROP       tcp  --  anywhere             anywhere             tcp flags:!FIN,SYN,RST,ACK\/SYN state NEW\nACCEPT     tcp  --  anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG\/NONE limit: avg 1\/hour burst 5\nACCEPT     tcp  --  anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG\/FIN,SYN,RST,PSH,ACK,URG limit: avg 1\/hour burst 5\nRETURN     all  --  anywhere             anywhere\n\nChain services (1 references)\ntarget     prot opt source               destination\nservice_sec  tcp  --  anywhere             anywhere             tcp dpt:ssh\nACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh\nservice_sec  tcp  --  anywhere             anywhere             tcp dpt:http\nACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http\nservice_sec  tcp  --  anywhere             anywhere             tcp dpt:https\nACCEPT     tcp  --  anywhere             anywhere             tcp dpt:https\nRETURN     all  --  anywhere             anywhere\n<\/code><\/pre>\n\n\n\n<p>Noch ein kleiner Hinweis: iptables arbeitet alles nacheinander ab. Wenn also oben erstmal alles verboten wird und dann nach und nach dinge wieder erlaubt werden, ist das so in Ordnung.<\/p>\n\n\n\n<p>Weitere n\u00fctzliche Informationen zu IPtables findet ihr <a href=\"https:\/\/wiki.ubuntuusers.de\/iptables2\/\">hier.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ein Server ohne Firewall &#8211; kann man mal machen, aber dann ist es halt &#8230;. \ud83d\ude09 Zugegeben, der Grundstock dieses Scripts stammt nicht aus meiner Feder. Ich habe es vor Jahren mal irgendwo gefunden und dann immer wieder angepasst mittlerweile &hellip; <a href=\"https:\/\/blog.steiner.systems\/?p=25\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,3,6],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.steiner.systems\/index.php?rest_route=\/wp\/v2\/posts\/25"}],"collection":[{"href":"https:\/\/blog.steiner.systems\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.steiner.systems\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.steiner.systems\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.steiner.systems\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=25"}],"version-history":[{"count":1,"href":"https:\/\/blog.steiner.systems\/index.php?rest_route=\/wp\/v2\/posts\/25\/revisions"}],"predecessor-version":[{"id":26,"href":"https:\/\/blog.steiner.systems\/index.php?rest_route=\/wp\/v2\/posts\/25\/revisions\/26"}],"wp:attachment":[{"href":"https:\/\/blog.steiner.systems\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=25"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.steiner.systems\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=25"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.steiner.systems\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=25"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}