System: SuSE Linux 9.1
Der Rechner, auf dem diese Regeln laufen, hat einen DSL-Zugang ins Internet und eine Netzwerkkarte zum lokalen Netz. Das lokale Netz soll gegen das Internet abgeschirmt werden, der Zugriff ins Internet erfolgt nur über Proxies, ssh ins Internet beispielsweise mit Hilfe von Socks. Wenn IPSec gestartet ist, ist der Zugriff vom Notebook auf Ressourcen im lokalen Netz möglich.
Ich habe verschiedene benutzerdefinierte Chains verwendet:
Außerdem habe ich soweit möglich das multiport-Modul verwendet, was die Pflege des Skripts sehr vereinfacht. Neue Dienste müssen nur bei den Ports eingetragen werden. In den einzelnen Chains ist jeweils nur das erste IP-Paket aufgeführt, um die weiteren IP-Pakete kümmert sich das state-Modul.
Da es beim Kernel 2.6.x bei IPSec kein Interface ipsec0 mehr gibt, sind auch die Regeln für IPSec geändert, dort kommt jetzt das mangle-Modul zum Einsatz, das Pakete markiert. Die Markierung wird ausgewertet, um Pakete zu erkennen, die zum IPSec-Tunnel gehören.
#!/bin/bash
# Copyright (c) 2004 Björn Lotz
#
# Author: Björn Lotz
#
# /etc/init.d/ipt_rules
#
# and symbolic its link
#
# /sbin/rcipt_rules
#
# System startup script for the packet filter
#
### BEGIN INIT INFO
# Provides: packetfilter
# Required-Start: $network $syslog
# Required-Stop: $network $syslog
# Default-Start: 3 5
# Default-Stop: 0 1 2 4 6
# Description: Start iptables-Firewall
### END INIT INFO
. /etc/rc.status
# First reset status of this service
rc_reset
case "$1" in
start|restart|reload)
echo "Die Packet-Filter-Regeln werden gesetzt ..."
######### Variablen:
# Interfaces
DSL=ppp0
LAN=eth0
# Adressen
LOKALE_IP=192.168.0.15
LOKALES_NETZ=192.168.0.0/24
# Nameserver
NS1=194.25.2.129
NS2=212.185.252.201
# Zeitserver
# T-Online, ntp1.t-online.de
#TIME1=195.145.119.188
# Braunschweig
TIME1=192.53.103.103
TIME2=192.53.103.104
# Ports
UNPRIV="1024:65535"
TRACEROUTE="33434:33999"
# Private Adressbereiche
CLASSA=10.0.0.0/8
CLASSB=172.16.0.0/12
CLASSC=192.168.0.0/16
######### Kernelparameter (Barth, Firewall-Buch p209)
# Routing erforderlich für IPSec und für die Port-Umleitung,
# da aufgrund einer Änderung am SuSE-Kernel 2.6.5,
# diese nur funktioniert, wenn Routing eingeschaltet ist |-(
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
# Schutz vor ICMP-Redirect-Paketen aktivieren
for f in /proc/sys/net/ipv4/conf/*/accept_redirects
do
echo 0 > $f
done
# Blocken von Source-Routed-Paketen
for f in /proc/sys/net/ipv4/conf/*/accept_source_route
do
echo 0 > $f
done
# Loggen von gespooften Paketen, Source-Routed-Paketen und Redirect-Paketen
# geht nicht mit IP-Sec
#for f in /proc/sys/net/ipv4/conf/*/log_martians; do
# echo 1 > $f
#done
# Schutz vor IP-Spoofing aktivieren
# geht nicht mit IP-Sec
#for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
# echo 1 > $f
#done
######### Default-Policy setzen und vorhandene Regeln l�chen
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
iptables -F
iptables -t nat -F
iptables -X
######### fr Stateful Inspection von ftp:
modprobe ip_conntrack_ftp
######### Lokale Prozesse
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
####################################################################################
# #
# Eigene Chains #
# #
####################################################################################
######### Logging #######################################
# Log und Reject, bzw Drop, wenn's viele Pakete sind
iptables -N my_drop
# zuerst mal die e-donkey-Pakete und die von verschiedenen Würmern verwerfen,
# die anscheinend nicht auf tcp-reset reagieren
iptables -A my_drop -p TCP --syn --dport 135:137 \
-m limit --limit 10/hour --limit-burst 2 -j LOG --log-prefix "DROP-TCP-SYN "
iptables -A my_drop -p TCP --syn --dport 135:137 \
-m limit --limit 1/s -j REJECT --reject-with tcp-reset
iptables -A my_drop -p TCP --syn --dport 135:137 -j DROP
iptables -A my_drop -p TCP --syn --dport 445 \
-m limit --limit 10/hour --limit-burst 2 -j LOG --log-prefix "DROP-TCP-SYN "
iptables -A my_drop -p TCP --syn --dport 445 \
-m limit --limit 1/s -j REJECT --reject-with tcp-reset
iptables -A my_drop -p TCP --syn --dport 445 -j DROP
iptables -A my_drop -p TCP --syn --dport 4662 \
-m limit --limit 10/hour --limit-burst 2 -j LOG --log-prefix "DROP-TCP-SYN "
iptables -A my_drop -p TCP --syn --dport 4662 \
-m limit --limit 1/s -j REJECT --reject-with tcp-reset
iptables -A my_drop -p TCP --syn --dport 4662 -j DROP
iptables -A my_drop -p TCP --syn -j LOG --log-prefix "DROP-TCP-SYN "
iptables -A my_drop -p TCP --syn \
-m limit --limit 5/s -j REJECT --reject-with tcp-reset
iptables -A my_drop -p TCP --syn -j DROP
iptables -A my_drop -p TCP -j LOG --log-prefix "DROP-TCP "
iptables -A my_drop -p TCP \
-m limit --limit 5/s -j REJECT --reject-with tcp-reset
iptables -A my_drop -p TCP -j DROP
iptables -A my_drop -p UDP -j LOG --log-prefix "DROP-UDP "
iptables -A my_drop -p UDP \
-m limit --limit 5/s -j REJECT --reject-with icmp-port-unreachable
iptables -A my_drop -p UDP -j DROP
iptables -A my_drop -p ICMP -j LOG --log-prefix "DROP-ICMP "
iptables -A my_drop -p ICMP -j DROP
iptables -A my_drop -j LOG --log-prefix "DROP-PROTO-ETC "
iptables -A my_drop \
-m limit --limit 5/s -j REJECT --reject-with icmp-proto-unreachable
iptables -A my_drop -j DROP
####################################################################################
# #
# EXTERNE Verbindungen INTERNET --> Rechner (INPUT-Interface $DSL) #
# #
####################################################################################
# In diese Chain kommt alles mit INPUT-Interface $DSL
iptables -N internet_in
# TCP, Internet --> Rechner: ###
#iptables -A internet_in -m mark --mark 10 -j LOG --log-prefix "MARKIERT--- "
# ssh - 22 (auch via 443), mit Logging
iptables -A internet_in -p TCP --syn --dport 22 -j LOG --log-prefix ">>> Zugriff
iptables -A internet_in -p TCP --syn --sport $UNPRIV -m multiport --dports 22 \
-j ACCEPT
# Nicht erforderlich als eigene Regel, aber der Deutlichkeit halber:
# Jeglicher sonstige TCP-Verbindungsaufbau von außen ist verboten.
iptables -A internet_in -p TCP -i $DSL --syn -j my_drop
# Ebenso: Schutz vor IP-Spoofing
iptables -A internet_in -s $CLASSA -j my_drop
iptables -A internet_in -s $CLASSB -j my_drop
#iptables -A internet_in -s $CLASSC -j my_drop
# UDP, Internet --> Rechner: ###
# isakmp - 500
iptables -A internet_in -p UDP --sport 500 --dport 500 -j ACCEPT
iptables -A internet_in -j my_drop
####################################################################################
# #
# EXTERNE Verbindungen Rechner --> INTERNET (OUTPUT-Interface $DSL) #
# #
####################################################################################
# In diese chain kommt alles mit OUTPUT-Interface $DSL
iptables -N internet_out
### TCP, Rechner --> Internet: ###
# ftp - 21
# smtp - 25
iptables -A internet_out -p TCP --syn -m multiport --dports 21,25 --sport $UNPRIV \
-j ACCEPT
# FTP-Proxy-Datenkanal, passiv, von hohen Ports zu hohen Ports (von hier ins I-Net)
# Für FTP bräuchte es das nicht, das wrde ftp-conntrack übernehmen,
# aber so sind auch Verbindungen von hier z.B. zu pgp-Keyservern möglich.
iptables -A internet_out -p TCP --syn --sport $UNPRIV --dport $UNPRIV -j ACCEPT
### UDP, Rechner --> Internet: ###
# time - 37, nur zu bestimmten Servern, deshalb eigene Regeln
# dns - 53
# isakmp - 500
# traceroute - Portrange, deshalb eigene Regel
iptables -A internet_out -p UDP --sport $UNPRIV -m multiport --dports 53 -j ACCEPT
iptables -A internet_out -p UDP -d $TIME1 --sport $UNPRIV --dport 37 -j ACCEPT
iptables -A internet_out -p UDP -d $TIME2 --sport $UNPRIV --dport 37 -j ACCEPT
iptables -A internet_out -p UDP --dport $TRACEROUTE -j ACCEPT
iptables -A internet_out -p UDP --sport 500 --dport 500 -j ACCEPT
iptables -A internet_out -j my_drop
####################################################################################
# #
# INTERNE Verbindungen INTRA --> Rechner (INPUT-Interface $LAN) #
# #
####################################################################################
# In diese chain kommt alles mit INPUT-Interface $LAN
iptables -N intra_in
# TCP, Internes Netz --> Rechner:
# ftp - 21
# smtp - 25
# dns - 53
# http - 80
# http-proxy - 3128
iptables -A intra_in -p TCP --dport 1080 -j my_counter
iptables -A intra_in -p TCP --syn --sport $UNPRIV \
-m multiport --dports 21,22,25,53,80,3128 -j ACCEPT
######### UDP, Intranet --> Rechner:
# time - 37
# dns - 53
# dhcp - 67
iptables -A intra_in -p UDP --sport $UNPRIV -m multiport --dports 37,53,67 \
-j ACCEPT
iptables -A intra_in -j my_drop
####################################################################################
# #
# INTERNE Verbindungen Rechner --> INTRA (OUTPUT Interface $LAN) #
# #
####################################################################################
# In diese Chain kommt alles mit OUTPUT-Interface $LAN
iptables -N intra_out
### TCP, Rechner --> Internes Netz: ###
# ssh - 22
# ident - 113
iptables -A intra_out -p TCP --syn --sport $UNPRIV -m multiport --dports 22,113 \
-j ACCEPT
### UDP, Rechner --> Internes Netz: ###
# dhcp - 67
# syslog - 514, zum Loghost
iptables -A intra_out -p UDP -d 192.168.0.1 --sport 514 --dport 514 -j ACCEPT
# anscheinend funktioniert bei DHCP das Connection Tracking nicht richtig,
# da das erste Packet von 0.0.0.0 kommt, die Antwort aber an eine
# bestimmte IP-Nummer geht. Daher noch folgende Regel:
iptables -A intra_out -p UDP --sport 67 -j ACCEPT
iptables -A intra_out -j my_drop
####################################################################################
# #
# IPSec #
# #
####################################################################################
iptables -N ipsec_for
# forwarding von Paketen aus dem Tunnel und zurück
iptables -A ipsec_for -i $DSL -o $LAN -m mark --mark 10 -j ACCEPT
# Oder mit dem Policy-Modul, was den Vorteil hat, dass man auch den
# Traffic in den Tunnel kontrollieren kann, d.h. Verbindungen vom
# Gateway zum Roadwarrior möglich sind:
# iptables -A FORWARD -i $DSL -m policy --dir in --pol ipsec \
# --mode tunnel --proto esp -j ACCEPT
# iptables -A FORWARD -o $DSL -m policy --dir out --pol ipsec \
# --mode tunnel --proto esp -j ACCEPT
iptables -A ipsec_for -j my_drop
####################################################################################
# #
### --- Ende benutzerdefinierte Chains --- ###
# #
####################################################################################
####################################################################################
# #
# Allgemeine Regeln #
# #
####################################################################################
# Umleitung auf ftp-Proxy:
# FTP
iptables -A PREROUTING -t nat -p tcp -i $LAN -d 0/0 --dport 21 -j REDIRECT
# IPSec-Pakete markieren:
# (Kann auch entfallen, siehe bei ipsec-Abschnitt)
iptables -t mangle -A PREROUTING -p 50 -i $DSL -j MARK --set-mark 10
######### Generelle Regeln für Folgepakete (2. und alle weiteren) ##################
# INPUT-Chain
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# OUTPUT-Chain
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# FORWARD-Chain
iptables -A FORWARD -i $DSL -o $LAN -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -o $DSL -i $LAN -m state --state ESTABLISHED,RELATED -j ACCEPT
####################################################################################
# #
# ICMP #
# #
####################################################################################
######### ICMP
# ICMP ping: 8 und 0 ausgehend erlaubt, alle Interfaces
iptables -A OUTPUT -p ICMP --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p ICMP --icmp-type echo-reply -j ACCEPT
# ICMP ping: 8 und 0 eingehend auf eth+ erlaubt
iptables -A INPUT -p ICMP -i $LAN --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -p ICMP -o $LAN --icmp-type echo-reply -j ACCEPT
# ICMP ping: 8 und 0 eingehend auf DSL-Karte in Grenzen erlaubt
iptables -A INPUT -p ICMP -i $DSL \
-m limit --limit 5/s --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p ICMP -i $DSL --icmp-type echo-request -j my_drop
iptables -A OUTPUT -p ICMP -o $DSL --icmp-type echo-reply -j ACCEPT
######### Die folgenden Typen sollten eigentlich durch den Parameter RELATED
# des Modules state abgedeckt sein:
# ICMP source quench 4
#iptables -A OUTPUT -p ICMP --icmp-type source-quench -j ACCEPT
#iptables -A INPUT -p ICMP --icmp-type source-quench -j my_drop
# ICMP time exceeded 11
#iptables -A OUTPUT -p ICMP --icmp-type time-exceeded -j ACCEPT
#iptables -A INPUT -p ICMP --icmp-type time-exceeded -j ACCEPT
# ICMP parameter problem 12
#iptables -A OUTPUT -p ICMP --icmp-type parameter-problem -j ACCEPT
#iptables -A INPUT -p ICMP --icmp-type parameter-problem -j ACCEPT
# ICMP destination unreachable 3
#iptables -A OUTPUT -p ICMP --icmp-type fragmentation-needed -j ACCEPT
#iptables -A INPUT -p ICMP --icmp-type fragmentation-needed -j ACCEPT
#iptables -A OUTPUT -p ICMP --icmp-type port-unreachable -j ACCEPT
#iptables -A INPUT -p ICMP --icmp-type port-unreachable -j ACCEPT
####################################################################################
# #
# Verteilung auf die jeweiligen benutzerdefinierten Chains #
# #
####################################################################################
iptables -A INPUT -i $LAN -j intra_in
iptables -A INPUT -i $DSL -p 50 -j ACCEPT
iptables -A INPUT -i $DSL -j internet_in
iptables -A OUTPUT -o $DSL -j internet_out
iptables -A OUTPUT -o $LAN -j intra_out
iptables -A FORWARD -i $DSL -m mark --mark 10 -j ipsec_for
# oder, falls im ipsec-Abschnitt mit -m policy gearbeitet wird:
# iptables -A FORWARD -i $DSL -j ipsec_for
# iptables -A FORWARD -o $DSL -j ipsec_for
######### Alles was bis hierher kam wird gelogged und dann verworfen bzw. nur zurckgewiesen.
iptables -A INPUT -j my_drop
iptables -A FORWARD -j my_drop
iptables -A OUTPUT -j my_drop
echo -n "Die Packet-Filter-Regeln sind jetzt gesetzt."
# Remember status and be verbose
rc_status -v
;;
stop)
echo "Die Packet-Filter-Regeln werden gelöscht ... "
iptables -F
iptables -t nat -F
iptables -X
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
echo -n "Die Packet-Filter-Regeln erlauben jetzt wieder alles."
echo 0 > /proc/sys/net/ipv4/ip_forward
echo -n "Routing ist ausgeschaltet."
# Remember status and be verbose
rc_status -v
;;
status)
echo "Die Filterregeln: "
iptables -v -n -L
iptables -v -n -t nat -L POSTROUTING
iptables -v -n -t nat -L PREROUTING
# Status has a slightly different for the status command:
# 0 - service running
# 1 - service dead, but /var/run/ pid file exists
# 2 - service dead, but /var/lock/ lock file exists
# 3 - service not running
# NOTE: checkproc returns LSB compliant status values.
#checkproc $FOO_BIN
#rc_status -v
;;
*)
echo "Usage: $0 {start|restart|reload|stop|status}"
exit 1
;;
esac
rc_exit