Prinzipiell sieht das schon sehr vernünftig aus. Welche Distribution benutzt du?
godsdisciple wrote:Code: Select all
# Firewallscript mit iptables
#
#!/bin/bash
INTERN=192.168.100.0/255
Das muss 192.168.100.0/24 heißen.
Code: Select all
INTERN-DEV=eth0
EXTERN-DEV=ppp0
IPTABLES=/sbin/iptables
NAT_FORWARDING_TCP_PORT="21,25,80,110,143,443,993,5190,5222,6667,6668,1863"
INPUT_INTERNET_TCP_PORT="443,22"
case $1 in
start)
$0 stop
$IPTABLES -F INPUT
$IPTABLES -F FORWARD
$IPTABLES -F OUTPUT
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP
Flushen der Regeln immer erst *nachdem* die Policy auf DROP gestellt wurde! Sonst gibt es eine kurze Lücke, in der die Firewall alles akzeptiert. Die Lücke kann auch verlängert werden, wenn man das Skript suspendiert oder der OOM-Killer zuschlägt.
Außerdem ist es sinnvoll, nicht nur die Filter-Chains sondern auch alle anderen Chains zu flushen, wenn man mit Masquerading/Mangling rumbaut.
Code: Select all
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "5" >/proc/sys/net/ipv4/icmp_ratelimit
echo "1" > /proc/sys/net/ipv4/conf/$EXTERN-DEV/rp_filter
#Defines the INPUT rules
$IPTABLES -t filter -A INPUT -i lo -j ACCEPT
Sinnvoll.
Code: Select all
$IPTABLES -t filter -A INPUT -p icmp -j ACCEPT
ICMP zu akzeptieren ist sinnvoll, nur Nachrichten vom Typ "redirect" sollte man filtern, da dadurch die Routingtabellen von außen manipuliert werden können.
Code: Select all
$IPTABLES -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Sinnvoll.
Code: Select all
$IPTABLES -t filter -A INPUT -s 0.0.0.0/0 -p tcp -m multiport --dport $INPUT_INTERNET_TCP_PORT -j ACCEPT
Dies erlaubt alle Dienste, die oben in INPUT_INTERNET_TCP_PORT eingestellt sind. Diese Liste solltest du an die Dienste anpassen, die ihr zum Internet hin freigeben wollt. Es kann sinnvoll sein, ssh auf einem anderen Port als Port 22 laufen zu lassen, da hier relativ viele automatisierte Einbruchsversuche stattfinden. Generell den direkten root-Login per ssh abschalten, am besten Login per Kennwort generell verbieten, alles per Key machen.
Code: Select all
$IPTABLES -t filter -A INPUT -p tcp ! --syn -j ACCEPT #syn packages
Der Kommentar ist falsch. Diese Regel erlaubt alle *nicht*-SYN-Pakete, also alle Pakete, die zu einer bestehenden TCP-Verbindung gehören. Eigentlich ist das doppelt gemoppelt, denn zuvor werden ja über State-Matching ohnehin alle Pakete erlaubt, die zu einer bestehenden Verbindung gehören.
Code: Select all
$IPTABLES -t filter -A INPUT -i $EXTERN_DEV -s 195.58.160.0/16 -p udp -j ACCEPT #Nameserver
$IPTABLES -t filter -A INPUT -i $EXTERN_DEV -s 195.58.161.0/16 -p udp -j ACCEPT #Nameserver
$IPTABLES -t filter -A INPUT -i $EXTERN_DEV -p udp --dport 53 -j ACCEPT
Der Adressbereich des Nameservers ist Quark. Entweder muss das 195.58.160.0/24 oder 195.58.0.0/16 sein. der zweite entsprechend.
Die erste und zweite Regel erlaubt alle UDP-Pakete aus diesem Netzbereich, sollte man auf --dport 53 beschränken.
Außerdem erlaubt die dritte Regel Pakete von *allen* Rechnern überhaupt, solange diese nur auf UDP Port 53 kommen. Musst du streichen, sonst sind Regel 1 und 2 sinnlos.
Code: Select all
#Defines the OUTPUT rules
$IPTABLES -t filter -A OUTPUT -p icmp -j ACCEPT
$IPTABLES -t filter -A OUTPUT -o lo -j ACCEPT
$IPTABLES -t filter -A OUTPUT -o $EXTERN_DEV -d 0.0.0.0/0 -p tcp -m multiport --dport $NAT_FORWARDING_TCP_PORT -j ACCEPT #Outgoing ftp
$IPTABLES -t filter -A OUTPUT -p tcp ! --syn -j ACCEPT #syn packages
Es ist meist nicht sinnvoll, ausgehende Pakete zu filtern, es sei denn, du willst deine Benutzer gängeln -- und dann suchen und finden sie eine Lücke (z.B.via HTTPS-Proxy). Stell einfach die Output-Policy auf ACCEPT.
Code: Select all
#Defines the NAT rules
$IPTABLES -A POSTROUTING -t nat -p tcp -o $EXTERN_DEV -s $INTERN -j MASQUERADE
$IPTABLES -A POSTROUTING -t nat -p udp -o $EXTERN_DEV -s $INTERN -j MASQUERADE
$IPTABLES -A POSTROUTING -t nat -p icmp -o $EXTERN_DEV -s $INTERN -j MASQUERADE
Sinnvoll. Wobei der kanonische Weg eigentlich ist, einfach alle Protokolle zu masqueraden.
Code: Select all
$IPTABLES -A FORWARD -p tcp ! --syn -j ACCEPT
$IPTABLES -A FORWARD -i $INTERN_DEV -o $EXTERN_DEV -s $INTERN -p tcp -m multiport --dport $NAT_FORWARDING_TCP_PORT -j ACCEPT
$IPTABLES -A FORWARD -m state --state NEW -p icmp -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
Das ist jetzt wieder zu kompliziert und gleichzeitig lückenhaft. Grundproblem: Die Forward-Chain ist sowohl für Pakete vom Internet in das interne Netz als auch andersrum zuständig. Es wird hier nun aber zwischen rein und raus nur anhand der IP-Adresse und anderer Inhalte des Paketes unterschieden. Viel einfacher und wasserdichter ist es, das per Bindung an das Input-Interface (-i) zu machen. Und außerdem die Portregeln von innen nach außen wegwerfen, Benutzergängelung!
Code: Select all
$IPTABLES -A FORWARD -i $INTERN_DEV -o $EXTERN_DEV -s $INTERN -p tcp -j LOG --log-prefix "~~FILTER~~ FORWARD TCP! " --log-ip-options
$IPTABLES -A FORWARD -i $INTERN_DEV -o $EXTERN_DEV -s $INTERN -p udp -j LOG --log-prefix "~~FILTER~~ FORWARD UDP! " --log-ip-options
Musst du selbst wissen, ob du diese Logs überhaupt lesen willst. Da steht nur drin, ob ein Benutzer einen "verbotenen" Port benutzen wollte. Sinnlos.
Code: Select all
echo "Firewall & Routing activated"
;;
stop)
$IPTABLES -t filter -F INPUT
$IPTABLES -t filter -F OUTPUT
$IPTABLES -t filter -F FORWARD
$IPTABLES -t nat -F POSTROUTING
Wieder dasselbe wie oben: Erst Policy einstellen, dann Chains flushen.
Code: Select all
;;
restart)
$0 start
;;
*)
echo "Usage: $0 {startwd|stop|restart}"
;;
esac
Vielen Dank für eure Hilfe. Könnt ihr mir ausserdem sagen, ob es möglich ist, dieses Script so abzuändern, dass es für 2 Modems gilt. Muss ich diese dann über die interfaces als z.B. ppp0 und ppp1 einrichten?
Sollen die zwei Modems alternativ benutzt werden oder gleichzeitig? Wenn letzteres, musst du auch noch die Kanalbündelung einrichten.
Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.