Nftables Netze absichern: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
Zeile 1: Zeile 1:
 +
<span id="einleitung"></span>
 +
= Einleitung =
  
=Einleitung=
+
* Nachdem wir ein Hostsystem abgesichert haben, kommen wir nun zum Absichern von Netzen.
*Nachdem wir ein Hostsystem abgesichert haben, kommen wir nun zum Absichern von Netzen.
+
* Die Firewall agiert als Vermittler zwischen verschiedenen Netzen.
*Die Firewall agiert als Vermittler zwischen verschiedenen Netzen.
+
* In unserem Beispiel haben wir 3 Netzbereiche.
*In unserem Beispiel haben wir 3 Netzbereiche.
 
  
=WAN=
+
<!----->
*Wide Area Net steht für alles was nicht die anderen beiden Netze betrifft
+
<span id="wan"></span>
=LAN=
+
= WAN =
*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.
+
* Wide Area Net steht für alles was nicht die anderen beiden Netze betrifft
 +
 
 +
<!----->
 +
<span id="lan"></span>
 +
= LAN =
  
=DMZ=
+
* Local Area Net steht in der Regel für ein Netz das von aussen nicht erreichbar ist.
*Demilitarized Zone ist ein Netz welches von aussen erreichbar ist.
+
* Meist ist es über Network Address Translation (NAT) angebunden.
*Die Zugriffe werden aber durch die Firewall abgesichert.
+
 
*Dort werden meistens Dienste wie Mail oder Web gehostet. Teilweise auch Proxy Server.
+
<!----->
 +
<span id="dmz"></span>
 +
= 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.
 +
 
 +
<!----->
 +
<span id="der-plan"></span>
 +
= Der Plan =
  
