Firewall

Aus Wiki
Zur Navigation springen Zur Suche springen

Allgemein

Um die NSLU weiter gegen Angreifer aus dem Internet abzusichern, wird im Folgenden die Linux-Standardfirewall "iptables" (http://www.netfilter.org) installiert. On Top wird Fail2ban (http://fail2ban.org) istalliert, 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 iptables

Installation der Kernel-Module

Für die Firewall iptables werden einige Kernel-Module benötigt, die entweder per → ipkg (bevorzugt) oder → manuell heruntergeladen werden und anschließend installiert werden.


IPKG-Installation

Hinweis:
Falls die Module nicht gefunden werden, oder ein sonstiger Fehler auftritt, Installation gemäß → Manuelle Installation durchführen.
ipkg install kernel-module-ip-tables
ipkg install kernel-module-iptable-filter
ipkg install kernel-module-ipt-multiport
ipkg install kernel-module-ip-conntrack
ipkg install kernel-module-iptable-nat
ipkg install kernel-module-ipt-recent
ipkg install kernel-module-ipt-log


Manuelle Installation

Hinweis:
Nur nötig, falls die Installation mittels ipkg scheitern sollte.

Ermitteln der aktuellen Version und Downloadlink der Kernel-Module: Auf der Seite http://ipkg.nslu2-linux.org/feeds/unslung/modules/cross/stable/ die Version (jeweils neueste)der folgenden Kernel-Module ermitteln:

  • kernel-module-ip-tables :z.B. kernel-module-ip-tables_2.4.22.l2.3r63-r22_nslu2be.ipk
  • kernel-module-iptable-filter :z.B. kernel-module-iptable-filter_2.4.22.l2.3r63-r22_nslu2be.ipk
  • kernel-module-ipt-multiport :z.B. kernel-module-ipt-multiport_2.4.22.l2.3r63-r22_nslu2be.ipk
  • kernel-module-ip-conntrack :z.B. kernel-module-ip-conntrack_2.4.22.l2.3r63-r22_nslu2be.ipk
  • kernel-module-iptable-nat :z.B. kernel-module-iptable-nat_2.4.22.l2.3r63-r22_nslu2be.ipk
  • kernel-module-ipt-recent :z.B. kernel-module-ipt-recent_2.4.22.l2.3r63-r22_nslu2be.ipk
  • kernel-module-ipt-log :z.B. kernel-module-ipt-log_2.4.22.l2.3r63-r22_nslu2be.ipk

damit ergibt sich z.B. für das kernel-module-ip-tables kernel-module-ip-tables_2.4.22.l2.3r63-r22_nslu2be.ipk der Downloadlink: http://ipkg.nslu2-linux.org/feeds/unslung/modules/cross/stable/kernel-module-ip-tables_2.4.22.l2.3r63-r22_nslu2be.ipk

Download der Module:

In den folgenden wget-Statements den Filenamen (Teil nach $SERVER/) mit den im ersten Schritt ermittelten Version/Filenamen ersetzen.

cd /work (mittels mkdir work anlegen, falls es nicht existiert)
SERVER=http://ipkg.nslu2-linux.org/feeds/unslung/modules/cross/stable/
wget $SERVER/kernel-module-ip-tables_2.4.22.l2.3r63-r22_nslu2be.ipk
wget $SERVER/kernel-module-iptable-filter_2.4.22.l2.3r63-r22_nslu2be.ipk
wget $SERVER/kernel-module-ipt-multiport_2.4.22.l2.3r63-r22_nslu2be.ipk
wget $SERVER/kernel-module-ip-conntrack_2.4.22.l2.3r63-r22_nslu2be.ipk
wget $SERVER/kernel-module-iptable-nat_2.4.22.l2.3r63-r22_nslu2be.ipk
wget $SERVER/kernel-module-ipt-recent_2.4.22.l2.3r63-r22_nslu2be.ipk
wget $SERVER/kernel-module-ipt-log_2.4.22.l2.3r63-r22_nslu2be.ipk

Installieren der Kernel-Module:

ipkg install kernel-module-ip-tables_2.4.22.l2.3r63-r22_nslu2be.ipk -force-depends
ipkg install kernel-module-iptable-filter_2.4.22.l2.3r63-r22_nslu2be.ipk -force-depends
ipkg install kernel-module-ipt-multiport_2.4.22.l2.3r63-r22_nslu2be.ipk -force-depends
ipkg install kernel-module-ip-conntrack_2.4.22.l2.3r63-r22_nslu2be.ipk -force-depends
ipkg install kernel-module-iptable-nat_2.4.22.l2.3r63-r22_nslu2be.ipk -force-depends
ipkg install kernel-module-ipt-recent_2.4.22.l2.3r63-r22_nslu2be.ipk -force-depends
ipkg install kernel-module-ipt-log_2.4.22.l2.3r63-r22_nslu2be.ipk -force-depends

Installation von iptables

ipkg update
ipkg 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 NSLU-Howtos installierten Programme enthält, die Standardmäßig auskommentiert sind.

vi /opt/etc/iptables.sh

Folgende Zeilen einfügen:

#!/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
insmod $IPT_MODPATH/ipt_multiport.o
#insmod $IPT_MODPATH/ip_conntrack.o
#insmod $IPT_MODPATH/ipt_nat.o
#insmod $IPT_MODPATH/ipt_recent.o
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
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 8282 -j ACCEPT

# FTP
#$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port ftp -j ACCEPT
#$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 2021 -j ACCEPT
# Passive
#$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

# telnet
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 23 -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
#
# This chain controlls what tcp traffic is allowed out

# 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 8282 -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

#SMTP
#$IPT -A tcp_outbound -p TCP -s 0/0 --destination-port 25 -j ACCEPT
#IMAPd
#$IPT -A tcp_outbound -p TCP -s 0/0 --destination-port 143 -j ACCEPT
#$IPT -A tcp_outbound -p TCP -s 0/0 --destination-port 993 -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

Firewall-Script ausführbar machen:

chmod +x /opt/etc/iptables.sh

Konfiguration von 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:

#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 →IMAPS-Server), 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

Weboberfläche und 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
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 8282 -j ACCEPT

Freigeben Port 80 für Webserver:

# 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 8282 -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. Falls proFTPd zusammen mit SSL-Verschlüsselung verwendet wird, muß ein zusätzlicher Port (z.B. 2021) für externe Anfragen aus dem Internet freigegeben werden.

# FTP
#$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port ftp -j ACCEPT
#$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 2021 -j ACCEPT
# Passive
#$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 60019:60049 -j ACCEPT

Z.B. Freigabe für bFTPd und VsFTPd:

# FTP
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port ftp -j ACCEPT
#$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 2021 -j ACCEPT
# Passive
#$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 60019:60049 -j ACCEPT

z.B. Freigabe für proFTPd:

# FTP
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port ftp -j ACCEPT
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 2021 -j ACCEPT
# Passive
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 60019:60049 -j ACCEPT


Funktionstest

Bevor die Firewall getestet werden kann, muß diese erst einmal gestartet werden. Dies erfolgt mit folgendem Befehl:

/opt/etc/iptables.sh

Hinweis: Sollte es zu Problemen mit der Firewall kommen, kann diese mittels

/opt/etc/iptables.sh stop

wieder angehalten werden.


  • Nach dem Start sollte weiterhin Zugriff auf die NSLU mittels OpenSSH bestehen. Es sollte auch getestet werden, ob eine neue Verbindung aufgebaut werden kann.
  • Mittels Webbrowser checken, ob die NSLU-Weboberfläche erreichbar ist.
  • Sofern Apache installiert ist auch checken, ob die eigenen Webseiten noch erreichbar sind.
  • Falls ein Mailserver eingerichtet wurde, prüfen ob dieser einwandfrei funktioniert. Insbesondere sollte der IMAP-Zugriff, das senden und empfangen von Mails überprüft werden.
  • Falls ein FTP-Server aktiviert wurde, prüfen, ob dieser trotz Firewall noch einwandrei erreichbar ist (sowohl intern als auch evtl. extern).


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 der NSLU mitstartet.

ACHTUNG:
Sollte die Firewall automatisch starten, und weder SSH noch Telnet erreichbar sein, ist keinerlei Zugriff mehr auf die NSLU möglich. D.h. um wieder Zugriff zu erhalten, ist eine komplette Neuinstallation nötig. Deshalb unbedingt sicher stellen, dass sowohl SSH als auch evtl. Telnet erreichbar sind, BEVOR der folgende Befehl ausgeführt wird.
ln -s /opt/etc/iptables.sh /opt/etc/init.d/S30iptables


Installation Fail2Ban

Fail2ban liegt zwar nicht als ipkg-Paket vor, dessen Installation ist aber dennoch nicht übermäßig kompliziert:

Fail2ban basiert auf Python. Dies ist eine Scriptsprache vergleichbar mit PHP oder Perl. Falls Python nicht installiert ist, muss dieses nun installiert werden:

ipkg install python24

Fail2ban bietet die Möglichkeit, mittels whois (http://de.wikipedia.org/wiki/Whois) weitere Informationen über die Herkunft einer gebannten IP-Adresse zu ermitteln. Dafür muss natürlich whois installiert werden:

ipkg install whois


Ermitteln der aktuellen Version unter: http://downloads.sourceforge.net/fail2ban Aktuell ist die Version V0.8.3 verfügbar. Falls eine neuere Version zur Verfügung steht, den Downloadlink entsprechend anpassen (und natürlich auch die tar und cd Befehle).

cd /work  (mkdir /work ausführen, falls dieses noch nicht existiert)
wget http://downloads.sourceforge.net/fail2ban/fail2ban-0.8.3.tar.bz2

Entpacken:

tar xvfj fail2ban-0.8.3.tar.bz2

Installieren:

cd fail2ban-0.8.3
python setup.py install

Optional:Email-Benachrichtigungen Voraussetzung: Postfix ist installiert. Fail2ban benötigt sendmail im Verzeichnis /usr/sbin/sendmail. Um dies zu erreichen:

ln -s /opt/sbin/sendmail /usr/sbin/sendmail

Damit 'whois' bei der email-Benachrichtigung aufgerufen wird, muss noch der Pfad auf 'whois' angepasst werden:

vi /etc/fail2ban/action.d/sendmail-whois.conf

Die Zeile

`/usr/bin/whois <ip>`\n

im Bereich actionban folgendermaßen abändern:

`/opt/bin/whois <ip>`\n


Konfiguration von Fail2ban

vi /etc/fail2ban/fail2ban.conf

Socket-File ändern:

socket = /var/run/fail2ban/fail2ban.sock

Ersetzen durch:

socket = /var/run/fail2ban.sock

Neben dieser Konfigurationsdatei existiert noch das File /etc/fail2ban/jail.conf. Dieses definiert die anzuwendenden Regeln (Filter) und die entsprechenden Aktionen daraus. Die Filter sind jeweils in einer Konfig-Datei im Verzeichnis /etc/fail2ban/filter.d/ Für viele Tools sind bereits Filter-Files vordefiniert.

Desweiteren sind bereits zahlreiche Beispiele von Konfigurationen in der jail.conf vorgegeben, die allerdings alle deaktiviert sind (enabled=false).

Genereller Aufbau jeder Fail2ban-Definition (Jail) in der jail.conf:

  • enabled: true: Regel aktiviert / false: Regel inaktiv
  • filter: Filterfile, das ein Log-File analysiert
  • action: Aktion, die ausgeführt wird, wenn der Filter einen Einbruchsversuch detektiert hat.
         iptables: Ergänzt eine Firewall-Regel, die den Angreifer komplett aussperrt
         sendmail-whois: Sendet eine Mail. Email-Adresse des Empfängers unter dest eintragen.
  • logpath: Logfile, das analysiert weren soll
  • maxretry:Anzahl der Fehlversuche, bis die Sperre aktiv wird
  • bantime: Dauer der Sperre in s


Fail2ban:FTP-Server

vi /etc/fail2ban/jail.conf

Nur eine der folgenden Regeln aktivieren, je nachdem, ob bFTPd, VsFTPd oder proFTPd aktiviert wurde. bFTPd:

TBD

VsFTPd:

Für vsFTPd existiert bereits ein Konfigurationseintrag. Diesen anpassen:

[vsftpd-iptables]

enabled  = true
filter   = vsftpd
action   = iptables[name=VSFTPD, port=ftp, protocol=tcp]
           sendmail-whois[name=VSFTPD, dest=you@mail.com]
logpath  = /opt/var/log/vsftpd.log
maxretry = 3
bantime  = 300

ProFTPd:

Für proFTPd existiert bereits ein Konfigurationseintrag. Diesen anpassen:

[proftpd-iptables]

enabled  = true
filter   = proftpd
action   = iptables[name=ProFTPD, port=ftp, protocol=tcp]
           sendmail-whois[name=ProFTPD, dest=you@mail.com]
logpath  =/var/log/messages     (siehe Hinweis unten)
maxretry = 3
bantime  = 300

Falls proFTPd für SSL eingerichtet wurde, den proFTPd-Abschnitt folgendermaßen abändern:

[proftpd-iptables]

enabled  = true
filter   = proftpd
action   = iptables-multiport[name=ProFTPD, port="ftp,ftpext", protocol=tcp]
           iptables[name=ProFTPD, port="60019:60049", protocol=tcp]
           sendmail-whois[name=ProFTPD, dest=you@mail.com]
logpath  =/var/log/messages     (siehe Hinweis unten)
maxretry = 3
bantime  = 300


Hinweis:
Falls Syslog-NG installiert ist, empfiehlt es sich, den Pfad zum Log-File für proFTPD abzuändern:
logpath  =/var/log/auth.log

In diesem File protokolliert proFTPd alle erfolgreichen und gescheiterten Login-Versuche. Das File enthält deutlich weniger Logeinträge und somit verbraucht das scannen des Files deutlich weniger Zeit und Ressourcen als zum scannen von /var/log/messages nötig wäre.


Fail2ban:Imap-Server

Ein →Imap-Server kann mittels Fail2ban ebenfalls geschützt werden. Für Cyrus ist leider keine Definition in jail.conf vorhanden. Weiterhin ist ein sog. Filter nötig.

Anlegen des Filters:

vi /etc/fail2ban/filter.d/cyrus-imap.conf

Folgende Zeilen einfügen:

# Fail2Ban configuration file
#
# Author: Author: Jan Wagner <waja@cyconet.org>
#
# $Revision: 551 $
#

[Definition]

# Option:  failregex
# Notes.:  regex to match the password failures messages in the logfile. The
#          host must be matched by a group named "host". The tag "<HOST>" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P<host>\S+)
# Values:  TEXT
#
failregex = : badlogin: .*\[<HOST>\] plaintext .*SASL\(-13\): authentication failure: checkpass failed$
            : badlogin: .*\[<HOST>\] LOGIN \[SASL\(-13\): authentication failure: checkpass failed\]$
            : badlogin: .*\[<HOST>\] (?:CRAM-MD5|NTLM) \[SASL\(-13\): authentication failure: incorrect (?:digest|NTLM) response\]$
            : badlogin: .*\[<HOST>\] DIGEST-MD5 \[SASL\(-13\): authentication failure: client response doesn't match what we  generated\]$

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex = 


Erstellen der jail.conf-Definition:

vi /etc/fail2ban/jail.conf

Folgenden Abschnitt ergänzen:

[cyrus-imap]
# 
#
enabled  = true
#
filter   = cyrus-imap
action   = iptables-multiport[name=Cyrus-Imap, port="imap2,imap3,imaps", protocol=tcp]
           sendmail-whois[name=Cyrus-Imap, dest=you@mail.com]
#
logpath  = /var/log/messages
#
maxretry = 3
bantime =300


Fail2ban: Webserver

TBD


Start von Fail2ban

Um Fail2ban zu starten und anzuhalten wird ein Startscript erstellt:

vi /opt/etc/init.d/S31fail2ban

Folgende Zeilen eingeben:

#!/bin/sh
# Startscript fuer den fail2ban Client

case "$1" in
     start)
       echo "Starting IP Trap..."
       #exec /opt/local/bin/fail2ban-client start
       /opt/bin/python2.4 /opt/local/bin/fail2ban-server -x
       /opt/local/bin/fail2ban-client reload
       ;;

      stop)
        echo "Stopping IP Trap... leaving machine wide open now ..."
        /opt/local/bin/fail2ban-client stop
        ;;

      restart)
        $0 stop
        sleep 1
        $0 start
        ;;

      reload)
        exec /opt/local/bin/fail2ban-client reload
        ;;

      *)
        echo "Usage: $0 {start|stop|restart|reload}"
        exit 1
        ;;

