Hinweis: Dieses Script stammt aus 2009 und nutzt iptables auf einem Debian mit Kernel 2.4. Die Konzepte sind zeitlos, aber die Umsetzung ist veraltet. Heute nimmt man nftables statt iptables. Trotzdem: Wer versteht was hier passiert, versteht auch nftables.
Das Setup
Dedizierte Firewall-Maschine mit drei Netzwerkkarten. Ein Interface zum Internet (PPPoE), zwei für interne Netze mit unterschiedlichen Berechtigungen. Default-Policy auf allen Chains: DROP. Alles was nicht explizit erlaubt ist, wird verworfen.
Grundstruktur
#!/bin/bash # Module laden modprobe ip_tables modprobe ip_conntrack modprobe ip_conntrack_ftp modprobe ip_nat_ftp # Tabellen leeren iptables -F iptables -t nat -F iptables -t mangle -F iptables -X iptables -t nat -X iptables -t mangle -X # Default: Alles verwerfen iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP
Custom Chains für Logging
Eigene Chains für sauberes Logging. Jedes verworfene Paket wird mit Prefix geloggt bevor es gedroppt wird:
# MY_REJECT: Protokollieren und zurückweisen iptables -N MY_REJECT iptables -A MY_REJECT -p tcp -m limit --limit 7200/h -j LOG --log-prefix "REJECT TCP " iptables -A MY_REJECT -p tcp -j REJECT --reject-with tcp-reset iptables -A MY_REJECT -p udp -m limit --limit 7200/h -j LOG --log-prefix "REJECT UDP " iptables -A MY_REJECT -p udp -j REJECT --reject-with icmp-port-unreachable # MY_DROP: Portscans stillschweigend verwerfen iptables -N MY_DROP iptables -A MY_DROP -m limit --limit 7200/h -j LOG --log-prefix "PORTSCAN DROP " iptables -A MY_DROP -j DROP
Stealth Scan Detection
Ungültige TCP-Flag-Kombinationen erkennen und verwerfen. Kein normaler Client setzt SYN+FIN gleichzeitig oder schickt ein Paket ohne Flags:
# Keine Flags gesetzt iptables -A INPUT -p tcp --tcp-flags ALL NONE -j MY_DROP # SYN und FIN gleichzeitig iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j MY_DROP # SYN und RST gleichzeitig iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j MY_DROP # FIN ohne ACK iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j MY_DROP
Connection Tracking und NAT
Stateful Firewall: Bestehende und zugehörige Verbindungen durchlassen, neue nur aus dem internen Netz erlauben. NAT per MASQUERADE für den Internetzugang:
# Loopback erlauben iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # Ausgehend: Alles erlauben iptables -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT # Forwarding: Neue Verbindungen nur von innen iptables -A FORWARD -i ! ppp0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # NAT für interne Netze iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.0.0/24 -j MASQUERADE
Traffic Shaping mit tc
Mit tc (traffic control) und iptables -t mangle lässt sich die Bandbreite pro Client oder Netz begrenzen. iptables markiert die Pakete, tc ordnet sie in Queues ein:
# HTB Queueing Discipline auf dem internen Interface tc qdisc add dev eth2 root handle 1:0 htb default 10 tc class add dev eth2 parent 1:0 classid 1:1 htb rate 150kbit ceil 250kbit tc filter add dev eth2 parent 1: prio 0 protocol ip handle 1 fw flowid 1:1 # Pakete per iptables markieren iptables -t mangle -A FORWARD -s 192.168.100.0/24 -j MARK --set-mark 1
Kernel-Hardening
Am Ende des Scripts werden Kernel-Parameter gesetzt die über die Firewall hinausgehen:
# SYN-Cookies gegen SYN-Flood echo 1 > /proc/sys/net/ipv4/tcp_syncookies # Source-Routing deaktivieren for i in /proc/sys/net/ipv4/conf/*; do echo 0 > $i/accept_source_route; done # Redirects ignorieren for i in /proc/sys/net/ipv4/conf/*; do echo 0 > $i/accept_redirects; done # Martian-Pakete loggen for i in /proc/sys/net/ipv4/conf/*; do echo 1 > $i/log_martians; done # ICMP-Ping ignorieren echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all # TCP-FIN-Timeout gegen DoS echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
Die Konzepte aus diesem Script gelten unverändert: Default DROP, Stateful Tracking, Custom Chains für Logging, Stealth Scan Detection, Kernel-Hardening. Nur die Syntax hat sich geändert. Wer heute eine Linux-Firewall baut, nimmt nft statt iptables und erspart sich die Modprobe-Zeilen. Für IPv6 braucht man eine eigene Regelkette, damals mit ip6tables, heute in nftables integriert.
Fragen? Einfach melden.
Schreibe einen Kommentar