=Der Plan=
 
 
{{#drawio:netzplan-nftables-1}}
 
{{#drawio:netzplan-nftables-1}}
=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
 
<pre>
 
#!/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 = enp0s18
 
define dmzdev = enp0s19
 
define landev = enp0s20
 
define lan = 192.168.4.0/24
 
  
flush ruleset
+
<span id="das-grundgerüst"></span>
table inet filter {
+
= Das Grundgerüst =
        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 {
+
* Wir nutzen unsere Host Firewall als Ausgangsskript
                type filter hook output priority filter; policy drop;
+
* Wir wollen aber von vorneherein verstärkt mit Variablen arbeiten.
                ct state established,related accept
+
* Dies macht die Skripte universeller.
                ct state new oifname "lo" accept
+
* cat /etc/nftables.conf
                ct state new tcp dport $remote_tcp_ports accept
 
                ct state new udp dport $remote_udp_ports accept
 
                log prefix "--nftables-drop-output--"
 
        }
 
}
 
  
</pre>
+
<!----->
 +
#!/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--"
 +
    }
 +
}
 +
<span id="forwarding"></span>
 +
= Forwarding =
  
=Forwarding=
+
* Damit Pakete weitergeleitet werden können, muss als erstes FORWARDING im Kernel aktiviert werden.
*Damit Pakete weitergeleitet werden können, muss als erstes FORWARDING im Kernel aktiviert werden.
+
 
 +
<!----->
 
<span id="aktivierung"></span>
 
<span id="aktivierung"></span>
 
== Aktivierung ==
 
== Aktivierung ==
*echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
+
 
*sysctl -p
+
* echo “net.ipv4.ip_forward = 1” &gt;&gt; /etc/sysctl.conf
=Weitere Tabellen=
+
* sysctl -p
 +
 
 +
<!----->
 +
<span id="weitere-tabellen"></span>
 +
= 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
 +
 
 +
<!----->
 
{{#drawio:nft-inet1}}
 
{{#drawio:nft-inet1}}
  
 +
<span id="snat"></span>
 
== SNAT ==
 
== 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.
 
  
 +
* 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
 
  #!/usr/sbin/nft -f
 
   
 
   
Zeile 78: Zeile 112:
 
  define remote_udp_ports = { 53 }
 
  define remote_udp_ports = { 53 }
 
  define local_tcp_ports = { 22,80,443 }
 
  define local_tcp_ports = { 22,80,443 }
  define wandev = enp0s3
+
  define wandev = ens18
  define dmzdev = enp0s8
+
  define dmzdev = ens19
  define landev = enp0s9
+
  define landev = ens20
  define wanip = 10.82.229.11
+
  define wanip = 10.82.232.11
  define lan = 10.0.11.0/24
+
  define lan = 192.168.4.0/24
 
   
 
   
 
  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
Zeile 95: Zeile 129:
 
   
 
   
 
     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 110: Zeile 144:
 
  '''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'''
    '''}'''
+
'''}'''
 
  '''}'''
 
  '''}'''
 
Neu verwendete Syntax:
 
Neu verwendete Syntax:
Zeile 127: Zeile 161:
  
 
<!----->
 
<!----->
oifname ''device name''
+
oifname ‘’device name’’
* IPv4-Adresse des Ursprungpaketes
+
 
 +
<ul>
 +
<li><p>IPv4-Adresse des Ursprungpaketes</p>
 +
<p>ip saddr ’‘<source address>’’</p></li></ul>
  
<!----->
 
ip saddr ''<source address>''
 
 
<span id="portforwarding"></span>
 
<span id="portforwarding"></span>
 
 
== Portforwarding ==
 
== 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
+
<ul>
+
<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>
flush ruleset
+
<li><p>Hierbei kann es ein anderer, nicht-standard Port der Firewall sein.</p>
+
<p>#!/usr/sbin/nft -f</p>
flush ruleset
+
<p>flush ruleset</p>
define remote_tcp_ports = { 22,25,53,80,465,443 }
+
<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>
define remote_udp_ports = { 53 }
+
<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>
define local_tcp_ports = { 22,80,443 }
 
define wandev = enp0s3
 
define dmzdev = enp0s8
 
define landev = enp0s9
 
define wanip = 10.82.229.11
 
define lan = 10.0.11.0/24
 
'''define webserver = 10.0.11.102'''
 
 
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--"
 
=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.
 
  
<!----->
 
 
<span id="absichern-von-netzen"></span>
 
<span id="absichern-von-netzen"></span>
 
 
= Absichern von Netzen =
 
= Absichern von Netzen =
  
Zeile 178: Zeile 188:
 
  define wandev = ens18
 
  define wandev = ens18
 
  '''define landev = ens19'''
 
  '''define landev = ens19'''
  define wanip = 10.82.229.11
+
  define wanip = 10.82.232.11
  define lan = 10.82.244.0/24
+
  define lan = 192.168.4.0/24
  define webserver = 10.82.244.8
+
  define webserver = 192.168.4.12
 
   
 
   
 
  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
        iifname $wandev meta nfproto ipv4 ip daddr $webserver tcp dport 22 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
+
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 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 udp dport 53 accept'''
        '''ct state new iifname $landev oifname $wandev ip saddr $lan tcp dport { 25, 53, 80, 143, 443, 465, 993 } 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--"
+
log prefix "--nftables-drop-forward--"
    }
+
}
 
   
 
   
 
  }
 
  }
 
  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;
        meta nfproto ipv4 ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22
+
    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
+
    meta nfproto ipv4 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
 
     }
 
     }
 
  }
 
  }
Zeile 228: Zeile 238:
 
  ''transport_protocol'' dport { ''port number'' }
 
  ''transport_protocol'' dport { ''port number'' }
 
<span id="eigene-ketten"></span>
 
<span id="eigene-ketten"></span>
 
 
= Eigene Ketten =
 
= Eigene Ketten =
  
Zeile 238: Zeile 247:
 
  define wandev = ens18
 
  define wandev = ens18
 
  define landev = ens19
 
  define landev = ens19
  define wanip = 10.82.229.11
+
  define wanip = 10.82.232.11
  define lan = 10.82.244.0/24
+
  define lan = 192.168.4.0/24
  define webserver = 10.82.244.8
+
  define webserver = 192.168.4.11
 
   
 
   
 
  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
        ct state new iifname "lo" accept
+
        ct state new iifname "lo" 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
        ct state new iifname $wandev ip daddr $webserver tcp dport 22 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 iifname $wandev ip daddr $webserver tcp dport 80 accept
        ct state new icmp type echo-request '''jump lan2wan'''
