Statefull Router Script (iptables)
Statefull Router Script (iptables)
Hallo, ich baue grad ein Linux home router auf und habe ein IPTables Skript geschrieben.
An die Experten an euch, sind die Regeln für Input output forward soweit sicher?
Habe ich die statefull kette richtig eingebaut und ist es in der output kette sinvoll noch statefull einzubauen und stimmt die Reihenfolge der Regeln?
Bin mir da noch nicht so ganz sicher. Wär nett wenn ihr mir das Skript absegnen und verbessern oder ergänzen könnt. Auf dem Router läuft bis jetzt Debian mit bind9, isc-dhcp, ssh, ntp und ntop. snort und apache soll später noch drauf.
#!/bin/bash
# Variblen Festlegen
I=/sbin/iptables
INT=eth0
EXT=eth1
# Routing aktivieren
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "Firewall wird gestartet ..."
# alte Ketten Löschen
echo "Alte Ketten werden gelöscht..."
$I -F
$I -t nat -F
$I -t nat --delete-chain
$I --delete-chain
# default Regeln
echo "Loopback device erlauben"
$I -P INPUT DROP
$I -P OUTPUT DROP
$I -P FORWARD DROP
# loobback device
$I -A INPUT -i lo -j ACCEPT
$I -A OUTPUT -o lo -j ACCEPT
# Masquieren des WAN
echo "Masquerade $EXT"
# Dynamische IP vom Provider wird Maskiert
$I -t nat -A POSTROUTING -o $EXT -j MASQUERADE
# Statefulll Kette und Regeln
echo "Statefull Kette"
$I -N statefull
$I -F statefull
$I -P statefull DROP
$I -A statefull -m state --state ESTABLISHED,RELATED -j ACCEPT
$I -A statefull -m state --state NEW,INVALID -m limit -j LOG --log-prefix "Bad traffic to Firewall: "
$I -A statefull -m state --state NEW,INVALID -j DROP
$I -A statefull -p all -j LOG --log-prefix "Default statefull DROP: "
$I -A statefull -p all -j DROP
# INPUT Kette
echo "Input Kette"
$I -A INPUT -i $INT -p tcp --dport 22 -j ACCEPT
$I -A INPUT -i $INT -p icmp --icmp-typ echo-request -j ACCEPT
$I -A INPUT -i $INT -p udp --dport 53 -j ACCEPT
$I -A INPUT -i $INT -p tcp --dport 53 -j ACCEPT
$I -A INPUT -i $INT -p tcp --dport 3000 -j ACCEPT #ntop
$I -A INPUT -i $INT -j statefull
$I -A INPUT -i $EXT -p tcp --dport 113 -j LOG --log-prefix "ident prope:"
$I -A INPUT -i $EXT -p tcp --dport 113 -j REJECT
$I -A INPUT -i $EXT -j statefull
$I -A INPUT -p all -j LOG --log-prefix "ACHTUNG INPUT DROP: "
$I -A INPUT -p all -j DROP
echo "Output Kette"
# OUTPUT KETTE
$I -A OUTPUT -p all -j ACCEPT
$I -A OUTPUT -j statefull
$I -A OUTPUT -p all -j LOG --log-prefix "ACHTUNG OUTPUT DROP: "
$I -A OUTPUT -p all -j DROP
echo forward
# Forward Kette
$I -A FORWARD -i $INT -o $EXT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
$I -A FORWARD -i $INT -o $EXT -p all -j ACCEPT
$I -A FORWARD -i $INT -o $EXT -p all -j statefull
$I -A FORWARD -i $EXT -o $INT -p all -j statefull
$I -A FORWARD -p all -j DROP
An die Experten an euch, sind die Regeln für Input output forward soweit sicher?
Habe ich die statefull kette richtig eingebaut und ist es in der output kette sinvoll noch statefull einzubauen und stimmt die Reihenfolge der Regeln?
Bin mir da noch nicht so ganz sicher. Wär nett wenn ihr mir das Skript absegnen und verbessern oder ergänzen könnt. Auf dem Router läuft bis jetzt Debian mit bind9, isc-dhcp, ssh, ntp und ntop. snort und apache soll später noch drauf.
#!/bin/bash
# Variblen Festlegen
I=/sbin/iptables
INT=eth0
EXT=eth1
# Routing aktivieren
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "Firewall wird gestartet ..."
# alte Ketten Löschen
echo "Alte Ketten werden gelöscht..."
$I -F
$I -t nat -F
$I -t nat --delete-chain
$I --delete-chain
# default Regeln
echo "Loopback device erlauben"
$I -P INPUT DROP
$I -P OUTPUT DROP
$I -P FORWARD DROP
# loobback device
$I -A INPUT -i lo -j ACCEPT
$I -A OUTPUT -o lo -j ACCEPT
# Masquieren des WAN
echo "Masquerade $EXT"
# Dynamische IP vom Provider wird Maskiert
$I -t nat -A POSTROUTING -o $EXT -j MASQUERADE
# Statefulll Kette und Regeln
echo "Statefull Kette"
$I -N statefull
$I -F statefull
$I -P statefull DROP
$I -A statefull -m state --state ESTABLISHED,RELATED -j ACCEPT
$I -A statefull -m state --state NEW,INVALID -m limit -j LOG --log-prefix "Bad traffic to Firewall: "
$I -A statefull -m state --state NEW,INVALID -j DROP
$I -A statefull -p all -j LOG --log-prefix "Default statefull DROP: "
$I -A statefull -p all -j DROP
# INPUT Kette
echo "Input Kette"
$I -A INPUT -i $INT -p tcp --dport 22 -j ACCEPT
$I -A INPUT -i $INT -p icmp --icmp-typ echo-request -j ACCEPT
$I -A INPUT -i $INT -p udp --dport 53 -j ACCEPT
$I -A INPUT -i $INT -p tcp --dport 53 -j ACCEPT
$I -A INPUT -i $INT -p tcp --dport 3000 -j ACCEPT #ntop
$I -A INPUT -i $INT -j statefull
$I -A INPUT -i $EXT -p tcp --dport 113 -j LOG --log-prefix "ident prope:"
$I -A INPUT -i $EXT -p tcp --dport 113 -j REJECT
$I -A INPUT -i $EXT -j statefull
$I -A INPUT -p all -j LOG --log-prefix "ACHTUNG INPUT DROP: "
$I -A INPUT -p all -j DROP
echo "Output Kette"
# OUTPUT KETTE
$I -A OUTPUT -p all -j ACCEPT
$I -A OUTPUT -j statefull
$I -A OUTPUT -p all -j LOG --log-prefix "ACHTUNG OUTPUT DROP: "
$I -A OUTPUT -p all -j DROP
echo forward
# Forward Kette
$I -A FORWARD -i $INT -o $EXT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
$I -A FORWARD -i $INT -o $EXT -p all -j ACCEPT
$I -A FORWARD -i $INT -o $EXT -p all -j statefull
$I -A FORWARD -i $EXT -o $INT -p all -j statefull
$I -A FORWARD -p all -j DROP
Du flushst/löschst die Chains, erst dann stellst du die Policies auf DROP - in der Zwischenzeit ist die Firewall offen. Stateful schreibt man mit einem l. Selbstangelegte Chains haben keine Policy. Output-Filterregeln sind fast immer sinnlos, kannst du weglassen. Deine Forward-Regeln haben ein ACCEPT auf alles von innen nach außen, die nachfolgende Regel in dieser Richtung wird daher ignoriert. Regeln -j DROP am Ende einer Built-in-Chain sind sinnlos, dafür gibt es die Policy. Man braucht neu angelegte Chains nicht zu flushen. Deine "Stateful"-Chain ended mit DROP, die Log-Targets in den aufrufenden Chains werden daher nie erreicht. Du blockierst ICMP bis auf echo, was Probleme verursachen wird - blockiere stattdessen *ausschließlich* ICMP type 5 (Redirect), die anderen ICMP-Nachrichten werden gebraucht und tun auch nichts schlimmes.
Janka
Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
Ich mag die Schreie.
diese Log Regel in der Iinput Chain geht hab ich mit dem heise portscanner getesten und die meldung 'ident probe' kommt in var log messages
$I -A INPUT -i $EXT -p tcp --dport 113 -j LOG --log-prefix "ident probe:"
$I -A INPUT -i $EXT -p tcp --dport 113 -j REJECT
die nachvolgende aber nicht oder?
$I -A INPUT -i $EXT -j stateful
$I -A INPUT -p all -j LOG --log-prefix "ACHTUNG INPUT DROP: "
$I -A INPUT -p all -j DROP
also das drop kann man weglassen weil dann eh die default policy greift und das log sollte ein default log sein aber wenn das eh nie ankommt, hmm
$I -A INPUT -i $EXT -p tcp --dport 113 -j LOG --log-prefix "ident probe:"
$I -A INPUT -i $EXT -p tcp --dport 113 -j REJECT
die nachvolgende aber nicht oder?
$I -A INPUT -i $EXT -j stateful
$I -A INPUT -p all -j LOG --log-prefix "ACHTUNG INPUT DROP: "
$I -A INPUT -p all -j DROP
also das drop kann man weglassen weil dann eh die default policy greift und das log sollte ein default log sein aber wenn das eh nie ankommt, hmm
Deine Regel -j LOG "ACHTUNG INPUT DROP:" kann nicht erreicht werden, weil die chain "stateful" mit -pall -j DROP ended. Danach ist das Paket weg, es erreicht die aufrufende Chain nicht mehr.
Das Stateful-Package-Filtering ist ja gerade für weitergeleitete Pakete gedacht. Im übrigen ist -m state veraltet, das macht jetzt das conntrack-Modul. Die Verbindungsabbrüche für weitergeleitete Pakete hast du höchstwahrscheinlich, weil du im Input ICMP blockierst. Die ICMP-Nachrichten des übergeordneten Gateways z.B. für das Fragmentieren von weitergeleiteten Paketen muss nämlich dein Gateway verarbeiten, und das verbietest du ihm.
Wenn dein Kernel ohnehin ICMP Typ 5 ignoriert, brauchst du gar keine ICMP-Regeln.
Janka
Das Stateful-Package-Filtering ist ja gerade für weitergeleitete Pakete gedacht. Im übrigen ist -m state veraltet, das macht jetzt das conntrack-Modul. Die Verbindungsabbrüche für weitergeleitete Pakete hast du höchstwahrscheinlich, weil du im Input ICMP blockierst. Die ICMP-Nachrichten des übergeordneten Gateways z.B. für das Fragmentieren von weitergeleiteten Paketen muss nämlich dein Gateway verarbeiten, und das verbietest du ihm.
Wenn dein Kernel ohnehin ICMP Typ 5 ignoriert, brauchst du gar keine ICMP-Regeln.
Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
Ich mag die Schreie.
ahhh verstehe 
das Logging mit IP-Tables muss man ja immer speziell angeben, also z.b mit --dport 22 -j LOG etc, wenn mann also detailierte logging infos haben will welche ports abgefragt oder blockiert werden, dann werden das ja ganz schön viele regeln. Da macht es doch mehr sinn alles weitere mit snort zu überwachen und zu loggen oder?
gruß hardia

