Nftables Netze absichern: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
Zeile 211: Zeile 211:
 
   }
 
   }
 
  }
 
  }
 
+
=old stuff=
== Portforwarding ==
+
*[[nftables-net-oldstuff]]
 
 
* 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
 
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
 
  }
 
}
 
 
 
 
 
* 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
 
    }
 
}
 

Version vom 17. April 2025, 05:01 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
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
 }
}

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>

Forward von innen nach aussen

  • Wir wollen das unsere Clients und die Server vorerst nach aussen alles dürfen.
#!/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 }
define localnets = { $lan , $server , $dmz, $server}
 
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;
  ct state established,related accept
  ct state new saddr $localnets accept
  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
 }
}

old stuff