Nftables Netze absichern: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
Zeile 60: Zeile 60:
 
     }
 
     }
 
     chain forward {
 
     chain forward {
    type filter hook forward priority filter; policy drop;
+
        type filter hook forward priority filter; policy drop;
    ct state established,related accept
+
        ct state established,related accept
 
         log prefix "--nftables-drop-forward--"
 
         log prefix "--nftables-drop-forward--"
 
     }
 
     }
 
   
 
   
 
     chain output {
 
     chain output {
    type filter hook output priority filter; policy drop;
+
        type filter hook output priority filter; policy drop;
    ct state established,related accept
+
        ct state established,related accept
 
         ct state new oifname "lo" accept
 
         ct state new oifname "lo" accept
 
         ct state new tcp dport $remote_tcp_ports accept
 
         ct state new tcp dport $remote_tcp_ports accept
Zeile 75: Zeile 75:
 
  }
 
  }
 
<span id="forwarding"></span>
 
<span id="forwarding"></span>
 
 
= Forwarding =
 
= Forwarding =
  
Zeile 120: Zeile 119:
 
   
 
   
 
  table inet filter {
 
  table inet filter {
chain input {
+
    chain input {
    type filter hook input priority filter; policy drop;
+
        type filter hook input priority filter; policy drop;
    ct state established,related accept
+
        ct state established,related accept
    iifname "lo" ct state new accept
+
        iifname "lo" ct state new accept
    ct state new tcp dport 22 accept
+
        ct state new tcp dport 22 accept
    ct state new icmp type echo-request accept
+
        ct state new icmp type echo-request accept
    log prefix "--nftables-drop-input--"
+
        log prefix "--nftables-drop-input--"
}
+
    }
 
   
 
   
 
     chain output {
 
     chain output {
    type filter hook output priority filter; policy drop;
+
        type filter hook output priority filter; policy drop;
    ct state established,related,new accept
+
        ct state established,related,new accept
    log prefix "--nftables-drop-output--"
+
        log prefix "--nftables-drop-output--"
 
     }
 
     }
 
   
 
   
 
     chain forward {
 
     chain forward {
    type filter hook forward priority filter; policy drop;
+
        type filter hook forward priority filter; policy drop;
    ct state established,related accept
+
        ct state established,related accept
 
         log prefix "--nftables-drop-forward--"
 
         log prefix "--nftables-drop-forward--"
 
     }
 
     }
Zeile 144: Zeile 143:
 
   
 
   
 
  '''table inet nat {'''
 
  '''table inet nat {'''
'''chain prerouting {'''
+
    '''chain prerouting {'''
    '''type nat hook prerouting priority dstnat; policy accept;'''
+
        '''type nat hook prerouting priority dstnat; policy accept;'''
 
     '''}'''
 
     '''}'''
 
   
 
   
'''chain postrouting {'''
+
    '''chain postrouting {'''
    '''type nat hook postrouting priority srcnat; policy accept;'''
+
        '''type nat hook postrouting priority srcnat; policy accept;'''
    '''oifname $wandev ip saddr $lan snat ip to $wanip'''
+
        '''oifname $wandev ip saddr $lan snat ip to $wanip'''
'''}'''
+
    '''}'''
 
   
 
   
 
  '''}'''
 
  '''}'''
Zeile 172: Zeile 171:
 
== Portforwarding ==
 
== Portforwarding ==
  
<ul>
+
* Um auf bestimmte Funktionen eines Rechners hinter einer Firewall zugreifen zu können, müssen die dazugehörenden Ports entsprechend weitergeleitet werden.
<li><p>Um auf bestimmte Funktionen eines Rechners hinter einer Firewall zugreifen zu können, müssen die dazugehörenden Ports entsprechend weitergeleitet werden.</p></li>
+
* Hierbei kann es ein anderer, nicht-standard Port der Firewall sein.
<li><p>Hierbei kann es ein anderer, nicht-standard Port der Firewall sein.</p>
 
<p>#!/usr/sbin/nft -f</p>
 
<p>flush ruleset</p>
 
<p>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’’’</p>
 
<p>table inet filter { chain input { type filter hook input priority filter; policy drop; ct state established,related accept iifname “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–”</p></li></ul>
 
  
 +
<!----->
 +
#!/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
 +
iifname "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--"
 
<span id="absichern-von-netzen"></span>
 
<span id="absichern-von-netzen"></span>
 
= Absichern von Netzen =
 
= Absichern von Netzen =
Zeile 223: Zeile 241:
 
  }
 
  }
 
  table inet nat {
 
  table inet nat {
chain prerouting {
+
chain prerouting { type nat hook prerouting priority dstnat; policy accept; meta nfproto ipv4 ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22 meta nfproto ipv4 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80 }
    type nat hook prerouting priority dstnat; policy accept;
+
 
    meta nfproto ipv4 ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22
+
chain postrouting { type nat hook postrouting priority srcnat; policy accept; oifname $wandev ip saddr $lan snat ip to $wanip } }
    meta nfproto ipv4 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80
+
 
    }
 
 
chain postrouting {
 
    type nat hook postrouting priority srcnat; policy accept;
 
    oifname $wandev ip saddr $lan snat ip to $wanip
 
    }
 
}
 
 
Neu verwendete Syntax:
 
Neu verwendete Syntax:
  
Zeile 254: Zeile 265:
 
   
 
   
 
  table inet filter {
 
  table inet filter {
chain input {
+
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 22 accept ct state new icmp type echo-request accept log prefix “–nftables-drop-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 22 accept
 
        ct state new icmp type echo-request accept
 
        log prefix "--nftables-drop-input--"
 
    }
 
   
 
 
     chain output {
 
     chain output {
    type filter hook output priority filter; policy drop;
+
type filter hook output priority filter; policy drop; ct state established,related,new accept log prefix “–nftables-drop-output–” }
        ct state established,related,new accept
+
 
        log prefix "--nftables-drop-output--"
 
    }
 
   
 
 
     chain forward {
 
     chain forward {
    type filter hook forward priority filter; policy drop;
+
type filter hook forward priority filter; policy drop; ct state established,related accept ct state new iifname $wandev ip daddr $webserver tcp dport 22 accept ct state new iifname $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–” }
        ct state established,related accept
+
 
        ct state new iifname $wandev ip daddr $webserver tcp dport 22 accept
+
’‘’chain lan2wan {’’’ ’‘’ct state new iifname $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 }
        ct state new iifname $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 iifname $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 {
 
     chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
+
type nat hook postrouting priority srcnat; policy accept; oifname $wandev ip saddr $lan snat ip to $wanip } }
        oifname $wandev ip saddr $lan snat ip to $wanip
+
 
    }
 
}
 
 
Neu verwendete Syntax:
 
Neu verwendete Syntax:
  
Zeile 319: Zeile 301:
 
   
 
   
 
  table inet filter {
 
  table inet filter {
chain input {
+
chain input { type filter hook input priority filter; policy drop; ct state established,related accept iifname “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–” }
        type filter hook input priority filter; policy drop;
+
 
        ct state established,related accept
 
        iifname "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 {
 
     chain output {
 
         type filter hook output priority filter; policy drop;
 
         type filter hook output priority filter; policy drop;
Zeile 350: Zeile 325:
 
  }
 
  }
 
  table inet nat {
 
  table inet nat {
chain prerouting {
+
chain prerouting { type nat hook prerouting priority dstnat; policy accept; meta nfproto ipv4 ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22 meta nfproto ipv4 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80 }
    type nat hook prerouting priority dstnat; policy accept;
+
 
    meta nfproto ipv4 ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22
+
chain postrouting { type nat hook postrouting priority srcnat; policy accept; oifname $wandev ip saddr $lan snat ip to $wanip } }
    meta nfproto ipv4 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80
+
 
}
 
 
chain postrouting {
 
    type nat hook postrouting priority srcnat; policy accept;
 
    oifname $wandev ip saddr $lan snat ip to $wanip
 
}
 
}
 
 
<span id="vpns-ermöglichen"></span>
 
<span id="vpns-ermöglichen"></span>
 
= VPNs ermöglichen =
 
= VPNs ermöglichen =
  
<ul>
+
* Damit VPN-Verbindungen von außen aufgebaut werden können müssen die UDP-Ports 500 und 4500 für IPSec-Protokolle offen sein.
<li><p>Damit VPN-Verbindungen von außen aufgebaut werden können müssen die UDP-Ports 500 und 4500 für IPSec-Protokolle offen sein.</p></li>
+
* Nachdem eine Secure Association hergestellt wurde, müssen ESP Pakete von der Firewall zugelassen und die entpackten Pakete weitergeleitet werden.
<li><p>Nachdem eine Secure Association hergestellt wurde, müssen ESP Pakete von der Firewall zugelassen und die entpackten Pakete weitergeleitet werden.</p></li>
+
* vim fw.nft
<li><p>vim fw.nft</p>
+
 
<p>#!/usr/sbin/nft -f</p>
+
<!----->
<p>flush ruleset define wandev = ens18 define landev = ens19 define wanip = 10.82.232.11 define lan = 192.168.4.0/24 ’‘’define vpn = 192.168.178.0/24’’’ define webserver = 192.168.4.11</p>
+
#!/usr/sbin/nft -f
<p>table inet filter { chain input { type filter hook input priority filter; policy drop; ct state established,related accept iifname “lo” ct state new accept ct state new tcp dport 22 accept ct state new icmp type echo-request accept ’‘’iifname $wandev ct state new udp dport 500 jump ipsec’’’ ’‘’iifname $wandev ct state new udp dport 4500 jump ipsec’’’ ’‘’iifname $wandev ct state new meta l4proto esp jump ipsec’’’ limit rate 5/minute log prefix “–nftables-drop-input–” }</p>
+
  chain output {
+
flush ruleset
type filter hook output priority filter; policy drop;
+
define wandev = ens18
    ct state established,related,new accept
+
define landev = ens19
    limit rate 5/minute log prefix "--nftables-drop-output--"
+
define wanip = 10.82.232.11
  }
+
define lan = 192.168.4.0/24
<p>chain forward { type filter hook forward priority filter; policy drop; ct state established,related accept iifname $wandev meta nfproto ipv4 ip daddr $webserver tcp dport 22 accept iifname $wandev meta nfproto ipv4 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 ’‘’iifname $wandev ip saddr $vpn ct state new jump ipsec’’’ limit rate 5/minute log prefix “–nftables-drop-forward–” }</p>
+
'''define vpn = 192.168.178.0/24'''
  chain lan2wan {
+
define webserver = 192.168.4.11
ct state new iifname $landev oifname $wandev ip saddr $lan accept
 
  }
 
 
   
 
   
  '''chain ipsec {'''
+
table inet filter {
'''accept'''
+
chain input { type filter hook input priority filter; policy drop; ct state established,related accept iifname “lo” ct state new accept ct state new tcp dport 22 accept ct state new icmp type echo-request accept ’‘’iifname $wandev ct state new udp dport 500 jump ipsec’’’ ’‘’iifname $wandev ct state new udp dport 4500 jump ipsec’’’ ’‘’iifname $wandev ct state new meta l4proto esp jump ipsec’’’ limit rate 5/minute log prefix “–nftables-drop-input–” }
  '''}'''
+
 
  }
+
    chain output {
  table inet nat {
+
type filter hook output priority filter; policy drop; ct state established,related,new accept limit rate 5/minute log prefix “–nftables-drop-output–” }
chain prerouting {
+
 
    type nat hook prerouting priority dstnat; policy accept;
+
chain forward { type filter hook forward priority filter; policy drop; ct state established,related accept iifname $wandev meta nfproto ipv4 ip daddr $webserver tcp dport 22 accept iifname $wandev meta nfproto ipv4 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 ’‘’iifname $wandev ip saddr $vpn ct state new jump ipsec’’’ limit rate 5/minute log prefix “–nftables-drop-forward–” }
    meta nfproto ipv4 ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22
+
 
    meta nfproto ipv4 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80
+
    chain lan2wan {
  }
+
ct state new iifname $landev oifname $wandev ip saddr $lan accept }
<p>chain postrouting { type nat hook postrouting priority srcnat; policy accept; oifname $wandev ip saddr $lan snat ip to $wanip } }</p></li></ul>
+
 
 +
    '''chain ipsec {'''
 +
’‘’accept’’’ ’’‘}’’’ } table inet nat { chain prerouting { type nat hook prerouting priority dstnat; policy accept; meta nfproto ipv4 ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22 meta nfproto ipv4 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80 }
 +
 
 +
chain postrouting { type nat hook postrouting priority srcnat; policy accept; oifname $wandev ip saddr $lan snat ip to $wanip } }
  
 
Der Weg nach außen muss in dem Fall nicht speziell freigeschaltet werden, da unsere Firewall sowieso alle neuen Pakete nach außen durchlässt. Damit aber ESP-Pakete korrekt generiert werden, muss die postrouting-Regel für den Internetzugang der Clients angepasst werden. Ein Blick auf die Routing-Tabelle zeigt nämlich, …
 
Der Weg nach außen muss in dem Fall nicht speziell freigeschaltet werden, da unsere Firewall sowieso alle neuen Pakete nach außen durchlässt. Damit aber ESP-Pakete korrekt generiert werden, muss die postrouting-Regel für den Internetzugang der Clients angepasst werden. Ein Blick auf die Routing-Tabelle zeigt nämlich, …
Zeile 397: Zeile 367:
 
* ip route show table 220
 
* ip route show table 220
  
 +
<!----->
 
192.168.178.0/24 via 10.82.229.1 dev ens18 proto static src 192.168.4.1
 
192.168.178.0/24 via 10.82.229.1 dev ens18 proto static src 192.168.4.1
  
Zeile 412: Zeile 383:
 
   
 
   
 
  table inet filter {
 
  table inet filter {
chain input {
+
chain input { type filter hook input priority filter; policy drop; ct state established,related accept iifname “lo” ct state new accept ct state new tcp dport 22 accept ct state new icmp type echo-request accept iifname $wandev ct state new udp dport 500 jump ipsec iifname $wandev ct state new udp dport 4500 jump ipsec iifname $wandev ct state new meta l4proto esp jump ipsec limit rate 5/minute log prefix “–nftables-drop-input–” }
    type filter hook input priority filter; policy drop;
+
 
        ct state established,related accept
 
        iifname "lo" ct state new accept
 
        ct state new tcp dport 22 accept
 
        ct state new icmp type echo-request accept
 
        iifname $wandev ct state new udp dport 500 jump ipsec
 
        iifname $wandev ct state new udp dport 4500 jump ipsec
 
        iifname $wandev ct state new meta l4proto esp jump ipsec
 
        limit rate 5/minute log prefix "--nftables-drop-input--"
 
    }
 
   
 
 
     chain output {
 
     chain output {
    type filter hook output priority filter; policy drop;
+
type filter hook output priority filter; policy drop; ct state established,related,new accept limit rate 5/minute log prefix “–nftables-drop-output–” }
        ct state established,related,new accept
+
 
        limit rate 5/minute log prefix "--nftables-drop-output--"
 
    }
 
   
 
 
     chain forward {
 
     chain forward {
    type filter hook forward priority filter; policy drop;
+
type filter hook forward priority filter; policy drop; ct state established,related accept iifname $wandev meta nfproto ipv4 ip daddr $webserver tcp dport 22 accept iifname $wandev meta nfproto ipv4 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 iifname $wandev ip saddr $vpn ct state new jump ipsec limit rate 5/minute log prefix “–nftables-drop-forward–” }
        ct state established,related accept
+
 
        iifname $wandev meta nfproto ipv4 ip daddr $webserver tcp dport 22 accept
 
        iifname $wandev meta nfproto ipv4 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
 
        iifname $wandev ip saddr $vpn ct state new jump ipsec
 
        limit rate 5/minute log prefix "--nftables-drop-forward--"
 
    }
 
   
 
 
     chain lan2wan {
 
     chain lan2wan {
    ct state new iifname $landev oifname $wandev ip saddr $lan accept
+
ct state new iifname $landev oifname $wandev ip saddr $lan accept }
    }
+
 
   
 
 
     chain ipsec {
 
     chain ipsec {
    accept
+
accept } } table inet nat { chain prerouting { type nat hook prerouting priority dstnat; policy accept; meta nfproto ipv4 ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22 meta nfproto ipv4 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80 }
    }
+
 
}
+
chain postrouting { type nat hook postrouting priority srcnat; policy accept; oifname $wandev ip saddr $lan ’‘’ip daddr != $vpn’’’ snat ip to $wanip } }
table inet nat {
+
 
chain prerouting {
 
    type nat hook prerouting priority dstnat; policy accept;
 
    meta nfproto ipv4 ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22
 
    meta nfproto ipv4 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80
 
}
 
 
chain postrouting {
 
    type nat hook postrouting priority srcnat; policy accept;
 
    oifname $wandev ip saddr $lan '''ip daddr != $vpn''' snat ip to $wanip
 
}
 
}
 
 
Zum Vergleich die ‘’tcpdump’’-Analysen bei einem Ping auf einen der Rechner im VPN…
 
Zum Vergleich die ‘’tcpdump’’-Analysen bei einem Ping auf einen der Rechner im VPN…
  

Version vom 21. November 2022, 14:51 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 aussen 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.
  • cat /etc/nftables.conf
#!/usr/sbin/nft -f
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

flush ruleset
table inet filter {
    chain input {
        type filter hook input priority filter; policy drop;
        ct state established,related accept
        ct state new tcp dport $local_tcp_ports accept
        log prefix "--nftables-drop-input--"
    }
    chain forward {
        type filter hook forward priority filter; policy drop;
        ct state established,related 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 tcp dport $remote_tcp_ports accept
        ct state new udp dport $remote_udp_ports accept
        log prefix "--nftables-drop-output--"
    }
}

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
        iifname "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;
        oifname $wandev ip saddr $lan snat ip to $wanip
    }

}

Neu verwendete Syntax:

  • Definieren einer Variable
define variable_name = value
  • Interface des herausgehenden Paketes:

oifname ‘’device name’’

  • IPv4-Adresse des Ursprungpaketes

    ip saddr ’‘<source address>’’

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
iifname "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--"

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 wandev = ens18
define landev = ens19
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
iifname "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
iifname $wandev meta nfproto ipv4 ip daddr $webserver tcp dport 22 accept
iifname $wandev meta nfproto ipv4 ip daddr $webserver tcp dport 80 accept
ct state new iifname $landev oifname $wandev ip saddr $lan icmp type echo-request accept
ct state new iifname $landev oifname $wandev ip saddr $lan udp dport 53 accept
ct state new iifname $landev oifname $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; meta nfproto ipv4 ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22 meta nfproto ipv4 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80 }