das Logging mit IP-Tables muss man ja immer speziell angeben, also z.b mit --dport 22 -j LOG etc, wenn mann also detailierte logging infos haben will welche ports abgefragt oder blockiert werden, dann werden das ja ganz schön viele regeln. Da macht es doch mehr sinn alles weitere mit snort zu überwachen und zu loggen oder?
gruß hardia
Vor allem kann Snort viel komplizierte Angriffsszenarien erkennen als man das mit einem simplen iptables-Aufruf könnte. Für ein Home-Router braucht man beides nicht, denn *was machst du*, wenn du einen Angriff von außen erkennst? Schulterzucken? Diese Werkzeuge sind dafür gedacht, Netzwerke innerhalb deines Einflussbereichs zu überwachen, damit du das Problem am Quellrechner abstellen kannst, statt die Pakete nur zu blockieren.
Janka
Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
Ich mag die Schreie.
Jupp da hast du recht. Ich find es nur sehr interessant zu sehen was im Netzwerk so los ist
Hab das Skript nochmal überarbeitet. Müsste schon besser sein, es können bestimmt noch einige Sicherheitsrelevannte oder Netzverkehr optimierende Regeln rein.
#!/bin/bash
# Variblen Festlegen
I=/sbin/iptables
INT=eth0
EXT=eth1
# default Regeln
$I -P INPUT DROP
$I -P OUTPUT DROP
$I -P FORWARD DROP
# Routing aktivieren
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "Firewall wird gestartet ..."
# alte Ketten Löschen
echo "Alte Ketten werden gelöscht..."
$I -F
$I -t nat -F
$I -t nat --delete-chain
$I --delete-chain
# loobback device
echo "Loopback device erlauben"
$I -A INPUT -i lo -j ACCEPT
$I -A OUTPUT -o lo -j ACCEPT
# Masquieren des WAN
echo "Masquerade $EXT"
# Dynamische IP vom Provider wird Maskiert
$I -t nat -A POSTROUTING -o $EXT -j MASQUERADE
# Statefulll Kette und Regeln
echo "Stateful Kette"
$I -N stateful
$I -A stateful -m state --state ESTABLISHED,RELATED -j ACCEPT
$I -A stateful -m state --state NEW,INVALID -m limit -j LOG --log-prefix "Bad traffic to Firewall: "
$I -A stateful -m state --state NEW,INVALID -j DROP
$I -A stateful -p all -j LOG --log-prefix "Default stateful DROP: "
$I -A stateful -p all -j DROP
# INPUT Kette
echo "Input Regeln starten"
$I -A INPUT -i $INT -p icmp -j ACCEPT
$I -A INPUT -i $INT -p tcp --dport 22 -j ACCEPT
$I -A INPUT -i $INT -p udp --dport 53 -j ACCEPT
$I -A INPUT -i $INT -p tcp --dport 53 -j ACCEPT
$I -A INPUT -i $INT -p tcp --dport 3000 -j ACCEPT
$I -A INPUT -i $INT -j stateful
$I -A INPUT -i $EXT -p tcp --dport 113 -j LOG --log-prefix "ACHTUNG ->ident prope: "
$I -A INPUT -i $EXT -p tcp --dport 113 -j REJECT
$I -A INPUT -i $EXT -j stateful
# OUTPUT KETTE
echo "Output Regeln starten"
$I -A OUTPUT -p all -j ACCEPT
$I -A OUTPUT -j stateful
# Forward Kette
echo Forward Regeln starten
$I -A FORWARD -i $INT -o $EXT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
$I -A FORWARD -i $INT -o $EXT -p icmp -j ACCEPT
$I -A FORWARD -i $INT -o $EXT -p tcp -j ACCEPT
$I -A FORWARD -i $INT -o $EXT -p udp -j ACCEPT
$I -A FORWARD -i $INT -o $EXT -p all -j stateful
$I -A FORWARD -i $EXT -o $INT -p all -j stateful

