Iptables Netze absichern: Unterschied zwischen den Versionen
| (4 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 94: | Zeile 94: | ||
'''sysctl -p''' | '''sysctl -p''' | ||
| + | == Weitere Tabellen == | ||
| + | |||
| + | * Eine Skizze über die Reihenfolge der Ketten | ||
| + | * Als erstes greift der Prerouting | ||
| + | * Je nachdem wie geroutet wird greift dann entweder Input- oder Forward | ||
| + | * Falls ein lokaler Prozess ein Paket sendet, dann greift der Output | ||
| + | * Als letztes kann man das Paket mit dem Postrouting beeinflußen | ||
| + | |||
| + | {{#drawio:iptables-nat.png}} | ||
| + | |||
| + | == SNAT == | ||
| + | |||
| + | * Rechner in einem LAN können nicht ohne weiteres mit dem WAN kommunizieren, da an die lokale IP-Adresse der Rechner im LAN nicht von außen geroutet werden kann. | ||
| + | * Um eine Internetverbindung aufzubauen, muss die Adresse aus dem LAN in eine öffentliche umgeschrieben werden. | ||
| + | |||
| + | '''vim /etc/iptables-snat.sh''' | ||
| + | |||
| + | <pre> | ||
| + | #!/bin/bash | ||
| + | |||
| + | # Variablen | ||
| + | WAN_IF="ens18" | ||
| + | DMZ_IF="ens19" | ||
| + | LAN_IF="ens20" | ||
| + | LAN_NET="192.168.4.0/24" | ||
| + | WAN_IP="10.82.232.11" | ||
| + | |||
| + | # Regelwerk löschen | ||
| + | iptables -F | ||
| + | iptables -X | ||
| + | iptables -t nat -F | ||
| + | iptables -t nat -X | ||
| + | |||
| + | # Default Policies | ||
| + | iptables -P INPUT DROP | ||
| + | iptables -P FORWARD DROP | ||
| + | iptables -P OUTPUT DROP | ||
| + | |||
| + | # Loopback erlauben | ||
| + | iptables -A INPUT -i lo -j ACCEPT | ||
| + | iptables -A OUTPUT -o lo -j ACCEPT | ||
| + | |||
| + | # ICMP erlauben | ||
| + | iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT | ||
| + | |||
| + | # SSH und andere notwendige Ports | ||
| + | iptables -A INPUT -p tcp --dport 22 -j ACCEPT | ||
| + | |||
| + | # Etablierte Verbindungen | ||
| + | iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT | ||
| + | iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED,NEW -j ACCEPT | ||
| + | iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT | ||
| + | |||
| + | # SNAT für ausgehende Pakete vom LAN ins WAN | ||
| + | iptables -t nat -A POSTROUTING -s $LAN_NET -o $WAN_IF -j SNAT --to-source $WAN_IP | ||
| + | |||
| + | # Logging | ||
| + | iptables -A INPUT -j LOG --log-prefix "--iptables-drop-input--" | ||
| + | iptables -A OUTPUT -j LOG --log-prefix "--iptables-drop-output--" | ||
| + | iptables -A FORWARD -j LOG --log-prefix "--iptables-drop-forward--" | ||
| + | </pre> | ||
| + | |||
| + | == Neu verwendete Syntax in iptables == | ||
| + | |||
| + | * Interface des herausgehenden Paketes: | ||
| + | |||
| + | '''-o <device_name>''' | ||
| + | |||
| + | * match auf Quelladresse des Pakets: | ||
| + | |||
| + | '''-s <source_ip>''' | ||
| + | |||
| + | * Quelladresse umschreiben: | ||
| + | |||
| + | '''-j SNAT --to-source <new_source_ip>''' | ||
| + | == Portforwarding == | ||
| + | |||
| + | * Um auf bestimmte Funktionen eines Rechners hinter einer Firewall zugreifen zu können, müssen die dazugehörenden Ports entsprechend weitergeleitet werden. | ||
| + | * Hierbei kann es ein anderer, nicht-standard Port der Firewall sein. | ||
| + | |||
| + | '''vim /etc/iptables-portfwd.sh''' | ||
| + | |||
| + | <pre> | ||
| + | #!/bin/bash | ||
| + | |||
| + | # Variablen | ||
| + | WAN_IF="ens18" | ||
| + | LAN_IF="ens20" | ||
| + | LAN_NET="192.168.4.0/24" | ||
| + | WAN_IP="10.82.232.11" | ||
| + | WEBSERVER="192.168.4.12" | ||
| + | |||
| + | # Regelwerk löschen | ||
| + | iptables -F | ||
| + | iptables -X | ||
| + | iptables -t nat -F | ||
| + | iptables -t nat -X | ||
| + | |||
| + | # Default Policies | ||
| + | iptables -P INPUT DROP | ||
| + | iptables -P FORWARD DROP | ||
| + | iptables -P OUTPUT DROP | ||
| + | |||
| + | # Loopback erlauben | ||
| + | iptables -A INPUT -i lo -j ACCEPT | ||
| + | iptables -A OUTPUT -o lo -j ACCEPT | ||
| + | |||
| + | # ICMP erlauben | ||
| + | iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT | ||
| + | |||
| + | # SSH von außen | ||
| + | iptables -A INPUT -p tcp --dport 9922 -j ACCEPT | ||
| + | |||
| + | # Etablierte Verbindungen | ||
| + | iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT | ||
| + | iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED,NEW -j ACCEPT | ||
| + | iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT | ||
| + | |||
| + | # Weiterleitung zu internem Webserver | ||
| + | iptables -A FORWARD -p tcp -d $WEBSERVER --dport 22 -i $WAN_IF -j ACCEPT | ||
| + | iptables -A FORWARD -p tcp -d $WEBSERVER --dport 80 -i $WAN_IF -j ACCEPT | ||
| + | |||
| + | # Portweiterleitung | ||
| + | iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 9922 -j DNAT --to-destination $WEBSERVER:22 | ||
| + | iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 80 -j DNAT --to-destination $WEBSERVER:80 | ||
| + | |||
| + | # SNAT für Rückweg | ||
| + | iptables -t nat -A POSTROUTING -s $LAN_NET -o $WAN_IF -j SNAT --to-source $WAN_IP | ||
| + | |||
| + | # Logging | ||
| + | iptables -A INPUT -j LOG --log-prefix "--iptables-drop-input--" | ||
| + | iptables -A OUTPUT -j LOG --log-prefix "--iptables-drop-output--" | ||
| + | iptables -A FORWARD -j LOG --log-prefix "--iptables-drop-forward--" | ||
| + | </pre> | ||
| + | |||
| + | * Nun kann man per SSH auf den Rechner hinter der Firewall über Port 9922 der Firewall zugreifen… | ||
| + | '''ssh user@WEBSERVER -p 9922''' | ||
| + | |||
| + | * ... und HTTP-Requests an den Rechner hinter der Firewall schicken | ||
| + | '''curl WEBSERVER''' | ||
| + | |||
| + | == Neu verwendete Syntax in iptables == | ||
| + | |||
| + | * matche die Ziel-IP-Adresse: | ||
| + | |||
| + | '''-d <target_ip>''' | ||
| + | |||
| + | * Ziel-IP-Adresse auf eine andere umschreiben: | ||
| + | |||
| + | '''-j DNAT --to-destination <new_target_ip>''' | ||
| + | |||
| + | = Absichern von Netzen = | ||
| + | |||
| + | Momentan wird nichts vom LAN zum WAN weitergeleitet. Um nur bestimmte Anwendungen zu erlauben, kann man die für diese designierten Ports freischalten. | ||
| + | |||
| + | '''vim /etc/iptables-absichern.sh''' | ||
| + | |||
| + | <pre> | ||
| + | #!/bin/bash | ||
| + | |||
| + | # Variablen | ||
| + | WAN_IF="ens18" | ||
| + | LAN_IF="ens20" | ||
| + | LAN_NET="192.168.4.0/24" | ||
| + | WAN_IP="10.82.232.11" | ||
| + | WEBSERVER="192.168.4.12" | ||
| + | |||
| + | # Regelwerk löschen | ||
| + | iptables -F | ||
| + | iptables -X | ||
| + | iptables -t nat -F | ||
| + | iptables -t nat -X | ||
| + | |||
| + | # Default Policies | ||
| + | iptables -P INPUT DROP | ||
| + | iptables -P FORWARD DROP | ||
| + | iptables -P OUTPUT DROP | ||
| + | |||
| + | # Loopback erlauben | ||
| + | iptables -A INPUT -i lo -j ACCEPT | ||
| + | iptables -A OUTPUT -o lo -j ACCEPT | ||
| + | |||
| + | # ICMP erlauben | ||
| + | iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT | ||
| + | |||
| + | # SSH von außen | ||
| + | iptables -A INPUT -p tcp --dport 9922 -j ACCEPT | ||
| + | |||
| + | # Etablierte Verbindungen | ||
| + | iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT | ||
| + | iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED,NEW -j ACCEPT | ||
| + | iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT | ||
| + | |||
| + | # Zugriff vom WAN auf Webserver | ||
| + | iptables -A FORWARD -p tcp -d $WEBSERVER --dport 22 -i $WAN_IF -j ACCEPT | ||
| + | iptables -A FORWARD -p tcp -d $WEBSERVER --dport 80 -i $WAN_IF -j ACCEPT | ||
| + | |||
| + | # Zugriff vom LAN ins WAN – nur bestimmte Dienste | ||
| + | iptables -A FORWARD -p icmp -s $LAN_NET -i $LAN_IF -o $WAN_IF --icmp-type echo-request -m conntrack --ctstate NEW -j ACCEPT | ||
| + | iptables -A FORWARD -p udp -s $LAN_NET -i $LAN_IF -o $WAN_IF --dport 53 -m conntrack --ctstate NEW -j ACCEPT | ||
| + | |||
| + | # TCP-Dienste freigeben: SMTP, DNS, HTTP, IMAP, HTTPS, SMTPS, IMAPS | ||
| + | for port in 25 53 80 143 443 465 993; do | ||
| + | iptables -A FORWARD -p tcp -s $LAN_NET -i $LAN_IF -o $WAN_IF --dport $port -m conntrack --ctstate NEW -j ACCEPT | ||
| + | done | ||
| + | |||
| + | # NAT: Portweiterleitung auf Webserver | ||
| + | iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 9922 -j DNAT --to-destination $WEBSERVER:22 | ||
| + | iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 80 -j DNAT --to-destination $WEBSERVER:80 | ||
| + | |||
| + | # SNAT für ausgehende LAN-Verbindungen | ||
| + | iptables -t nat -A POSTROUTING -s $LAN_NET -o $WAN_IF -j SNAT --to-source $WAN_IP | ||
| + | |||
| + | # Logging | ||
| + | iptables -A INPUT -j LOG --log-prefix "--iptables-drop-input--" | ||
| + | iptables -A OUTPUT -j LOG --log-prefix "--iptables-drop-output--" | ||
| + | iptables -A FORWARD -j LOG --log-prefix "--iptables-drop-forward--" | ||
| + | </pre> | ||
| + | |||
| + | == Neu verwendete Syntax in iptables == | ||
| + | |||
| + | * Bestimmte Ziel-Ports angeben: | ||
| + | |||
| + | '''--dport <port>''' | ||
| + | |||
| + | * Für mehrere Ports (per Schleife): | ||
| + | |||
| + | '''for port in ... ; do iptables ... --dport $port ... ; done''' | ||
| + | = Eigene Ketten = | ||
| + | |||
| + | Man kann auch Ketten ohne Default Policy oder Hooks erstellen, die mehrere Regeln zusammenfassen. In diese Ketten gelangt man durch die Basisketten. | ||
| + | |||
| + | '''vim /etc/iptables-ketten.sh''' | ||
| + | |||
| + | <pre> | ||
| + | #!/bin/bash | ||
| + | |||
| + | # Variablen | ||
| + | WAN_IF="ens18" | ||
| + | LAN_IF="ens20" | ||
| + | LAN_NET="192.168.4.0/24" | ||
| + | WAN_IP="10.82.232.11" | ||
| + | WEBSERVER="192.168.4.12" | ||
| + | |||
| + | # Regelwerk löschen | ||
| + | iptables -F | ||
| + | iptables -X | ||
| + | iptables -t nat -F | ||
| + | iptables -t nat -X | ||
| + | |||
| + | # Eigene Kette erstellen | ||
| + | iptables -N LAN2WAN | ||
| + | |||
| + | # Default Policies | ||
| + | iptables -P INPUT DROP | ||
| + | iptables -P FORWARD DROP | ||
| + | iptables -P OUTPUT DROP | ||
| + | |||
| + | # Loopback erlauben | ||
| + | iptables -A INPUT -i lo -j ACCEPT | ||
| + | iptables -A OUTPUT -o lo -j ACCEPT | ||
| + | |||
| + | # ICMP erlauben | ||
| + | iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT | ||
| + | |||
| + | # SSH von außen | ||
| + | iptables -A INPUT -p tcp --dport 9922 -j ACCEPT | ||
| + | |||
| + | # Etablierte Verbindungen | ||
| + | iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT | ||
| + | iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED,NEW -j ACCEPT | ||
| + | iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT | ||
| + | |||
| + | # Zugriff vom WAN auf Webserver | ||
| + | iptables -A FORWARD -p tcp -d $WEBSERVER --dport 22 -i $WAN_IF -j ACCEPT | ||
| + | iptables -A FORWARD -p tcp -d $WEBSERVER --dport 80 -i $WAN_IF -j ACCEPT | ||
| + | |||
| + | # LAN -> WAN nur bestimmte Dienste, Weiterleitung an eigene Kette | ||
| + | iptables -A FORWARD -p icmp -s $LAN_NET -i $LAN_IF -o $WAN_IF --icmp-type echo-request -m conntrack --ctstate NEW -j LAN2WAN | ||
| + | iptables -A FORWARD -p udp -s $LAN_NET -i $LAN_IF -o $WAN_IF --dport 53 -j LAN2WAN | ||
| + | |||
| + | for port in 25 53 80 143 443 465 993; do | ||
| + | iptables -A FORWARD -p tcp -s $LAN_NET -i $LAN_IF -o $WAN_IF --dport $port -j LAN2WAN | ||
| + | done | ||
| + | |||
| + | # Eigene Kette LAN2WAN – akzeptiere Pakete | ||
| + | iptables -A LAN2WAN -j ACCEPT | ||
| + | |||
| + | # NAT: Portweiterleitung auf Webserver | ||
| + | iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 9922 -j DNAT --to-destination $WEBSERVER:22 | ||
| + | iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 80 -j DNAT --to-destination $WEBSERVER:80 | ||
| + | |||
| + | # SNAT für Rückweg | ||
| + | iptables -t nat -A POSTROUTING -s $LAN_NET -o $WAN_IF -j SNAT --to-source $WAN_IP | ||
| + | |||
| + | # Logging | ||
| + | iptables -A INPUT -j LOG --log-prefix "--iptables-drop-input--" | ||
| + | iptables -A OUTPUT -j LOG --log-prefix "--iptables-drop-output--" | ||
| + | iptables -A FORWARD -j LOG --log-prefix "--iptables-drop-forward--" | ||
| + | </pre> | ||
| + | |||
| + | == Neu verwendete Syntax in iptables == | ||
| + | |||
| + | * Springe in eine andere Kette: | ||
| + | |||
| + | '''-j <target_chain>''' | ||
| + | |||
| + | * Eigene Kette erstellen: | ||
| + | |||
| + | '''iptables -N <name_der_kette>''' | ||
| + | |||
| + | = Limits setzen = | ||
| + | |||
| + | * Man kann die Anzahl, die eine Regel annimmt, zeitlich begrenzen. | ||
| + | * Dafür verwendet man in iptables das ''limit''-Modul. | ||
| + | * Falls nur 5 Pakete pro Minute geloggt werden sollen: | ||
| + | |||
| + | '''vim /etc/iptables-limits.sh''' | ||
| + | |||
| + | <pre> | ||
| + | #!/bin/bash | ||
| + | |||
| + | # Variablen | ||
| + | WAN_IF="ens18" | ||
| + | LAN_IF="ens20" | ||
| + | LAN_NET="192.168.4.0/24" | ||
| + | WAN_IP="10.82.232.11" | ||
| + | WEBSERVER="192.168.4.12" | ||
| + | |||
| + | # Regelwerk löschen | ||
| + | iptables -F | ||
| + | iptables -X | ||
| + | iptables -t nat -F | ||
| + | iptables -t nat -X | ||
| + | |||
| + | # Eigene Kette erstellen | ||
| + | iptables -N LAN2WAN | ||
| + | |||
| + | # Default Policies | ||
| + | iptables -P INPUT DROP | ||
| + | iptables -P FORWARD DROP | ||
| + | iptables -P OUTPUT DROP | ||
| + | |||
| + | # Loopback erlauben | ||
| + | iptables -A INPUT -i lo -j ACCEPT | ||
| + | iptables -A OUTPUT -o lo -j ACCEPT | ||
| + | |||
| + | # ICMP erlauben | ||
| + | iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT | ||
| + | |||
| + | # SSH von außen | ||
| + | iptables -A INPUT -p tcp --dport 9922 -j ACCEPT | ||
| + | |||
| + | # Etablierte Verbindungen | ||
| + | iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT | ||
| + | iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED,NEW -j ACCEPT | ||
| + | iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT | ||
| + | |||
| + | # Zugriff vom WAN auf Webserver | ||
| + | iptables -A FORWARD -p tcp -d $WEBSERVER --dport 22 -i $WAN_IF -j ACCEPT | ||
| + | iptables -A FORWARD -p tcp -d $WEBSERVER --dport 80 -i $WAN_IF -j ACCEPT | ||
| + | |||
| + | # LAN -> WAN nur bestimmte Dienste, Weiterleitung an eigene Kette | ||
| + | iptables -A FORWARD -p icmp -s $LAN_NET -i $LAN_IF -o $WAN_IF --icmp-type echo-request -m conntrack --ctstate NEW -j LAN2WAN | ||
| + | iptables -A FORWARD -p udp -s $LAN_NET -i $LAN_IF -o $WAN_IF --dport 53 -j LAN2WAN | ||
| + | |||
| + | for port in 25 53 80 143 443 465 993; do | ||
| + | iptables -A FORWARD -p tcp -s $LAN_NET -i $LAN_IF -o $WAN_IF --dport $port -j LAN2WAN | ||
| + | done | ||
| + | |||
| + | # Eigene Kette LAN2WAN – akzeptiere Pakete | ||
| + | iptables -A LAN2WAN -j ACCEPT | ||
| + | |||
| + | # NAT: Portweiterleitung auf Webserver | ||
| + | iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 9922 -j DNAT --to-destination $WEBSERVER:22 | ||
| + | iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 80 -j DNAT --to-destination $WEBSERVER:80 | ||
| + | |||
| + | # SNAT für Rückweg | ||
| + | iptables -t nat -A POSTROUTING -s $LAN_NET -o $WAN_IF -j SNAT --to-source $WAN_IP | ||
| + | |||
| + | # Logging mit Limitierung auf 5 Einträge pro Minute | ||
| + | iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "--iptables-drop-input--" | ||
| + | iptables -A OUTPUT -m limit --limit 5/min -j LOG --log-prefix "--iptables-drop-output--" | ||
| + | iptables -A FORWARD -m limit --limit 5/min -j LOG --log-prefix "--iptables-drop-forward--" | ||
| + | </pre> | ||
| + | |||
| + | == Neu verwendete Syntax in iptables == | ||
| + | |||
| + | * Limitierung der Anzahl geloggter Pakete pro Minute: | ||
| + | |||
| + | '''-m limit --limit 5/min''' | ||
Aktuelle Version vom 12. April 2025, 20:43 Uhr
Einleitung
- Nachdem wir ein Hostsystem abgesichert haben, kommen wir nun zum Absichern von Netzen.
- Die Firewall agiert als Vermittler zwischen verschiedenen Netzen.
- In unserem Beispiel haben wir 3 Netzbereiche.
WAN
- Wide Area Net steht für alles was nicht die anderen beiden Netze betrifft
LAN
- Local Area Net steht in der Regel für ein Netz das von aussen nicht erreichbar ist.
- Meist ist es über Network Address Translation (NAT) angebunden.
DMZ
- Demilitarized Zone ist ein Netz welches von außen erreichbar ist.
- Die Zugriffe werden aber durch die Firewall abgesichert.
- Dort werden meistens Dienste wie Mail oder Web gehostet. Teilweise auch Proxy Server.
Der Plan
Das Grundgerüst
- Wir nutzen unsere Host Firewall als Ausgangsskript
- Wir wollen aber von vorneherein verstärkt mit Variablen arbeiten.
- Dies macht die Skripte universeller.
iptables-Skript
vim /etc/iptables.sh
#!/bin/bash
# Variablen
WAN_IF="ens18"
DMZ_IF="ens19"
LAN_IF="ens20"
LAN_NET="192.168.4.0/24"
REMOTE_TCP_PORTS="22 25 53 80 465 443"
REMOTE_UDP_PORTS="53"
LOCAL_TCP_PORTS="22 80 443"
# Regelwerk löschen
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
# Default Policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# Loopback erlauben
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Etablierte Verbindungen
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Lokale Dienste (eingehend)
for port in $LOCAL_TCP_PORTS; do
iptables -A INPUT -p tcp --dport $port -j ACCEPT
done
# Ausgehende Verbindungen
for port in $REMOTE_TCP_PORTS; do
iptables -A OUTPUT -p tcp --dport $port -j ACCEPT
done
for port in $REMOTE_UDP_PORTS; do
iptables -A OUTPUT -p udp --dport $port -j ACCEPT
done
# Logging
iptables -A INPUT -j LOG --log-prefix "--iptables-drop-input--"
iptables -A OUTPUT -j LOG --log-prefix "--iptables-drop-output--"
iptables -A FORWARD -j LOG --log-prefix "--iptables-drop-forward--"
Forwarding
Damit Pakete weitergeleitet werden können, muss als erstes FORWARDING im Kernel aktiviert werden.
Aktivierung
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
Weitere Tabellen
- Eine Skizze über die Reihenfolge der Ketten
- Als erstes greift der Prerouting
- Je nachdem wie geroutet wird greift dann entweder Input- oder Forward
- Falls ein lokaler Prozess ein Paket sendet, dann greift der Output
- Als letztes kann man das Paket mit dem Postrouting beeinflußen
SNAT
- Rechner in einem LAN können nicht ohne weiteres mit dem WAN kommunizieren, da an die lokale IP-Adresse der Rechner im LAN nicht von außen geroutet werden kann.
- Um eine Internetverbindung aufzubauen, muss die Adresse aus dem LAN in eine öffentliche umgeschrieben werden.
vim /etc/iptables-snat.sh
#!/bin/bash # Variablen WAN_IF="ens18" DMZ_IF="ens19" LAN_IF="ens20" LAN_NET="192.168.4.0/24" WAN_IP="10.82.232.11" # Regelwerk löschen iptables -F iptables -X iptables -t nat -F iptables -t nat -X # Default Policies iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP # Loopback erlauben iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # ICMP erlauben iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT # SSH und andere notwendige Ports iptables -A INPUT -p tcp --dport 22 -j ACCEPT # Etablierte Verbindungen iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED,NEW -j ACCEPT iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # SNAT für ausgehende Pakete vom LAN ins WAN iptables -t nat -A POSTROUTING -s $LAN_NET -o $WAN_IF -j SNAT --to-source $WAN_IP # Logging iptables -A INPUT -j LOG --log-prefix "--iptables-drop-input--" iptables -A OUTPUT -j LOG --log-prefix "--iptables-drop-output--" iptables -A FORWARD -j LOG --log-prefix "--iptables-drop-forward--"
Neu verwendete Syntax in iptables
- Interface des herausgehenden Paketes:
-o <device_name>
- match auf Quelladresse des Pakets:
-s <source_ip>
- Quelladresse umschreiben:
-j SNAT --to-source <new_source_ip>
Portforwarding
- Um auf bestimmte Funktionen eines Rechners hinter einer Firewall zugreifen zu können, müssen die dazugehörenden Ports entsprechend weitergeleitet werden.
- Hierbei kann es ein anderer, nicht-standard Port der Firewall sein.
vim /etc/iptables-portfwd.sh
#!/bin/bash # Variablen WAN_IF="ens18" LAN_IF="ens20" LAN_NET="192.168.4.0/24" WAN_IP="10.82.232.11" WEBSERVER="192.168.4.12" # Regelwerk löschen iptables -F iptables -X iptables -t nat -F iptables -t nat -X # Default Policies iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP # Loopback erlauben iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # ICMP erlauben iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT # SSH von außen iptables -A INPUT -p tcp --dport 9922 -j ACCEPT # Etablierte Verbindungen iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED,NEW -j ACCEPT iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Weiterleitung zu internem Webserver iptables -A FORWARD -p tcp -d $WEBSERVER --dport 22 -i $WAN_IF -j ACCEPT iptables -A FORWARD -p tcp -d $WEBSERVER --dport 80 -i $WAN_IF -j ACCEPT # Portweiterleitung iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 9922 -j DNAT --to-destination $WEBSERVER:22 iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 80 -j DNAT --to-destination $WEBSERVER:80 # SNAT für Rückweg iptables -t nat -A POSTROUTING -s $LAN_NET -o $WAN_IF -j SNAT --to-source $WAN_IP # Logging iptables -A INPUT -j LOG --log-prefix "--iptables-drop-input--" iptables -A OUTPUT -j LOG --log-prefix "--iptables-drop-output--" iptables -A FORWARD -j LOG --log-prefix "--iptables-drop-forward--"
- Nun kann man per SSH auf den Rechner hinter der Firewall über Port 9922 der Firewall zugreifen…
ssh user@WEBSERVER -p 9922
- ... und HTTP-Requests an den Rechner hinter der Firewall schicken
curl WEBSERVER
Neu verwendete Syntax in iptables
- matche die Ziel-IP-Adresse:
-d <target_ip>
- Ziel-IP-Adresse auf eine andere umschreiben:
-j DNAT --to-destination <new_target_ip>
Absichern von Netzen
Momentan wird nichts vom LAN zum WAN weitergeleitet. Um nur bestimmte Anwendungen zu erlauben, kann man die für diese designierten Ports freischalten.
vim /etc/iptables-absichern.sh
#!/bin/bash
# Variablen
WAN_IF="ens18"
LAN_IF="ens20"
LAN_NET="192.168.4.0/24"
WAN_IP="10.82.232.11"
WEBSERVER="192.168.4.12"
# Regelwerk löschen
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
# Default Policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# Loopback erlauben
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# ICMP erlauben
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# SSH von außen
iptables -A INPUT -p tcp --dport 9922 -j ACCEPT
# Etablierte Verbindungen
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED,NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Zugriff vom WAN auf Webserver
iptables -A FORWARD -p tcp -d $WEBSERVER --dport 22 -i $WAN_IF -j ACCEPT
iptables -A FORWARD -p tcp -d $WEBSERVER --dport 80 -i $WAN_IF -j ACCEPT
# Zugriff vom LAN ins WAN – nur bestimmte Dienste
iptables -A FORWARD -p icmp -s $LAN_NET -i $LAN_IF -o $WAN_IF --icmp-type echo-request -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -p udp -s $LAN_NET -i $LAN_IF -o $WAN_IF --dport 53 -m conntrack --ctstate NEW -j ACCEPT
# TCP-Dienste freigeben: SMTP, DNS, HTTP, IMAP, HTTPS, SMTPS, IMAPS
for port in 25 53 80 143 443 465 993; do
iptables -A FORWARD -p tcp -s $LAN_NET -i $LAN_IF -o $WAN_IF --dport $port -m conntrack --ctstate NEW -j ACCEPT
done
# NAT: Portweiterleitung auf Webserver
iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 9922 -j DNAT --to-destination $WEBSERVER:22
iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 80 -j DNAT --to-destination $WEBSERVER:80
# SNAT für ausgehende LAN-Verbindungen
iptables -t nat -A POSTROUTING -s $LAN_NET -o $WAN_IF -j SNAT --to-source $WAN_IP
# Logging
iptables -A INPUT -j LOG --log-prefix "--iptables-drop-input--"
iptables -A OUTPUT -j LOG --log-prefix "--iptables-drop-output--"
iptables -A FORWARD -j LOG --log-prefix "--iptables-drop-forward--"
Neu verwendete Syntax in iptables
- Bestimmte Ziel-Ports angeben:
--dport <port>
- Für mehrere Ports (per Schleife):
for port in ... ; do iptables ... --dport $port ... ; done
Eigene Ketten
Man kann auch Ketten ohne Default Policy oder Hooks erstellen, die mehrere Regeln zusammenfassen. In diese Ketten gelangt man durch die Basisketten.
vim /etc/iptables-ketten.sh
#!/bin/bash
# Variablen
WAN_IF="ens18"
LAN_IF="ens20"
LAN_NET="192.168.4.0/24"
WAN_IP="10.82.232.11"
WEBSERVER="192.168.4.12"
# Regelwerk löschen
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
# Eigene Kette erstellen
iptables -N LAN2WAN
# Default Policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# Loopback erlauben
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# ICMP erlauben
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# SSH von außen
iptables -A INPUT -p tcp --dport 9922 -j ACCEPT
# Etablierte Verbindungen
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED,NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Zugriff vom WAN auf Webserver
iptables -A FORWARD -p tcp -d $WEBSERVER --dport 22 -i $WAN_IF -j ACCEPT
iptables -A FORWARD -p tcp -d $WEBSERVER --dport 80 -i $WAN_IF -j ACCEPT
# LAN -> WAN nur bestimmte Dienste, Weiterleitung an eigene Kette
iptables -A FORWARD -p icmp -s $LAN_NET -i $LAN_IF -o $WAN_IF --icmp-type echo-request -m conntrack --ctstate NEW -j LAN2WAN
iptables -A FORWARD -p udp -s $LAN_NET -i $LAN_IF -o $WAN_IF --dport 53 -j LAN2WAN
for port in 25 53 80 143 443 465 993; do
iptables -A FORWARD -p tcp -s $LAN_NET -i $LAN_IF -o $WAN_IF --dport $port -j LAN2WAN
done
# Eigene Kette LAN2WAN – akzeptiere Pakete
iptables -A LAN2WAN -j ACCEPT
# NAT: Portweiterleitung auf Webserver
iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 9922 -j DNAT --to-destination $WEBSERVER:22
iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 80 -j DNAT --to-destination $WEBSERVER:80
# SNAT für Rückweg
iptables -t nat -A POSTROUTING -s $LAN_NET -o $WAN_IF -j SNAT --to-source $WAN_IP
# Logging
iptables -A INPUT -j LOG --log-prefix "--iptables-drop-input--"
iptables -A OUTPUT -j LOG --log-prefix "--iptables-drop-output--"
iptables -A FORWARD -j LOG --log-prefix "--iptables-drop-forward--"
Neu verwendete Syntax in iptables
- Springe in eine andere Kette:
-j <target_chain>
- Eigene Kette erstellen:
iptables -N <name_der_kette>
Limits setzen
- Man kann die Anzahl, die eine Regel annimmt, zeitlich begrenzen.
- Dafür verwendet man in iptables das limit-Modul.
- Falls nur 5 Pakete pro Minute geloggt werden sollen:
vim /etc/iptables-limits.sh
#!/bin/bash
# Variablen
WAN_IF="ens18"
LAN_IF="ens20"
LAN_NET="192.168.4.0/24"
WAN_IP="10.82.232.11"
WEBSERVER="192.168.4.12"
# Regelwerk löschen
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
# Eigene Kette erstellen
iptables -N LAN2WAN
# Default Policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# Loopback erlauben
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# ICMP erlauben
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# SSH von außen
iptables -A INPUT -p tcp --dport 9922 -j ACCEPT
# Etablierte Verbindungen
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED,NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Zugriff vom WAN auf Webserver
iptables -A FORWARD -p tcp -d $WEBSERVER --dport 22 -i $WAN_IF -j ACCEPT
iptables -A FORWARD -p tcp -d $WEBSERVER --dport 80 -i $WAN_IF -j ACCEPT
# LAN -> WAN nur bestimmte Dienste, Weiterleitung an eigene Kette
iptables -A FORWARD -p icmp -s $LAN_NET -i $LAN_IF -o $WAN_IF --icmp-type echo-request -m conntrack --ctstate NEW -j LAN2WAN
iptables -A FORWARD -p udp -s $LAN_NET -i $LAN_IF -o $WAN_IF --dport 53 -j LAN2WAN
for port in 25 53 80 143 443 465 993; do
iptables -A FORWARD -p tcp -s $LAN_NET -i $LAN_IF -o $WAN_IF --dport $port -j LAN2WAN
done
# Eigene Kette LAN2WAN – akzeptiere Pakete
iptables -A LAN2WAN -j ACCEPT
# NAT: Portweiterleitung auf Webserver
iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 9922 -j DNAT --to-destination $WEBSERVER:22
iptables -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 80 -j DNAT --to-destination $WEBSERVER:80
# SNAT für Rückweg
iptables -t nat -A POSTROUTING -s $LAN_NET -o $WAN_IF -j SNAT --to-source $WAN_IP
# Logging mit Limitierung auf 5 Einträge pro Minute
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "--iptables-drop-input--"
iptables -A OUTPUT -m limit --limit 5/min -j LOG --log-prefix "--iptables-drop-output--"
iptables -A FORWARD -m limit --limit 5/min -j LOG --log-prefix "--iptables-drop-forward--"
Neu verwendete Syntax in iptables
- Limitierung der Anzahl geloggter Pakete pro Minute:
-m limit --limit 5/min