chain postrouting { type nat hook postrouting priority srcnat; policy accept; oifname $wandev ip saddr $lan snat ip to $wanip } }

Neu verwendete Syntax:

Bestimmte Ziel-Ports angeben

transport_protocol dport { port number }

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 landev = ens19
define wanip = 10.82.232.11
define lan = 192.168.4.0/24
define webserver = 192.168.4.11

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 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 iifname $wandev ip daddr $webserver tcp dport 22 accept ct state new iifname $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 iifname $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; oifname $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 wandev = ens18
define landev = ens19
define wanip = 10.82.232.11
define lan = 192.168.4.0/24
define webserver = 192.168.4.11

table inet filter {

chain input { type filter hook input priority filter; policy drop; ct state established,related accept iifname “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
        iifname $wandev meta nfproto ipv4 ip daddr $webserver tcp dport 22 accept
        iifname $wandev meta nfproto ipv4 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 iifname $landev oifname $wandev ip saddr $lan accept
    }
}
table inet nat {

chain prerouting { type nat hook prerouting priority dstnat; policy accept; meta nfproto ipv4 ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22 meta nfproto ipv4 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80 }

chain postrouting { type nat hook postrouting priority srcnat; policy accept; oifname $wandev ip saddr $lan snat ip to $wanip } }