+
        ct state new icmp type echo-request '''jump lan2wan'''
        udp dport 53 '''jump lan2wan'''
+
        udp dport 53 '''jump lan2wan'''
        tcp dport { 25, 53, 80, 143, 443, 465, 993 } '''jump lan2wan'''
+
        tcp dport { 25, 53, 80, 143, 443, 465, 993 } '''jump lan2wan'''
        log prefix "--nftables-drop-forward--"
+
        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'''
 
     '''}'''
 
     '''}'''
 
  }
 
  }
 
  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;
        ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22
+
        ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22
        ip daddr $wanip tcp dport 80 dnat ip to $webserver:80
+
        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
 
     }
 
     }
 
  }
 
  }
Zeile 291: Zeile 300:
 
  jump ''target''
 
  jump ''target''
 
<span id="limits-setzten"></span>
 
<span id="limits-setzten"></span>
 
 
= Limits setzten =
 
= 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:
+
* 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
 
  #!/usr/sbin/nft -f
 
   
 
   
Zeile 301: Zeile 312:
 
  define wandev = ens18
 
  define wandev = ens18
 
  define landev = ens19
 
  define landev = ens19
  define wanip = 10.82.229.11
+
  define wanip = 10.82.232.11
  define lan = 10.82.244.0/24
+
  define lan = 192.168.4.0/24
  define webserver = 10.82.244.8
+
  define webserver = 192.168.4.11
 
   
 
   
 
  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
Zeile 314: Zeile 325:
 
         '''limit rate 5/minute''' log prefix "--nftables-drop-input--"
 
         '''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 320: Zeile 331:
 
         '''limit rate 5/minute''' log prefix "--nftables-drop-output--"
 
         '''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;
Zeile 331: Zeile 342:
 
         '''limit rate 5/minute''' log prefix "--nftables-drop-forward--"
 
         '''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
Zeile 337: Zeile 348:
 
  }
 
  }
 
  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;
        meta nfproto ipv4 ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22
+
    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
+
    meta nfproto ipv4 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
    }
+
}
 
  }
 
  }
 
<span id="vpns-ermöglichen"></span>
 
<span id="vpns-ermöglichen"></span>
 
= VPNs ermöglichen =
 
= 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.
+
<ul>
 +
<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>
 +
<li><p>Nachdem eine Secure Association hergestellt wurde, müssen ESP Pakete von der Firewall zugelassen und die entpackten Pakete weitergeleitet werden.</p></li>
 +
<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>
 +
<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 {
 +
type filter hook output priority filter; policy drop;
 +
    ct state established,related,new accept
 +
    limit rate 5/minute log prefix "--nftables-drop-output--"
 +
  }
 +
<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>
 +
  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
 +
  }
 +
<p>chain postrouting { type nat hook postrouting priority srcnat; policy accept; oifname $wandev ip saddr $lan snat ip to $wanip } }</p></li></ul>
  
* vim fw.nft
 
 
<!----->
 
#!/usr/sbin/nft -f
 
 
flush ruleset
 
define wandev = ens18
 
define landev = ens19
 
define wanip = 10.82.229.11
 
define lan = 10.82.244.0/24
 
'''define VPN = 192.168.178.0/24'''
 
define webserver = 10.82.244.8
 
 
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, …
 
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
 
* 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 10.82.244.1
+
 
… dass nur Pakete mit einer Ursprungs-IP von 10.82.244.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:
+
… 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
 
  #!/usr/sbin/nft -f
Zeile 430: Zeile 404:
 
  define wandev = ens18
 
  define wandev = ens18
 
  define landev = ens19
 
  define landev = ens19
  define wanip = 10.82.229.11
+
  define wanip = 10.82.232.11
  define lan = 10.82.244.0/24
+
  define lan = 192.168.4.0/24
  define VPN = 192.168.178.0/24
+
  define vpn = 192.168.178.0/24
  define webserver = 10.82.244.8
+
  define webserver = 192.168.4.11
 
   
 
   
 
  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