esac

Ausführbar machen:

chmod +x /opt/etc/init.d/S31fail2ban


Fail2ban starten:

/opt/etc/init.d/S31fail2ban start

Hinweis zu den Optionen:

  • start: Startet Fail2ban
  • stop: Beendet Fail2ban
  • restart: Beendet und Starttet Fail2ban neu
  • reload: Lädt die Konfiguration (fail2ban.conf und jail.conf) neu, ohne den server zu beenden

Check des Logfiles:

vi /opt/var/log/fail2ban.log

Es sollten keine Fehler vorhanden sein und in etwa so aussehen(je nach Anzahl und Art der jails):

2008-10-18 15:08:43,367 fail2ban.server : INFO   Changed logging target to /opt/var/log/fail2ban.log for Fail2ban v0.8.3
2008-10-18 15:08:43,394 fail2ban.jail   : INFO   Creating new jail 'cyrus-imap'
2008-10-18 15:08:43,405 fail2ban.jail   : INFO   Jail 'cyrus-imap' uses poller
2008-10-18 15:08:44,040 fail2ban.filter : INFO   Added logfile = /var/log/messages
2008-10-18 15:08:44,068 fail2ban.filter : INFO   Set maxRetry = 3
2008-10-18 15:08:44,127 fail2ban.filter : INFO   Set findtime = 600
2008-10-18 15:08:44,165 fail2ban.actions: INFO   Set banTime = 3600
2008-10-18 15:08:45,077 fail2ban.jail   : INFO   Creating new jail 'proftpd-iptables'
2008-10-18 15:08:45,087 fail2ban.jail   : INFO   Jail 'proftpd-iptables' uses poller
2008-10-18 15:08:51,598 fail2ban.filter : INFO   Added logfile = /var/log/messages
2008-10-18 15:08:51,633 fail2ban.filter : INFO   Set maxRetry = 3
2008-10-18 15:08:51,696 fail2ban.filter : INFO   Set findtime = 600
2008-10-18 15:08:51,721 fail2ban.actions: INFO   Set banTime = 3600
2008-10-18 15:08:52,673 fail2ban.filter : INFO   Added logfile = /var/log/messages
2008-10-18 15:08:52,706 fail2ban.filter : INFO   Set maxRetry = 3
2008-10-18 15:08:52,754 fail2ban.filter : INFO   Set findtime = 600
2008-10-18 15:08:52,783 fail2ban.actions: INFO   Set banTime = 600
2008-10-18 15:08:53,405 fail2ban.jail   : INFO   Jail 'cyrus-imap' started
2008-10-18 15:08:53,893 fail2ban.jail   : INFO   Jail 'proftpd-iptables' started