VPNs ermöglichen

  • Damit VPN-Verbindungen von außen aufgebaut werden können müssen die UDP-Ports 500 und 4500 für IPSec-Protokolle offen sein.
  • Nachdem eine Secure Association hergestellt wurde, müssen ESP Pakete von der Firewall zugelassen und die entpackten Pakete weitergeleitet werden.
  • vim fw.nft
#!/usr/sbin/nft -f

flush ruleset
define wandev = ens18
define landev = ens19
define wanip = 10.82.232.11
define lan = 192.168.4.0/24
define vpn = 192.168.178.0/24
define webserver = 192.168.4.11

table inet filter {

chain input { type filter hook input priority filter; policy drop; ct state established,related accept iifname “lo” ct state new accept ct state new tcp dport 22 accept ct state new icmp type echo-request accept ’‘’iifname $wandev ct state new udp dport 500 jump ipsec’’’ ’‘’iifname $wandev ct state new udp dport 4500 jump ipsec’’’ ’‘’iifname $wandev ct state new meta l4proto esp jump ipsec’’’ 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 iifname $wandev meta nfproto ipv4 ip daddr $webserver tcp dport 22 accept iifname $wandev meta nfproto ipv4 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 ’‘’iifname $wandev ip saddr $vpn ct state new jump ipsec’’’ limit rate 5/minute log prefix “–nftables-drop-forward–” }

    chain lan2wan {

ct state new iifname $landev oifname $wandev ip saddr $lan accept }

    chain ipsec {

’‘’accept’’’ ’’‘}’’’ } table inet nat { chain prerouting { type nat hook prerouting priority dstnat; policy accept; meta nfproto ipv4 ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22 meta nfproto ipv4 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80 }

chain postrouting { type nat hook postrouting priority srcnat; policy accept; oifname $wandev ip saddr $lan snat ip to $wanip } }

