
Wer im Netz einen Webserver betreibt, der wird sich immer wieder Attacken gegen seinen Server ausgesetzt fühlen. Das sind nicht oft gezielte Angriffe, sondern eher Suchmachanismen, die an diversen Standardports herausfinden, ob diverse Dienste wie http oder ssh freigegeben sind. An solchen freigegeben Ports werden dann entsprechende Einbruchsversuche gestartet. Dies geschieht über verschiedene Wege. Die einfachste aber am häufigsten verwendete Methode ist der sogenannte Brute Force Angriff. Hier versucht der Angreifer mittels vorgefertigter Passwortlisten das korrekte Passwort zu erraten. Dabei werden anhand dieser Liste Logins solange probiert, bis das passende Passwort gefunden ist. Ähnliches kann natürlich auch am FTP Server passieren.
Dieses Tutorial soll nun eine Möglichkeit aufzeichnen, solchen Brut Force Attacken zu begegnen und zusätzlich die NSLU2 über ein Firewall-Script soweit abzudichten, bis eben auf die für die NSLU2 benötigten Ports. Das Tutorial soll allerdings keinesfalls eine falsche Sicherheit vorgaukeln. Eine Firewall und eine IP Falle, wie wir sie im nachfolgenden Text über das Programm Fail2Ban realisieren werden kann nur eine gewisse Sicherheit bieten. Wichtig ist zudem weiterhin, seine Log-Dateien regelmäßig im Auge zu behalten und auch zu kontrollieren, welche Dateien sich auf der Büchse befinden. Bekommen die Dateien ungebetenen Zuwachs, dann ist wohl der ftp-Server geknackt worden.
Das von mir verfasste Tutorial fasst einige Arbeitsschritte zusammen, die für sich betrachtet auch noch ausbaufähig sind. Aufgrund der Komplexität des Themas kann dies auch nicht wirklich vollständig sein und stellt in dieser Hinsicht eine Art Grundgerüst dar, auf dass freilich weiter aufgebaut werden kann.
Da das Konfigurieren einer Firewall nicht wirklich trivial ist sei noch gesagt: Bevor Ihr irgendwelche Scripte automatisiert, startet diese IMMER erst manuell und testet die Funktionalität der Scripte. Sperrt Ihr Euch aus Versehen durch eine Falschkonfiguration aus und die Scripte werden nach einem Reboot automatisch gestartet, weil diese bereits in den Initscripten integriert wurden habt Ihr wenig bis gar keine Chance mehr, auf Eure Büchse zu kommen. Hier muss das Gerät dann wieder mit einer frischen Firmware geflasht werden und Ihr könnt das Gerät wieder von vorne neu einrichten.
Ziel dieses Tutorials ist es nun, eine IP Falle mit dem Programm Fail2Ban zu installieren. Mittels dieser "Falle" können Loginversuche limitiert werden. IP-Nummern über die nun versucht wird, ein Passwort zu erraten, werden nach einer vordefinierten Anzahl von Fehlversuchen einfach gesperrt. Die Sperre wird dann nach einer gewissen Zeit wieder aufgehoben. Hierbei empfiehlt sich eine Sperre von mehreren Tagen, damit der Versuch, einen Einbruch über eine Passwortliste zu unternehmen ad Absurdum führt. Zudem sollen Einbruchsversuche uns per E-Mail gemeldet werden. Zum Schluss wollen wir noch eine Firewall für die restlichen Ports unseres Servers einrichten.
Also lest alles in Ruhe durch, nehmt Euch Zeit für Euer Projekt, dann werdet Ihr denke ich auch eine Menge Spaß dabei haben!

Basis Pakete installieren
Zuerst sollten wir - falls nicht schon aufgrund meiner vorangegangenen Tutorials geschehen - die NSLU2 durch die Entwicklerpakete ergänzen, damit wir bei Bedarf etwas kompilieren können:
Code:
ipkg install optware-devel
ipkg install python
Danach modifizieren wir die /etc/profile, damit wir einen sauberen Kompile hinbekommen:
Ergänzt dann folgende Zeilen und speichert die Datei ab:
Code:
export PATH=$PATH:/opt/bin:/opt/sbin:/opt/usr/bin:/opt/usr/sbin:.
export LD_LIBRARY_PATH=/opt/lib
Meldet Euch erstmal aus Eurer Slug ab und dann wieder an, damit die Suchpfade übernommen werden.