Fail2ban Status anzeigen:

/opt/local/bin/fail2ban-client status

Die Ausgabe sollte in etwa so aussehen:

Status
|- Number of jail:      2
`- Jail list:           cyrus-imap, proftpd-iptables

Hinweis:

Wenn die email-adresse bei den einzelnen 'jails' korrekt eingegeben wurde, dann versendet fail2ban beim Start je eine email pro konfigurierter und gestarteter 'jail'.


Test von Fail2ban

Zum Test von Fail2ban empfiehlt es sich, das fail2ban Log-File permanent zu verfolgen:

tail -f /opt/var/log/fail2ban.log

Ban eines Programms

  • Zu testendes Programm öffnen (z.B. FTP-Programm) und eine Verbindung zur NSLU aufbauen. Allerdings mehrmals falsches Passwort verwenden.
  • Im Log-File muß ein Eintrag in der folgenden Form erscheinen:
2008-10-18 15:26:47,287 fail2ban.actions: WARNING [proftpd-iptables] Ban IP-Adresse
  • Falls email in der 'jail' korrekt konfiguriert wurde, versendet fail2ban eine Hinweismail, mit der IP-Adresse des Angreifers und des Dienstes, der geblockt wurde.
  • Versuchen eine Verbindung (mit korrektem Passwort) aufzubauen. Diese Verbindung darf nun NICHT möglich sein.


UnBan eines Programms

  • Nach Ablauf der "bantime" erscheint der folgende Eintrag im LOG-File:
2008-10-18 16:26:47,835 fail2ban.actions: WARNING [proftpd-iptables] Unban IP-Adresse
  • Evtl. versendet fail2ban eine Hinweismail.
  • Testen, ob Verbindung wieder möglich ist.


Optimieren/Anpassen von Fail2Ban

Nachdem Fail2Ban erfolgreich eingerichtet und getestet wurde, sollten nun einige Anpassungen erfolgen. So wurde z.B. in den einzelnen Jails die Bantime auf 300s (=5Minuten) gesetzt, um den Funktionstest sinnvoll durchführen zu können. Diese Zeit sollte nach erfolgreichem Test (Ban und Unban funktionieren tadellos) für den produktiven Einsatz deutlich erhöht werden - z.B. 3600s oder 7200s, um einen Angreifer deutlich länger auszusperren, bevor dieser erneut Zugriff erhält.

vi /etc/fail2ban/jail.conf

Die bantime von allen Jails, die von Interesse sind, entsprechend anpassen. z.B.

[proftpd-iptables]

enabled  = true
filter   = proftpd
action   = iptables-multiport[name=ProFTPD, port="ftp,ftpext", protocol=tcp]
           iptables[name=ProFTPD, port="60019:60049", protocol=tcp]
           sendmail-whois[name=ProFTPD, dest=you@mail.com]
logpath  =/var/log/messages
maxretry = 3
bantime  = 7200

In den bisher definierten Jails werden bestimmte Ports bzw. Portbereiche gesperrt, nachdem ein Angriffsversuch erkannt wurde. Es kann aber auch eine komplette IP-Adresse gesperrt werden, sodass keinerlei Zugriff mehr von dieser IP-Adresse aus auf die NSLU möglich ist, bis die bantime abgelaufen ist. Dies geschieht mit der action iptables-allports. Z.B. proFTPd-Beispiel von oben:

[proftpd-iptables]

enabled  = true
filter   = proftpd
action   = iptables-allports[name=ProFTPD]
           sendmail-whois[name=ProFTPD, dest=you@mail.com]
logpath  =/var/log/messages
maxretry = 3
bantime  = 7200  

Insbesondere, wenn iptables-allports verwendet wird, ist es relativ einfach möglich, sich selbs komplett auszusperren, solange bis die bantime abgelaufen ist. Aus diesem Grund ist es möglich, Hosts von der Überwachung auszunehmen - z.B. lokale PC's im LAN. Dies kann mittels Parameter ignoreip (am Anfang der Konfigurationsdatei jail.conf) erfolgen. z.B.

ignoreip = 127.0.0.1 192.168.1.111 192.168.1.222

Diese Zeile schließt Hosts mit den IP-Adressen 127.0.0.1 (localhost, NSLU), 192.168.1.111 und 192.168.1.222 von der Überwachung aus.

Mit dem Parameter findtime wird bestimmt, innerhalb welcher Überwachungszeit die Anzahl der Fehlversuche (maxretry) überwacht wird, bevor das 'Banereignis' eintritt. Z.B.

findtime  = 3600
maxretry  = 3

bedeutet, dass ein Host gebannt wird, sobald er ein Passwort innerhalb von 3600s 3x falsch eingibt.

Hinweis:

Die Parameter, die im oberen globalen Bereich angegeben werden können in den einzelnen Jail-Definitionen wieder überschrieben werden, falls diese angegeben werden. So wäre es z.B. möglich maxretry im globalen Bereich auf 5 zu setzen und in den einzelnen Jails keine Angabe zu machen, mit Ausnahme z.B. in proFTPd. Damit wäre für alle Jails maxretry=5 und nur für proFTPd maxretry=3.

Nachdem alle Änderungen durchgeführt wurden, muß die Konfiguration neu eingelesen werden:

/opt/etc/init.d/S31fail2ban reload