Der Weg nach außen muss in dem Fall nicht speziell freigeschaltet werden, da unsere Firewall sowieso alle neuen Pakete nach außen durchlässt. Damit aber ESP-Pakete korrekt generiert werden, muss die postrouting-Regel für den Internetzugang der Clients angepasst werden. Ein Blick auf die Routing-Tabelle zeigt nämlich, …

  • ip route show table 220

192.168.178.0/24 via 10.82.229.1 dev ens18 proto static src 192.168.4.1

… dass nur Pakete mit einer Ursprungs-IP von 192.168.4.1 an das lokale Netz der VPN-Verbindung geleitet wird. Die bisherige SNAT-Regel schreibt jedoch alle Pakete auf die IP des WAN-Interfaces um. Also müssen wir die Ziel-IPs der VPN ausschließen:

#!/usr/sbin/nft -f

flush ruleset
define wandev = ens18
define landev = ens19
define wanip = 10.82.232.11
define lan = 192.168.4.0/24
define vpn = 192.168.178.0/24
define webserver = 192.168.4.11

table inet filter {

chain input { type filter hook input priority filter; policy drop; ct state established,related accept iifname “lo” ct state new accept ct state new tcp dport 22 accept ct state new icmp type echo-request accept iifname $wandev ct state new udp dport 500 jump ipsec iifname $wandev ct state new udp dport 4500 jump ipsec iifname $wandev ct state new meta l4proto esp jump ipsec 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 iifname $wandev meta nfproto ipv4 ip daddr $webserver tcp dport 22 accept iifname $wandev meta nfproto ipv4 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 iifname $wandev ip saddr $vpn ct state new jump ipsec limit rate 5/minute log prefix “–nftables-drop-forward–” }

    chain lan2wan {

ct state new iifname $landev oifname $wandev ip saddr $lan accept }

    chain ipsec {

accept } } table inet nat { chain prerouting { type nat hook prerouting priority dstnat; policy accept; meta nfproto ipv4 ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22 meta nfproto ipv4 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80 }

chain postrouting { type nat hook postrouting priority srcnat; policy accept; oifname $wandev ip saddr $lan ’‘’ip daddr != $vpn’’’ snat ip to $wanip } }