#!/bin/bash
# Variblen Festlegen
I=/sbin/iptables
INT=eth0
EXT=eth1
# default Regeln
$I -P INPUT DROP
$I -P OUTPUT DROP
$I -P FORWARD DROP
# Routing aktivieren
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "Firewall wird gestartet ..."
# alte Ketten Löschen
echo "Alte Ketten werden gelöscht..."
$I -F
$I -t nat -F
$I -t nat --delete-chain
$I --delete-chain
# loobback device
echo "Loopback device erlauben"
$I -A INPUT -i lo -j ACCEPT
$I -A OUTPUT -o lo -j ACCEPT
# Masquieren des WAN
echo "Masquerade $EXT"
# Dynamische IP vom Provider wird Maskiert
$I -t nat -A POSTROUTING -o $EXT -j MASQUERADE
# Statefulll Kette und Regeln
echo "Stateful Kette"
$I -N stateful
$I -A stateful -m state --state ESTABLISHED,RELATED -j ACCEPT
$I -A stateful -m state --state NEW,INVALID -m limit -j LOG --log-prefix "Bad traffic to Firewall: "
$I -A stateful -m state --state NEW,INVALID -j DROP
$I -A stateful -p all -j LOG --log-prefix "Default stateful DROP: "
$I -A stateful -p all -j DROP
# INPUT Kette
echo "Input Regeln starten"
$I -A INPUT -i $INT -p icmp -j ACCEPT
$I -A INPUT -i $INT -p tcp --dport 22 -j ACCEPT
$I -A INPUT -i $INT -p udp --dport 53 -j ACCEPT
$I -A INPUT -i $INT -p tcp --dport 53 -j ACCEPT
$I -A INPUT -i $INT -p tcp --dport 3000 -j ACCEPT
$I -A INPUT -i $INT -j stateful
$I -A INPUT -i $EXT -p tcp --dport 113 -j LOG --log-prefix "ACHTUNG ->ident prope: "
$I -A INPUT -i $EXT -p tcp --dport 113 -j REJECT
$I -A INPUT -i $EXT -j stateful
# OUTPUT KETTE
echo "Output Regeln starten"
$I -A OUTPUT -p all -j ACCEPT
$I -A OUTPUT -j stateful
# Forward Kette
echo Forward Regeln starten
$I -A FORWARD -i $INT -o $EXT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
$I -A FORWARD -i $INT -o $EXT -p icmp -j ACCEPT
$I -A FORWARD -i $INT -o $EXT -p tcp -j ACCEPT
$I -A FORWARD -i $INT -o $EXT -p udp -j ACCEPT
$I -A FORWARD -i $INT -o $EXT -p all -j stateful
$I -A FORWARD -i $EXT -o $INT -p all -j stateful
Willst du wirklich "Domain"-Pakete nur vom *internen* Netz erlauben? Ich denke, das sollte eher das externe Netz sein, damit die DNS-Antworten durchkommen. Ebenso ICMP, das musst du von *außen* erlauben, damit der übergeordnete Gateway deinem Gateway Nachrichten schicken kann. Du brauchst keine Output-Regeln, setze die Policy einfach auf ACCEPT und gut ist. Ebenso kannst du alle Forward-Regeln von innen nach außen dahingehend vereinfachen, dass in dieser Richtung alles erlaubt ist. Übrig bleibt dort nur das TCPMSS-Target
Janka
Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
Ich mag die Schreie.
also das externe interface ist direkt am Internet, bzw am Kabelmodem. eth1 erhält von kabeldeutschland per dhcp eine öffentliche IP Adresse,die dns server Adressen und das default gateway. Und meine clients aus dem 192.168.0 Netz bekommen dann per dhcp die interne Adresse von eth0 (192.168.0.1) als DNS Server und Gateway. Ich will doch nicht mein bind server nach aussen öffnen oder? icmp kann man drüber nachdenken
output und forward kann ich noch vereinfachen stimmt
übrigens ersetze ich meinen alten dlink router durch dieses Gerät das ich grad aufbaue
https://www.olimex.com/Products/OLinuXi ... e-hardware
+ 2. usb lankarte und wlan-stick für wlan das später auch noch in die iptables Regeln rein soll, aber erstmal nur eth0 und eth1
bis jetzt läuft also dhcpd, bind und ntop
output und forward kann ich noch vereinfachen stimmt

