Nftables Netze absichern: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
| Zeile 40: | Zeile 40: | ||
define local_tcp_ports = { 22 } | define local_tcp_ports = { 22 } | ||
| − | + | ||
flush ruleset | flush ruleset | ||
table inet filter { | table inet filter { | ||
| Zeile 51: | Zeile 51: | ||
log prefix "--nftables-drop-input--" | log prefix "--nftables-drop-input--" | ||
} | } | ||
| − | chain | + | <span style="color:#FF0000">chain forward {</span> |
| − | type filter hook | + | <span style="color:#FF0000">type filter hook forward priority filter; policy drop;</span> |
| − | + | <span style="color:#FF0000">log prefix "--nftables-drop-forward--"</span> | |
| − | + | <span style="color:#FF0000">}</span> | |
| − | } | ||
chain output { | chain output { | ||
Version vom 17. April 2025, 04:38 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.
- vim /etc/nftables.conf
#!/usr/sbin/nft -f
define wandev = enp0s3
define wanip = 192.168.5.113
define lan = 172.17.113.0/24
define server = 172.16.113.0/24
define mgmt = 172.18.113.0/24
define dmz = 10.88.113.0/24
define local_tcp_ports = { 22 }
flush ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
ct state new iifname "lo" accept
ct state new tcp dport $local_tcp_ports accept
ct state new icmp type echo-request accept
log prefix "--nftables-drop-input--"
}
chain forward {
type filter hook forward priority filter; policy drop;
log prefix "--nftables-drop-forward--"
}
chain output {
type filter hook output priority filter; policy drop;
ct state established,related accept
ct state new oifname "lo" accept
ct state new accept
log prefix "--nftables-drop-output--"
}
}
table inet nat {
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oif $wandev ip saddr $lan snat to $wanip
oif $wandev ip saddr $server snat to $wanip
oif $wandev ip saddr $mgmt snat to $wanip
# DMZ wird genattet, außer zu 10.88.0.0/16 und 10.82.89.0/24
oif $wandev ip saddr $dmz ip daddr != { 10.88.0.0/16, 10.82.89.0/24 } snat to $wanip
}
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 Hooks.
- Als erstes greift der Prerouting-Hook
- Je nachdem wie geroutet wird greift dann entweder Input- oder Fowrward-Hook
- Falls ein lokaler Prozess ein Paket sendet, dann greift der Output-Hook
- Als letztes kann man das Paket mit dem Postrouting-Hook 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.
#!/usr/sbin/nft -f
flush ruleset
define remote_tcp_ports = { 22,25,53,80,465,443 }
define remote_udp_ports = { 53 }
define local_tcp_ports = { 22,80,443 }
define wandev = ens18
define dmzdev = ens19
define landev = ens20
define wanip = 10.82.232.11
define lan = 192.168.4.0/24
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
iif "lo" ct state new accept
ct state new tcp dport 22 accept
ct state new icmp type echo-request accept
log prefix "--nftables-drop-input--"
}
chain output {
type filter hook output priority filter; policy drop;
ct state established,related,new accept
log prefix "--nftables-drop-output--"
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
log prefix "--nftables-drop-forward--"
}
}
table inet nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oif $wandev ip saddr $lan snat ip to $wanip
}
}
Neu verwendete Syntax:
- Definieren einer Variable
define variable_name = value
- Interface des herausgehenden Paketes:
oif device_name
- matche IPv4-Adresse des Ursprungpaketes
ip saddr <source_ip>
- Die Ursprungs-IP auf eine andere Adresse natten
snat ip to <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.
#!/usr/sbin/nft -f
flush ruleset
flush ruleset
define remote_tcp_ports = { 22,25,53,80,465,443 }
define remote_udp_ports = { 53 }
define local_tcp_ports = { 22,80,443 }
define wandev = ens18
define dmzdev = ens19
define landev = ens20
define wanip = 10.82.232.11
define lan = 192.168.4.0/24
define webserver = 192.168.4.12
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
iif "lo" ct state new accept
ct state new tcp dport 22 accept
ct state new icmp type echo-request accept
log prefix "--nftables-drop-input--"
}
chain output {
type filter hook output priority filter; policy drop;
ct state established,related,new accept
log prefix "--nftables-drop-output--"
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
iif $wandev ip daddr $webserver tcp dport 22 accept
iif $wandev ip daddr $webserver tcp dport 80 accept
log prefix "--nftables-drop-forward--"
}
}
table inet nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22
ip daddr $wanip tcp dport 80 dnat ip to $webserver:80
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oif $wandev ip saddr $lan snat ip to $wanip
}
}
- 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:
- matche die Ziel IP-Adresse
ip daddr <target_ip>
- Ziel IP-Adresse auf eine andere natten
dnat ip to <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.
#!/usr/sbin/nft -f
flush ruleset
define remote_tcp_ports = { 22,25,53,80,465,443 }
define remote_udp_ports = { 53 }
define local_tcp_ports = { 22,80,443 }
define wandev = ens18
define dmzdev = ens19
define landev = ens20
define lan = 192.168.4.0/24
define wanip = 10.82.232.11
define webserver = 192.168.4.12
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
iif "lo" ct state new accept
ct state new tcp dport 22 accept
ct state new icmp type echo-request accept
log prefix "--nftables-drop-input--"
}
chain output {
type filter hook output priority filter; policy drop;
ct state established,related,new accept
log prefix "--nftables-drop-output--"
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
iif $wandev ip daddr $webserver tcp dport 22 accept
iif $wandev ip daddr $webserver tcp dport 80 accept
ct state new iif $landev oif $wandev ip saddr $lan icmp type echo-request accept
ct state new iif $landev oif $wandev ip saddr $lan udp dport 53 accept
ct state new iif $landev oif $wandev ip saddr $lan tcp dport { 25, 53, 80, 143, 443, 465, 993 } accept
log prefix "--nftables-drop-forward--"
}
}
table inet nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22
ip daddr $wanip tcp dport 80 dnat ip to $webserver:80
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oif $wandev ip saddr $lan snat ip to $wanip
}
}
Neu verwendete Syntax:
Bestimmte Ziel-Ports angeben
transport_protocol dport { port_number_1,port_number_2,... }
Eigene Ketten
Man kann auch Ketten ohne Default Policy oder Hooks erstellen, die mehrere Regeln zusammenfassen. In diese Ketten gelangt man durch die Basisketten.
#!/usr/sbin/nft -f
flush ruleset
define wandev = ens18
define dmzdev = ens19
define landev = ens20
define wanip = 10.82.232.11
define lan = 192.168.4.0/24
define webserver = 192.168.4.12
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
ct state new iif "lo" accept
ct state new tcp dport 22 accept
ct state new icmp type echo-request accept
log prefix "--nftables-drop-input--"
}
chain output {
type filter hook output priority filter; policy drop;
ct state established,related,new accept
log prefix "--nftables-drop-output--"
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
ct state new iif $wandev ip daddr $webserver tcp dport 22 accept
ct state new iif $wandev ip daddr $webserver tcp dport 80 accept
ct state new icmp type echo-request jump lan2wan
udp dport 53 jump lan2wan
tcp dport { 25, 53, 80, 143, 443, 465, 993 } jump lan2wan
log prefix "--nftables-drop-forward--"
}
chain lan2wan {
ct state new iif $landev oifname $wandev ip saddr $lan accept
}
}
table inet nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22
ip daddr $wanip tcp dport 80 dnat ip to $webserver:80
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oif $wandev ip saddr $lan snat ip to $wanip
}
}
Neu verwendete Syntax:
Springe in eine andere Kette
jump target
Limits setzten
- Man kann die Anzahl die eine Regel annimmt zeitlich begrenzen.
- Dafür fügt man limit rate in die Regel ein.
- Falls nur 5 Pakete pro Minute geloggt werden sollen:
#!/usr/sbin/nft -f
flush ruleset
define remote_tcp_ports = { 22,25,53,80,465,443 }
define remote_udp_ports = { 53 }
define local_tcp_ports = { 22,80,443 }
define wandev = ens18
define dmzdev = ens19
define landev = ens20
define lan = 192.168.4.0/24
define wanip = 10.82.232.11
define webserver = 192.168.4.12
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
iif "lo" ct state new accept
ct state new tcp dport 22 accept
ct state new icmp type echo-request accept
limit rate 5/minute log prefix "--nftables-drop-input--"
}
chain output {
type filter hook output priority filter; policy drop;
ct state established,related,new accept
limit rate 5/minute log prefix "--nftables-drop-output--"
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
iif $wandev ip daddr $webserver tcp dport 22 accept
iif $wandev ip daddr $webserver tcp dport 80 accept
icmp type echo-request jump lan2wan
udp dport 53 jump lan2wan
tcp dport { 25, 53, 80, 143, 443, 465, 993 } jump lan2wan
limit rate 5/minute log prefix "--nftables-drop-forward--"
}
chain lan2wan {
ct state new iif $landev oif $wandev ip saddr $lan accept
}
}
table inet nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22
ip daddr $wanip tcp dport 80 dnat ip to $webserver:80
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oif $wandev ip saddr $lan snat ip to $wanip
}
}

