iptables init-script für Arch
Ja, das vom Paket iptables mitgebrachte init-script leistet wunderbare Dienste. Nein, es besteht kein akuter Grund, eine Alternative zu schreiben...
Einen Nachteil hat es schon: die Konfiguration wird in einem nicht kommentierbaren Format hinterlegt, was bei mir in letzter Zeit ständig zur Frage "WTF hat doch gleich dieser Port da verloren? Was lässt die rule da nochmal durch?" geführt hat.
<bash-addicted>Yep, eindeutige Notwenigkeit für ein selbst gehämmertes, kommentierbares Script!</bash-addicted> Wie in guten alten Debian-Zeiten übernimmt jetzt also bei mir ein einfaches, aber für den Job völlig ausreichendes init-script den Job. Wer es verwenden mag:
#!/bin/bash # # easy-to-edit iptables init script for Arch # 2010 by Alexander Koch # # TCP services: ssh SERVICES_TCP=( 22 ) # UDP services: SERVICES_UDP=( ) . /etc/rc.conf . /etc/rc.d/functions if [ -e "/etc/conf.d/iptables" ]; then . /etc/conf.d/iptables fi if [ -z "$IPTABLES" ]; then IPTABLES="/usr/sbin/iptables" fi if ! [ -x "$IPTABLES" ]; then echo "unable to execute iptables binary: $IPTABLES" exit 1 fi function reset_tables() { ERR=0 $IPTABLES -F || ERR=1 $IPTABLES -X || ERR=1 $IPTABLES -P INPUT ACCEPT || ERR=1 $IPTABLES -P OUTPUT ACCEPT || ERR=1 if [ $IPTABLES_FORWARD -eq 1 ]; then $IPTABLES -P FORWARD ACCEPT || ERR=1 echo 1 >/proc/sys/net/ipv4/ip_forward || ERR=1 else $IPTABLES -P FORWARD DROP || ERR=1 echo 0 >/proc/sys/net/ipv4/ip_forward || ERR=1 fi return $ERR } function setup_tables() { ERR=0 # setup prevention chain against common attacks $IPTABLES -N preventions || ERR=1 $IPTABLES -A preventions -f -j DROP || ERR=1 # frags $IPTABLES -A preventions -p tcp --tcp-flags ALL ALL -j DROP || ERR=1 # XMAS $IPTABLES -A preventions -p tcp --tcp-flags ALL NONE -j DROP || ERR=1 # null # setup services chain $IPTABLES -N services || ERR=1 for PORT in ${SERVICES_TCP[@]}; do $IPTABLES -A services -p tcp --dport $PORT -j ACCEPT || ERR=1 done for PORT in ${SERVICES_UDP[@]}; do $IPTABLES -A services -p udp --dport $PORT -j ACCEPT || ERR=1 done # allow incoming ping requests iptables -A services -p icmp --icmp-type echo-request -j ACCEPT || ERR=1 # setup main chains $IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT || ERR=1 $IPTABLES -A INPUT -i lo -j ACCEPT || ERR=1 $IPTABLES -A INPUT -j preventions || ERR=1 $IPTABLES -A INPUT -m state --state NEW -j services || ERR=1 $IPTABLES -A INPUT -p tcp -j REJECT --reject-with tcp-reset || ERR=1 $IPTABLES -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable || ERR=1 $IPTABLES -P INPUT DROP || ERR=1 return $ERR } case "$1" in start) stat_busy "Loading IP Tables" reset_tables if ! setup_tables; then stat_fail exit 1 else add_daemon miptables stat_done fi ;; stop) stat_busy "Flushing IP Tables" if reset_tables; then rm_daemon miptables stat_done else stat_fail exit 1 fi ;; restart) if ! ck_daemon miptables; then rm_daemon miptables fi $0 start exit $? ;; *) echo "usage: $0 {start|stop|restart}" ;; esac exit 0
Gefiltert werden nur eingehende Pakete; related und established Pakete werden ebenfalls ohne weitere Beachtung durchgelassen, ebenso alles über loopback. Für neue Pakete werden zuerst ein paar Vulnerability-Checks durchgeführt. Nach Außen wird ein Verhalten wie ohne iptables emuliert (z.B. REJECTs mit tcp-reset).
Bugreports wie immer willkommen, und Benutzung auf eigene Gefahr!
Update 31.07.10: Bugfixed
Server Setup – Teil 1
Mehr oder weniger als Nachtrag hier ein paar Worte zum Setup des bereits angekündigten, neuen Servers: cron, logrotate und iptables.
Die Kiste (Debian 5.0 Lenny, minimal install) hatte standardmäßig anacron installiert, aufgrund der erweiterten Features wie load-condition und nice-values bin ich da gleich auf fcron umgestiegen.
Unter Lenny ist kein init-script mehr für iptables vorhanden, es ist wohl vorgesehen, einen Hook in den up- und down-scripts für die entsprechenden Interfaces zu verwenden. Da man auf einem Server ja eine eher statische Umgebung hat, genügte mir hier ein auf meinem iptables-setup-script basierendes init-script.
Zum logrotate-setup bleibt noch zu sagen, dass der Parameter dateext sich als sehr hilfreich erwiesen hat.
iptables Setup Script
Natürlich kann man sowas auch manuell immer wieder neu machen, aber bei vier aufeinanderfolgenden Installationen (allesamt auf Arch) ohne direkte Verbindung hat sich dann doch ein kleines (bash)Script angeboten.
Vielleicht kann es ja noch jemandem praktische Dienste leisten
BENUTZUNG AUF EIGENE GEFAHR!
#!/bin/sh # check requirements if [ -x /usr/sbin/iptables ]; then echo "iptables binary not found." exit 1 fi # clear chains iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT iptables -F iptables -X # create new chains and link them iptables -N open # services will be opened here iptables -N interfaces # completely open interfaces here iptables -A INPUT -j open iptables -A INPUT -j interfaces # deny forwarding iptables -P FORWARD DROP # allow all outgoing traffic iptables -P OUTPUT ACCEPT # allow all traffic on loopback iptables -A interfaces -i lo -j ACCEPT # allow related connections (--> stateful) iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # allowed services iptables -A INPUT -p icmp -j ACCEPT # ping iptables -A open -p tcp --dport 22 -j ACCEPT # ssh # deny all other incoming traffic iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset # imitate default linux behaviour iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable # " iptables -P INPUT DROP # protection against common attacks iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP # SYN for new packets iptables -A INPUT -f -j DROP # fragmentation check iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP # XMAS-packets iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP # null packets iptables -I INPUT -p icmp --icmp-type redirect -j DROP # ICMP type match blocking iptables -I INPUT -p icmp --icmp-type router-advertisement -j DROP # " iptables -I INPUT -p icmp --icmp-type router-solicitation -j DROP # " iptables -I INPUT -p icmp --icmp-type address-mask-request -j DROP # " iptables -I INPUT -p icmp --icmp-type address-mask-reply -j DROP # " echo "net.ipv4.conf.all.rp_filter = 1" >> /etc/sysctl.conf # enable source address verification echo "net.ipv4.tcp_timestamps = 0" >> /etc/sysctl.conf # nmap uptime detection echo "net.ipv4.conf.all.accept_source_route=0" >> /etc/sysctl.conf # we are not a router echo "net.ipv4.icmp_echo_ignore_broadcasts=1" >> /etc/sysctl.conf # " echo "net.ipv4.icmp_ignore_bogus_error_messages=1" >> /etc/sysctl.conf # " # disable ip forwarding if [ -e /etc/conf.d/iptables ]; then cat /etc/conf.d/iptables | egrep -v '^IPTABLES_FORWARD' > /tmp/iptables.conf echo "IPTABLES_FORWARD=0" >> /tmp/iptables.conf cat /tmp/iptables.conf > /etc/conf.d/iptables rm /tmp/iptables.conf fi # and finally save our work /etc/rc.d/iptables save
Das Script erstellt ein Basis-Regelwerk und lässt nur Ping (ICMP) und SSH (auf allen interfaces) eingehend zu. Alle anderen eingehenden Verbindungen werden geblockt; ausgehende Verbindungen vollständig erlaubt. Desweiteren implementiert es Schutzmaßnahmen gegen die üblichsten Attacken.