übrigens ersetze ich meinen alten dlink router durch dieses Gerät das ich grad aufbaue

+ 2. usb lankarte und wlan-stick für wlan das später auch noch in die iptables Regeln rein soll, aber erstmal nur eth0 und eth1

bis jetzt läuft also dhcpd, bind und ntop
Hab mich verguckt. Du musst in der Input-Chain --sport 53 erlauben, damit der Gateway DNS-Antworten vom übergeordneten Gateway erhält, nicht --dport. Wobei das über -m state schon abgedeckt wird.hardia hat geschrieben:Ich will doch nicht mein bind server nach aussen öffnen oder?
dnsmasq ist bekannt?bis jetzt läuft also dhcpd, bind und ntop
Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
Ich mag die Schreie.
jupp ist bekannt, mach es mit bind und dhcpd zur übung um noch vertrauter mit der configuration der dienste zu werden. dnsmasq wär warscheinlich resourcenschonender
Inkl. der Vereinfachung wie du sagtest von Forward und Output scheint das soweit erstmal ok zu sein.
Also Output -P ACCEPT
und
# Forward Kette
#INT-EXT
$I -A FORWARD -i $INT -o $EXT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
$I -A FORWARD -i $INT -o $EXT -p all -j ACCEPT
$I -A FORWARD -i $INT -o $EXT -p all -j stateful
#EXT-INT
$I -A FORWARD -i $EXT -o $INT -p all -j stateful
und in der stateful kette -m state --state durch das neuere -m conntrack --ctstate ersetzen

