Frage zu IPTables Firewall

Cazawhi

Geht ein
Registriert
13 Feb. 2016
Beiträge
357
Ort
im Funkloch
Servus,

Ich habe 'ne Maschine laufen, die mein eigenes Netzwerk aufbaut (ein Adapter klemmt am Router, der andere an nem Switch) und alle Clients vor dem Router bündelt sozusagen (via Forwarding eth0->eth1).
Gleichzeitig hostet diese Maschine auch eine Owncloud, einen dnsmasq/DNS und einen SSH Server. Somit sind dauerhaft die Ports 67, 68, 22, 53 und 80 offen und die Dienste auf beiden Adaptern erreichbar. Da mein Router ne potenzielle Schwachstelle ist, möchte ich gegenüber dem Router die Ports schließen, weiß allerdings nicht, wie ich sie nur auf eth0 schließe.

Hier folgt der INPUT-Teil meiner derzeitigen IPTables Firewall:
[src=bash]# Accept loopback
/sbin/iptables -A INPUT -i lo -j ACCEPT

# === Open Ports === #

# dnsmasq
/sbin/iptables -A INPUT -m state --state NEW -p udp --dport 67 -j ACCEPT
/sbin/iptables -A INPUT -m state --state NEW -p udp --dport 68 -j ACCEPT

# dns
/sbin/iptables -A INPUT -m state --state NEW -p tcp --dport 53 -j ACCEPT
/sbin/iptables -A INPUT -m state --state NEW -p udp --dport 53 -j ACCEPT

# ssh
/sbin/iptables -A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT

# http
/sbin/iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT

# === Other === #

# Accept ESTABLISHED
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Accept ICMP
/sbin/iptables -A INPUT -p icmp -j ACCEPT

# Drop invalid
/sbin/iptables -A INPUT -m state --state INVALID -j DROP

# Reject remaining
/sbin/iptables -A INPUT -j REJECT


exit 0
[/src]

Wäre super wenn mir jemand erklären könnte, wie ich das anpasse.

Danke schonmal und Liebe Grüße. :)
 
@Cazawhi: Der Schalter, eine Abfrage auf einen Adapter zu machen, ist -i für INPUT und -o für OUTPUT. Relevant wird das hauptsächlich bei Forwarding und Input:

[src=bash]iptables -A INPUT -i eth0 --dport 80 -j REJECT
iptables -A INPUT -i eth1 --dport 80 -j ACCEPT[/src]

Hast du Forwarding aktiv, kann sich ein Angreifer da aber immer noch Infos holen, wenn er statt der IP von eth0 die IP von eth1 anspricht. Damit lässt er sich quasi "durchstellen" und hat serverseitig als Input-Adapter eth1, der ja antworten darf. Um das zu verhindern fehlt ein:
[src=bash]iptables -A FORWARD -i eth0 --dport 80 -j REJECT[/src]

Soll er von außen hingegen reinkommen können, weil etwa andere Webserver in diesem Netz erreichbar sein sollen, musst du das abändern:
[src=bash]iptables -A FORWARD -i eth0 -d [IP von eth1] --dport 80 -j REJECT[/src]

Generell macht man sich das aber wesentlich einfacher, indem man nur erlaubte Verbindungen definiert und alle anderen einfach rejected. In deinem Fall würde ich sowieso deine komplette Firewall umschreiben (auch weil du ziemlich viel redundant hast):

[src=bash]# === General stuff ===

# Drop invalid
iptables -A INPUT -m state --state INVALID -j DROP

# Accept loopback
iptables -A INPUT -i lo -j ACCEPT

# Accept ESTABLISHED
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Accept ICMP
iptables -A INPUT -p icmp -j ACCEPT


# === Open Ports === #

# dnsmasq - DHCP auf allen Adaptern
iptables -A INPUT -p udp --dport 67 -j ACCEPT
# ODER auf einem davon
iptables -A INPUT -i eth1 -p udp --dport 67 -j ACCEPT
# Port 68 ist der Clientport, denke aber auch daran, dass du OUTPUT damit richtig schreiben musst, d. h. eine Antwort auch zulassen musst.

# dns - auf allen Adaptern
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT

# ssh - auf allen Adaptern
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# http - auf allen Adaptern
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# ODER auf einem davon
iptables -A INPUT -i eth1 -p tcp --dport 80 -j ACCEPT


# === Final statements ===

# Reject remaining
iptables -A INPUT -j REJECT


exit 0[/src]
Die ganzen state-NEW-Geschichten hab ich rausgeschmissen, weil du nach einem DROP von INVALID und ACCEPT von RELATED und ESTABLISHED sowieso nur noch NEW vorliegen hast - die Prüfung ist daher Zeitverschwendung. Allgemein macht es Sinn, die Pakete, die am Seltensten sind (also NEW oder INVALID), ganz am Ende abzuhandeln, sofern sie kein mögliches Sicherheitsproblem darstellen (INVALID). Merke: Je mehr Pakete bereits im zweiten Statement abgehandelt werden können, desto weniger Prüfungen musst du nachher noch machen, was dir Ressourcen schont.