Zeile 447: Zeile 421:
 
         limit rate 5/minute log prefix "--nftables-drop-input--"
 
         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
+
        ct state established,related,new accept
        limit rate 5/minute log prefix "--nftables-drop-output--"
+
        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
+
        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 22 accept
        iifname $wandev meta nfproto ipv4 ip daddr $webserver tcp dport 80 accept
+
        iifname $wandev meta nfproto ipv4 ip daddr $webserver tcp dport 80 accept
        icmp type echo-request jump lan2wan
+
        icmp type echo-request jump lan2wan
        udp dport 53 jump lan2wan
+
        udp dport 53 jump lan2wan
        tcp dport { 25, 53, 80, 143, 443, 465, 993 } jump lan2wan
+
        tcp dport { 25, 53, 80, 143, 443, 465, 993 } jump lan2wan
        iifname $wandev ip saddr $VPN ct state new jump ipsec
+
        iifname $wandev ip saddr $vpn ct state new jump ipsec
        limit rate 5/minute log prefix "--nftables-drop-forward--"
+
        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 {
 
  table inet nat {
    chain prerouting {
+
chain prerouting {
        type nat hook prerouting priority dstnat; policy accept;
+
    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 9922 dnat ip to $webserver:22
        meta nfproto ipv4 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80
+
    meta nfproto ipv4 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 '''ip daddr != $VPN''' snat ip to $wanip
+
    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…
 
 
* …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
 
  
<!----->
+
<ul>
15:27:31.091907 IP fw-linkai > 10.82.228.2: ESP(spi=0xc668795e,seq=0x4), length 136
+
<li><p>…ohne die Ziel-IPs auszuschließen: tcpdump -i ens18 icmp or esp</p>
15:27:31.093913 IP 10.82.228.2 > fw-linkai: ESP(spi=0xccf83bd8,seq=0x4), length 136
+
<p>15:30:07.481373 IP fw-linkai &gt; 192.168.178.2: ICMP echo request, id 2845, seq 1, length 64 15:30:08.493319 IP fw-linkai &gt; 192.168.178.2: ICMP echo request, id 2845, seq 2, length 64 15:30:09.517369 IP fw-linkai &gt; 192.168.178.2: ICMP echo request, id 2845, seq 3, length 64</p></li>
15:27:31.093913 IP 192.168.178.2 > 10.82.244.1: ICMP echo reply, id 32171, seq 1, length 64
+
<li><p>…wenn die Ziel-IPs auszuschließen werden: tcpdump -i ens18 icmp or esp</p>
15:27:32.093502 IP fw-linkai > 10.82.228.2: ESP(spi=0xc668795e,seq=0x5), length 136
+
<p>15:27:31.091907 IP fw-linkai &gt; 10.82.228.2: ESP(spi=0xc668795e,seq=0x4), length 136 15:27:31.093913 IP 10.82.228.2 &gt; fw-linkai: ESP(spi=0xccf83bd8,seq=0x4), length 136 15:27:31.093913 IP 192.168.178.2 &gt; 192.168.4.1: ICMP echo reply, id 32171, seq 1, length 64 15:27:32.093502 IP fw-linkai &gt; 10.82.228.2: ESP(spi=0xc668795e,seq=0x5), length 136 15:27:32.095404 IP 10.82.228.2 &gt; fw-linkai: ESP(spi=0xccf83bd8,seq=0x5), length 136 15:27:32.095404 IP 192.168.178.2 &gt; 192.168.4.1: ICMP echo reply, id 32171, seq 2, length 64 15:27:33.095023 IP fw-linkai &gt; 10.82.228.2: ESP(spi=0xc668795e,seq=0x6), length 136 15:27:33.096880 IP 10.82.228.2 &gt; fw-linkai: ESP(spi=0xccf83bd8,seq=0x6), length 136 15:27:33.096880 IP 192.168.178.2 &gt; 192.168.4.1: ICMP echo reply, id 32171, seq 3, length 64</p></li></ul>
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 > 10.82.244.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 > 10.82.244.1: ICMP echo reply, id 32171, seq 3, length 64
 

Version vom 21. November 2022, 14:25 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