Syslog ändern
Damit wir ein paar mehr wichtige Informationen wie eben auch die Sicherheitsmeldungen des openssh Servers geliefert bekommen, müssen wir den bisherigen Syslog Dämonen durch einen anderen ersetzen. Dies ist schnell erledigt!
Zuerst das neue Syslogpaket installieren
Code:
ipkg install syslog-ng
Danach in /etc/inittab folgende Zeilen auskommentieren:
Code:
# slog:unknown:/sbin/syslogd -n
# klog:unknown:/sbin/klogd -n
Alte Logdaemons abschießen:
Code:
killall syslogd
killall klogd
Syslog dann mit
Code:
/opt/etc/init.d/S01syslog-ng
starten. Beim nächsten Reboot wird das Programm automatisch gestartet.
Damit die Logdateien nicht auf Dauer zu groß werden und eventuell gerade bei der Verwendung von etwas knapp bemessenen USB-Sticks zu vollen Datenspeichern zu führen, empfehle ich die Verwendung des logrotate. Dieser sorgt dafür, dass die schnell wachsenden System-Logs in separaten gepackten Dateien gespeichert werden und die aktuelle Log-Datei heruntergekürzt werden. Dies geschieht rotierend, d.h. die gepackten Dateien werden durchnummeriert und die älteste jeweils gelöscht. Hierzu installiert bitte den logrotate mit folgendem Befehl:
Code:
ipkg install logrotate
Jetzt editiert die /opt/etc/logrotate.conf mit dem
Code:
vi /opt/etc/logrotate.conf
und ändert diese wie folgt ab:
Code:
compress
/opt/var/log/messages opt/var/log/syslog opt/var/log/kern.log opt/var/log/d**** {
rotate 5
postrotate
/bin/killall syslogd
/bin/killall klogd
/bin/killall -HUP syslog-ng
endscript
}
include /opt/etc/logrotate.d
rotate 5 bedeutet, dass Ihr 5 Sicherungen bekommt, bis die älteste bei der 6. Sicherung gelöscht wird. Damit das auch automatisiert funktioniert, editiert Eure crontab:
und fügt folgende Zeile ein:
Code:
30 23 * * 6 root /opt/sbin/logrotate -f /opt/etc/logrotate.conf &>/dev/null
Das löst jeden Samstag um 23:30 Uhr eine Bereinigung der Logfiles aus. Somit habt Ihr die Files zumindest 5 Wochen zur Verfügung, solltet Ihr irgendwelchen Unregelmäßigkeiten auf die Spur kommen wollen. Die gepackten Dateien befinden sich dann unter /opt/var/log und können mit dem Midnight Commander beispielsweise eingesehen werden.

Iptables / Firewall installieren
Bevor wir uns nun an das Eingemachte machen können, müssen wir noch diverse Kernelmodule nachinstallieren. Dann kommen die iptables dran, mit denen wir im weiteren Verlauf des Tutorials noch viel Freude haben werden. Folgende 4 Pakete werden nun installiert:
Code:
ipkg install kernel-module-ip-tables -force-depends
ipkg install kernel-module-iptable-filter -force-depends
ipkg install kernel-module-ipt-log
ipkg install iptables
Startet nun sicherheitshalber Eure Slug neu, damit alles sauber initialisiert wird.