Inkl. der Vereinfachung wie du sagtest von Forward und Output scheint das soweit erstmal ok zu sein.
Also Output -P ACCEPT
und
# Forward Kette
#INT-EXT
$I -A FORWARD -i $INT -o $EXT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
$I -A FORWARD -i $INT -o $EXT -p all -j ACCEPT
$I -A FORWARD -i $INT -o $EXT -p all -j stateful
#EXT-INT
$I -A FORWARD -i $EXT -o $INT -p all -j stateful
und in der stateful kette -m state --state durch das neuere -m conntrack --ctstate ersetzen
Eine Sache hätt ich noch wenn ich ports weiterleiten will mit z.B.
iptables -t nat -A PREROUTING -i $EXT -p tcp --dport 80 -j DNAT --to 192.168.0.10:81
Also port 80 an dem Gateway auf ein Webserver mit port 81 weiterleiten will, wie baue ich sowas in diesem skript am besten ein? Habs versucht hat aber noch nicht funktioniert
iptables -t nat -A PREROUTING -i $EXT -p tcp --dport 80 -j DNAT --to 192.168.0.10:81
Also port 80 an dem Gateway auf ein Webserver mit port 81 weiterleiten will, wie baue ich sowas in diesem skript am besten ein? Habs versucht hat aber noch nicht funktioniert