Zum Vergleich die ‘’tcpdump’’-Analysen bei einem Ping auf einen der Rechner im VPN…

  • …ohne die Ziel-IPs auszuschließen: tcpdump -i ens18 icmp or esp
15:30:07.481373 IP fw-linkai > 192.168.178.2: ICMP echo request, id 2845, seq 1, length 64
15:30:08.493319 IP fw-linkai > 192.168.178.2: ICMP echo request, id 2845, seq 2, length 64
15:30:09.517369 IP fw-linkai > 192.168.178.2: ICMP echo request, id 2845, seq 3, length 64
  • …wenn die Ziel-IPs auszuschließen werden: tcpdump -i ens18 icmp or esp
15:27:31.091907 IP fw-linkai > 10.82.228.2: ESP(spi=0xc668795e,seq=0x4), length 136
15:27:31.093913 IP 10.82.228.2 > fw-linkai: ESP(spi=0xccf83bd8,seq=0x4), length 136
15:27:31.093913 IP 192.168.178.2 > 192.168.4.1: ICMP echo reply, id 32171, seq 1, length 64
15:27:32.093502 IP fw-linkai > 10.82.228.2: ESP(spi=0xc668795e,seq=0x5), length 136
15:27:32.095404 IP 10.82.228.2 > fw-linkai: ESP(spi=0xccf83bd8,seq=0x5), length 136
15:27:32.095404 IP 192.168.178.2 > 192.168.4.1: ICMP echo reply, id 32171, seq 2, length 64
15:27:33.095023 IP fw-linkai > 10.82.228.2: ESP(spi=0xc668795e,seq=0x6), length 136
15:27:33.096880 IP 10.82.228.2 > fw-linkai: ESP(spi=0xccf83bd8,seq=0x6), length 136
15:27:33.096880 IP 192.168.178.2 > 192.168.4.1: ICMP echo reply, id 32171, seq 3, length 64