Alles in Allem hast du hier ein Drittel der Firewall, weil du OUTPUT und FORWARDING bislang völlig vernachlässigst, was auf einem routenden Device sträflich ist.
 
Zuletzt bearbeitet:
  • Thread Starter Thread Starter
  • #3
Erstmal danke für die Komplettlösung. :)

Habe wie beschrieben eben nur den INPUT-Teil hochgeladen, weil ich mir dachte, das würde reichen um mein Problem zu lösen. Wenn das schon so ein Desaster darstellt gebe ich dir noch das Forward-Skript, bei Output gibt es nicht viel hochzuladen, der wird einfach akzeptiert.

(enx000ec6d9e908 ist mein bisherig der Einfachheit halber "eth1")

[src=bash]#!/bin/bash

# Reject forwarding into webserver in localnet
iptables -A FORWARD -i eth0 --dport 80 -j REJECT

# Forward eth0 enx000
iptables -A FORWARD -i eth0 -o enx000ec6d9e908 -s 192.168.0.0/24 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -i enx000ec6d9e908 -o eth0 -s 192.168.0.0/24 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# Exit
exit 0[/src]
 
Also was ich hier sehe ist, dass du einfach deinen Traffic aus beiden Richtungen heraus vollständig akzeptierst - das ist nett, aber nicht clever, wenn du hinterher NAT betreibst und DHCP und und und...

Was du eigentlich möchtest, ist nur von innen nach außen, nicht von außen nach innen. Und die Conntrack-Statements kannst du dir sparen, das macht er eh (bzw. sie sind das, was er macht, wenn du --state nimmst, letzteres ist nämlich der Alias dafür).

Basic Router setup ist etwa sowas hier:

[src=bash]# === General Stuff ===

# Standard
iptables -A FORWARD -m state --state INVALID -j DROP
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# Dont forward Broadcasts
# Outside
iptables -A FORWARD -d 192.168.0.255 -j DROP
# Inside
iptables -A FORWARD -d 192.168.1.255 -j DROP
# Multicast
iptables -A FORWARD -d 224.0.0.0/4 -j DROP
# DHCP inquiry broadcast
iptables -A FORWARD -d 255.255.255.255 -j DROP


# === Special stuff ===

# Forward Inside (eth1) to Outside (eth0)
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT


# === Final statements ===

# Log REJECTs (debugging)
iptables -A FORWARD -m limit --limit 2/min -j LOG --log-prefix "[iptables] FORWARD REJECT: " --log-level 4
# Don't let anything else be forwarded
iptables -A FORWARD -j REJECT

# NAT everything talking to Outside (eth0)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE[/src]

Wenn jetzt was nicht so läuft, wie du es dir erwartest, musst du nur das syslog nach "[iptables] FORWARD REJECT" greppen, und siehst, was auf der Forward-Chain rejected wurde.

P.S.: OUTPUT solltest du trotzdem schreiben, gerade um zu verhindern, dass sich DHCP oder DNS an den falschen Stellen meldet, Broadcasts ins externe Netz gehen etc. Überleg dir, was genau dein Server wohin schicken dürfen soll, und lass genau das zu, alles andere rejectest du mit Log. Falls irgendwas dann nicht funktioniert, kannst du es am Log nachprüfen und ggfs. ändern.
 
Zuletzt bearbeitet:
  • Thread Starter Thread Starter
  • #5
Du ersparst mir grad viel zu viel Arbeit, hui! :)

Wann versendet einer meiner Clients oder mein Server denn einen Broadcast?
Ich kenne Broadcasts nur um z.B alle momentan laufenden Spiele-Server in CS zu finden, was machen die im lokalen Netz?

[src=bash][iptables] FORWARD REJECT: IN=eth0 OUT=eth1 MAC=xxx SRC=172.217.17.99 DST=192.168.2.10 LEN=84 TOS=0x00 PREC=0x00 TTL=55 ID=0 PROTO=ICMP TYPE=0 CODE=0 ID=16437 SEQ=50[/src]

Wenn ich das richtig verstehe, kommen die Antworten aus dem Internet nicht zurück.

Sollten die Antworten nicht ESTABLISHED und RELATED sein, da ich zuerst eine Anfrage gestellt habe?
 
Zuletzt bearbeitet:
@Cazawhi: PROTO=ICMP ist Ping. Wer ist denn 192.168.2.10, und soll er von extern gepingt werden können? Eigentlich sollte das, wenn er intern ist, nicht der Fall sein.
 
  • Thread Starter Thread Starter
  • #7
Ist die Antwort auf eine Ping-Anfrage von 192.168.2.10.

192.168.2.10 ist mein Laptop im Netzwerk mit dem ich zum Testen schnell was angepingt habe und keine Antwort bekommen habe.


//edit

Hab' den Übeltäter gefunden!

War das Leerzeichen nach dem Komma bei ESTABLISHED,RELATED :P
 
Zuletzt bearbeitet:
Zurück
Oben