Statefull Router Script (iptables)

Message
Author
hardia
Posts: 15
Joined: 04. Mar 2014 10:00

Statefull Router Script (iptables)

#1 Post by hardia »

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

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#2 Post by Janka »

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
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

hardia
Posts: 15
Joined: 04. Mar 2014 10:00

#3 Post by hardia »

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

hardia
Posts: 15
Joined: 04. Mar 2014 10:00

#4 Post by hardia »

kann man nur stateful in der forward regel richtig anwenden? Bei mir gabs da ständig verbindungsabrüche mit ssh oder downloads, deswegen habe ich einfach erstmal auf accept all $INT to $EXT geschaltet.

aber stateful $EXT to $INT ist doch richtig in der forward oder?

Gruß hardia

hardia
Posts: 15
Joined: 04. Mar 2014 10:00

#5 Post by hardia »

und noch was zu icmp:

also icmp type 5 ist redirect

root@olimex:/etc/init.d# cat /proc/sys/net/ipv4/conf/all/accept_redirects
0

ist bei mir nicht erlaubt im kern. wenn ich icmp also in iptables komplett erlaube ist doch type 5 trotzdem noch durch den kern verboten oder?

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#6 Post by Janka »

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
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

hardia
Posts: 15
Joined: 04. Mar 2014 10:00

#7 Post by hardia »

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

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#8 Post by Janka »

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
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

hardia
Posts: 15
Joined: 04. Mar 2014 10:00

#9 Post by hardia »

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

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#10 Post by Janka »

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
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

hardia
Posts: 15
Joined: 04. Mar 2014 10:00

#11 Post by hardia »

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

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#12 Post by Janka »

hardia wrote:Ich will doch nicht mein bind server nach aussen öffnen oder?
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.
bis jetzt läuft also dhcpd, bind und ntop
dnsmasq ist bekannt?

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

hardia
Posts: 15
Joined: 04. Mar 2014 10:00

#13 Post by hardia »

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

hardia
Posts: 15
Joined: 04. Mar 2014 10:00

#14 Post by hardia »

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

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#15 Post by Janka »

Ist denn Port 80 von Extern für Forward offen?

Hier eine Grafik des Paketflusses.

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

Post Reply