Erweiterung der Firewall mit IPTABLES
Wer seine Slug noch weiter abdichten möchte, der kann hier mit einem sehr guten Script arbeiten, dass man auf der NSLU2-Linux.org findet. Dieses fügt weitere Regeln hinzu und sperrt die Ports. Wobei Standarddienste wie der ftp und der http Server offen bleiben. Sollen weitere Ports geöffnet werden, so muss das in dem folgenden Script hinterlegt werden.
Jetzt ein Firewallscript anlegen:
Code:
touch /opt/etc/iptables.sh
Das machen wir ausführbar:
Code:
chmod +x /opt/etc/iptables.sh
Dann füllen wir den Inhalt mit folgender ausgezeichneten Firewallregel, welches ich auf der nslu2-linux.org gefunden habe (Link folgt nach dem Script):
Code:
#!/bin/sh
###############################################################################
#
# Local Settings
#
# IPTables Location - adjust if needed
IPT="/opt/sbin/iptables"
IPTS="/opt/sbin/iptables-save"
IPTR="/opt/sbin/iptables-restore"
# Internet Interface
INET_IFACE="ixp0"
# Path to iptables modules
IPT_MODPATH="/lib/modules/2.4.22-xfs/kernel/net/ipv4/netfilter"
# CHANGE THIS TO MATCH YOUR SLUG IP ADDRESS
# currently not used
INET_ADDRESS="10.0.0.123"
# 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/sysconfig/iptables ... "
$IPTS > /opt/etc/iptables
echo "done"
exit 0
elif [ "$1" = "restore" ]
then
echo -n "Restoring firewall from /etc/sysconfig/iptables ... "
$IPTR < /opt/etc/iptables
echo "done"
exit 0
fi
# Load Modules
echo "Loading kernel modules ..."
insmod $IPT_MODPATH/ip_tables.o
insmod $IPT_MODPATH/iptable_filter.o
# if you need logging, uncomment line above
# (be aware you have installed the kernel-module-ipt-log
#insmod $IPT_MODPATH/ipt_LOG.o
# 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
# ports you send udp packets to
# netbios/samba
$IPT -A udp_outbound -p UDP -s 0/0 --destination-port 137 -j ACCEPT
$IPT -A udp_outbound -p UDP -s 0/0 --destination-port 138 -j ACCEPT
# Network Time Protocol (NTP) Server
$IPT -A udp_outbound -p UDP -s 0/0 --destination-port 123 -j ACCEPT
# DHCP out
$IPT -A udp_outbound -p UDP -s 0/0 --destination-port 68 -j ACCEPT
# DNS out
$IPT -A udp_outbound -p UDP -s 0/0 --destination-port 53 -j ACCEPT
# No match, so ACCEPT
# make this DROP if you want to block any other outbound udp traffic
$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
# 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 33201:33210 -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
# telnet
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 23 -j ACCEPT
# Not matched, so return so it will be logged
$IPT -A tcp_inbound -p TCP -j RETURN
# tcp_outbound chain
#
# This chain controlls what tcp traffic is allowed out
# http
$IPT -A tcp_outbound -p TCP -s 0/0 --destination-port 80 -j ACCEPT
# DNS
$IPT -A tcp_outbound -p TCP -s 0/0 --destination-port 53 -j ACCEPT
# sshd
$IPT -A tcp_outbound -p TCP -s 0/0 --destination-port 22 -j ACCEPT
# No match, so ACCEPT
# Note, you could make this DROP to block any other outbound traffic
$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
( Das Script und einen Download findet Ihr unter folgender Adresse NSLU2-Linux - HowTo / EnableFirewall browse )
Gestartet wird die Firewall mit
Code:
/opt/etc/iptables.sh
Anhalten mit
Code:
/opt/etc/iptables.sh stop
Um die Firewall bei jedem Start automatisch zu aktivieren müssen wir einen Link anlegen:
Code:
ln -s /opt/etc/iptables.sh /opt/etc/init.d/S30iptables
Ihr werdet hier jetzt bemerken, dass z.B. Euer Webadmin geblockt ist, weil dieser nicht auf dem Port 80 liegt, sondern einem anderen, den Ihr bereits in der Vergangenheit zugewiesen habt. Um nun den http auch für einen zweiten Port freizugeben ergänzt das Script durch zwei neue Regeln, die Ihr am besten unter die bisherige Port 80 Regel setzt. Sucht dazu folgende Zeilen im Script:
Code:
# http
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 80 -j ACCEPT
Diese erweitert Ihr folgendermaßen, wenn Ihr Eurem Webadmin z.B. den Port 9055 zugewiesen habt:
Code:
# 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 9055 -j ACCEPT
Das gleiche für den Outbound:
Code:
# http
$IPT -A tcp_outbound -p TCP -s 0/0 --destination-port 80 -j ACCEPT
in
Code:
# http
$IPT -A tcp_outbound -p TCP -s 0/0 --destination-port 80 -j ACCEPT
$IPT -A tcp_outbound -p TCP -s 0/0 --destination-port 9055 -j ACCEPT
Wenn Ihr z.B. den Firefly MP3 Server installiert habt, dann benötigt dieser auch einen freien Port auf 3689 beispielsweise (je nachdem, wie Ihr ihn konfiguriert habt). Gebt diesen Port frei, indem Ihr direkt bei den Portfreigaben im Script folgende Zeilen ergänzt:
Code:
# MT-DAAP
$IPT -A tcp_outbound -p TCP -s 0/0 --destination-port 3689 -j ACCEPT
$IPT -A INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
$IPT -A OUTPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
Die IP 224.0.0.251 ist eine Multicast-Adresse, die hier Apples i-Tunes zum Rendezvous auf dem Port 5353 benötigt. Wird dieser geblockt findet der i-Tunes den NSLU2 Firefly Media Server nicht mehr im Netz.
Zum Schluss muss noch die /opt/etc/vsftpd.conf editiert werden, damit der passive Modus des vsftp FTP Server funktioniert und eine Verbindung wieder möglich wird. Ergänzt nun am Ende der vsftp.conf folgende Zeilen:
Code:
# for our firewall, only use this range of ports
pasv_min_port=33201
pasv_max_port=33210
Fortsetzung ...
Lesezeichen