Nftables Host absichern: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
 
(109 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
=Vorüberlegung=
*Sowohl nftables als auch der Vorgänger arbeiten mit Tabellen und Ketten.
*Beim Vorgänger gab es diese praktisch schon von Haus aus.
*Bei nftables müssen wir diese selbst anlegen.
*Dies geschieht in dem man sie mit dem richtigen Hacken(Hook) verbindet.
*Dies könnte man auf der Kommandozeile machen.
*Eleganter ist es allerdings dies in eine Konfigurations Datei zu tun.
*Bei einem frisch installierten Debian oder Ubuntu System sieht die Konfiguration so aus
*Diese stellt ein Zustand da, der an iptables erinnert.
*Wir haben die filter Tabelle und 3 Ketten: input, output und forward erstellt.
*Wenn wir die Konfiguration laden wird impliziet die Default Policy accept gesetzt.


=Datei=
=Die ersten wirklichen Regeln die etwas bewirken=
*cat /etc/nftables.conf
*Momentan wollen wir nur den Host absichern.
<pre>
*Darum können wir die '''forward''' Kette erstmal aussen vor lassen.
#!/usr/sbin/nft -f
*Wir beziehen uns also nur auf den Host selbst.
*Wir wollen nun folgendes tun:
*<span style="color:#202FF0">Der Rechner soll mit sich selbst über das Loopback Interface kommunizieren können.</span>
*<span style="color:#004334">Vom Rechner selbst nach aussen soll alles zugelassen werden </span>
*<span style="color:#8a2be2">Auf den Rechner soll per "ssh" zugegriffen werden können.</span>


flush ruleset
=Die erste sinnvolle Konfiguration=
{{nftabels-var1
| kit = 172.22.0.0/16
}}
# Alte Regeln löschen (flush)
flush ruleset


table inet filter {
table inet filter {
        chain input {
        chain input {
                type filter hook input priority 0;
                type filter hook input priority filter; policy drop;
        }
                ct state established,related accept
        chain forward {
                <span style="color:#8a2be2">ct state new iif "lo" accept</span>
                type filter hook forward priority 0;
                <span style="color:#8a2be2">ct state new tcp dport 22 accept</span>
        }
        chain output {
        }
                type filter hook output priority 0;
     
        }
}
        chain output {
                type filter hook output priority filter; policy drop;
                ct state established,related accept
                <span style="color:#004334">ct state new accept</span>
          }
}
{{vorlage:nat2}}
==Aktivieren und Kontrolliere==
;Aktivieren
*nft -f /etc/nftables.conf
;Kontrollieren
*nft list ruleset
 
=Wir schalten ping frei=
{{nftabels-var1
| kit = 172.22.0.0/16
}}
# Alte Regeln löschen (flush)
flush ruleset


</pre>
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
                <span style="color:#8a2be2">ct state new icmp type echo-request accept</span>
        }
     
        chain output {
                type filter hook output priority filter; policy drop;
                ct state established,related accept
                <span style="color:#004334">ct state new accept</span>
          }
}
{{vorlage:nat2}}


=Laden der Konfigurationsdatei=
==Aktivieren und Kontrolliere==
;Aktivieren
*nft -f /etc/nftables.conf
*nft -f /etc/nftables.conf
=Listen der aktuellen Konfiguration=
;Kontrollieren
*nft list ruleset
*nft list ruleset
<pre>
table inet filter {
chain input {
type filter hook input priority filter; policy accept;
}


chain forward {
=Wir loggen=
type filter hook forward priority filter; policy accept;
*Wir wollen die abgelehnten Pakete loggen.
}
*Die Idee dahinter ist, wir schreiben eine Regel kurz bevor die Default Policy greift.
*<span style="color:#FF0000">Neu: Wir fügen in jeder Kette eine log-Regel ein, um verworfene Pakete zu protokollieren</span>


chain output {
{{nftabels-var1
type filter hook output priority filter; policy accept;
| kit = 172.22.0.0/16
}
}}
}
# Alte Regeln löschen (flush)
</pre>
flush ruleset
=Welchen Zustand haben wir denn nun?=
table inet filter {
*Ein Paket geht grundsätzlich nur durch eine filter Kette.
        chain input {
*Ist das Paket für den Rechner selbst bestimmt, ist es die input Kette.
                type filter hook input priority filter; policy drop;
*Wird das Paket von einem lokalen Prozess generiert geht es durch die output Kette raus.
                ct state established,related accept
*Kommt es von einem anderen Rechner und wird es weitergeleietet ist es die forward Kette.
                ct state new iif "lo" accept
                ct state new tcp dport 22 accept
                ct state new icmp type echo-request accept
                  <span style="color:#8a2be2">log prefix " --nftables-drop-input-- "</span>
        }
   


{{#drawio:nftables-filter}}
        chain output {
=Funktionsweise=
                type filter hook output priority filter; policy drop;
==Regeln==
                ct state established,related accept
*Jede dieser Kette hat nun eine Aneinanderreihung von Regeln.
                ct state new oif "lo" accept
*Diese werden von oben nach unten durchlaufen.
                ct state new accept
*Trift eine wird sie angewandt, das bedeutet das sie nicht weiter geprüft wird.
                  <span style="color:#8a2be2">log prefix " --nftables-drop-output-- "</span>
*Es gibt hier aber auch je nach Ziel Ausnahmen
        }
*Am Ende wird die Default Policy angewandt.
}
==Ziele der Filter Ketten==
ACCEPT: das Paket kann passieren
REJECT: das Paket wird zurückgewiesen und ein Fehlerpaket wird gesendet
LOG: schreibt einen Eintrag in die syslog
DROP: das Paket wird ignoriert und keine Antwort gesendet


{| class="wikitable"
{{vorlage:nat2}}
!colspan="6"|filter table
|-style="font-style: italic; color: blue;"
||input||output||forward
|-
||rule 1 ||rule 1 ||rule 1
|-
||rule 2 ||rule 2 ||rule 2
|-
||rule 3 ||rule 3 ||
|-
||rule 4 ||||
|-style="font-style: italic; color: red;"
||DEFAULT POLICY||DEFAULT POLICY||DEFAULT POLICY
|}
=Wir ändern nun die Default Policy auf drop=
*cat /etc/nftables.conf
<pre>
#!/usr/sbin/nft -f


flush ruleset
*nft -f /etc/nftables.conf
table inet filter {
*nft list ruleset
chain input {
type filter hook input priority filter; policy drop;
}
 
chain forward {
type filter hook forward priority filter; policy drop;
}


chain output {
;Checken von eurem Host
type filter hook output priority filter; policy drop;
*netcat -vz 192.168.HS.2XX 80
}
;Kontrolle auf der firewall
}
*journalctl -fkg nft
</pre>
=Überlegung=
*Es ist momentan keine Idee das Firewallscript zu aktivieren.
*Wenn wir per ssh eingelogt wären, würden wir uns selbst abschiessen.
*Wir warten also noch mit der Aktivierung
=Connection Tracking=
*Beim Connection Tracking wird über jede Verbindung die durchgelassen wird, Buch geführt.
*Eine Verbindung die neu initiert wird, hat den Status '''new'''.  
*Ein Paket das zu einer bestehenden Verbindung gehört, hat den Status '''established'''.
*Es gibt noch den Zustand '''related'''. Dies bezieht sich auf icmp Pakete die einen Bezug zu dieser Verbindung haben.
*Oder auch Mehr Kanal Verbindungen wie beispielsweise ftp oder sip.
*Bei den Verbindung wird auch das eigentlich Verbindungslose Protokoll '''udp''' mit einbezogen.
*Dies wird über einen Timer geregelt.
=Die Idee hinter dem Connection Tracking=
*Die Idee ist nun alle '''established''' und '''related''' Pakekte freizuschalten.
*Und nur die Verbindungsinitiativen freizuschalten.
*Das Firewall Framework lässt dann jeweils nur die Pakete durch die zu einer bestehenden Verbindung gehören.
=Einbauen des Connection Tracking Grundgerüst=
*Wir erlauben alle Pakete die zu einer bestehenden Verbindung gehören.
*Wir erlauben alle Pakete die in einer Relation zu einer bestehenden Verbindung stehen.
*'''Achtung''' Die Firwall lässt immer noch nichts durch, weil wir noch keine neue Verbindung erlauben.


*cat /etc/nftables.conf
=DHCP für das Lan freischalten=
<pre>
*<span style="color:#FF0000">Neu: Wir schalten für das LAN UDP Port 67 frei</span>
#!/usr/sbin/nft -f


flush ruleset
{{nftabels-var1
table inet filter {
| kit = 172.22.0.0/16
chain input {
}}
type filter hook input priority filter; policy drop;
<span style="color:#8a2be2">define LANDEV = enp0s9</span>
                ct state established,related accept
# Alte Regeln löschen (flush)
}
flush ruleset
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
                <span style="color:#8a2be2">ct state new iif $LANDEV udp dport 67 accept</span>
                log prefix " --nftables-drop-input-- "
        }
   


chain forward {
        chain output {
type filter hook forward 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 oif "lo" accept
                ct state new accept
                log prefix " --nftables-drop-output-- "
        }
}


chain output {
{{vorlage:nat2}}
type filter hook output priority filter; policy drop;
                ct state established,related accept
}
}
</pre>
=Die ersten wirklichen Regeln die etwas bewirken=
*Momentan wollen wir nur den Host absichern.
*Darum können wir die '''forward''' Kette erstmal aussen vor lassen.
*Wir beziehen uns also nur auf den Host selbst.
*Wir wollen nun folgendes tun:
*<span style="color:#202FF0">Der Rechner soll mit sich selbst über das Loopback Interface kommunizieren können.</span>
*<span style="color:#004334">Vom Rechner selbst nach aussen soll zugelassen werden tcp 22,25,53,80,465,443, udp 53 und icmp</span>
*<span style="color:#8a2be2">Auf den Rechner soll per "ssh, http und https" zugegriffen werden können.</span>
=Die erste sinnvolle Konfiguration=
*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 }


flush ruleset
==nftables Logging über journalctl ==
table inet filter {
;Erklärung
        chain input {
*journalctl -k -f -g nftables
                type filter hook input priority filter; policy drop;
;Nur Logtext ohne Metadaten
                ct state established,related accept
*journalctl -k -f -g nftables -o cat
                ct state new tcp dport $local_tcp_ports accept
;Logausgabe mit ISO-Zeitformat
*journalctl -k -f -g nftables -o short-iso
;Nur drop-input
*journalctl -k -f -g nftables-drop-input


        }
=Aktivieren der Firewall beim Systemstart=
        chain forward {
*systemctl enable nftables --now
                type filter hook forward priority filter; policy drop;
                ct state established,related accept
        }


        chain output {
=Source oder Destination IP oder Netze=
                type filter hook output priority filter; policy drop;
;Hinweis für die Aufgaben.
                ct state established,related accept
Source Ips oder Netze werden mit einem '''ip saddr <IP>''' angeben
                ct state new oifname "lo" accept
                ct state new tcp dport $remote_tcp_ports accept
                ct state new udp dport $remote_udp_ports accept


        }
Destination Ips oder Netze werden mit einem '''ip daddr <IP>''' angeben
}
;Beispiele
</pre>
=Wir loggen=
*Wir wollen die abgelehnten Pakete loggen.
*Die Idee dahinter ist wir schreiben ein Regel kurz bevor die Default Policy greift.
*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 }


flush ruleset
ct state new iif "enp0s9" ip saddr 172.26.213.0/24 tcp dport 22 accept
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 {
=Aufgabe=
                type filter hook output priority filter; policy drop;
;Tip - Es werden nur Änderungen in der input Kette vorgenommen.
                ct state established,related accept
*Grenzt den Zugriff auf die Firewall per ssh so ein das folgende Bereiche zugelassen:
                ct state new oifname "lo" accept
**DMZ
                ct state new tcp dport $remote_tcp_ports accept
**LAN
                ct state new udp dport $remote_udp_ports accept
**SERVER
                log prefix "--nftables-drop-output--"
**HOST (Der Rechner vor dem sitzt)
        }
;Testet ob die Regel greifen positiv wie negativ <nowiki>:)</nowiki>
}
</pre>


=Wir schauen und die Log Datei an=
=Handling=
*tail -f /var/log/syslog
;Regelsatz anzeigen
2022-11-09T19:07:57.409090+01:00 fedora kernel: --nftables-drop-output--IN= OUT=ens18 SRC=10.0.10.115 DST=8.8.8.8 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=43885 DF PROTO=TCP SPT=55566 DPT=87 WINDOW=64240 RES=0x00 SYN URGP=0
*nft list ruleset
 
;Regelsatz neuladen
=Aktivieren der Firewall beim Systemstart=
*systemctl restart nftables
oder
*nft -f /etc/nftables.conf
;Regelsatz löschen
*systemctl stop nftables
oder
*nft flush ruleset
;Firewall für den System aktiveren
*systemctl enable nftables
;Ist die Firewall enabled?
*systemctl is-enabled nftables
;Firewall start
*systemctl start nftables
;Firewall start und enabled
*systemctl enable nftables --now
*systemctl enable nftables --now
;Logging
*journalctl -fkg nftables

Aktuelle Version vom 28. September 2026, 06:47 Uhr

Die ersten wirklichen Regeln die etwas bewirken

  • Momentan wollen wir nur den Host absichern.
  • Darum können wir die forward Kette erstmal aussen vor lassen.
  • Wir beziehen uns also nur auf den Host selbst.
  • Wir wollen nun folgendes tun:
  • Der Rechner soll mit sich selbst über das Loopback Interface kommunizieren können.
  • Vom Rechner selbst nach aussen soll alles zugelassen werden
  • Auf den Rechner soll per "ssh" zugegriffen werden können.

Die erste sinnvolle Konfiguration

  • cat /etc/nftables.conf
#!/usr/sbin/nft -f

# Variablen
define WANIP = <WANIP der Firewall>
define LAN = 172.26.2XX.0/24
define MGMT = 172.27.2XX.0/24
define SERVER = 10.2XX.1.0/24
define DMZ = 10.88.2XX.0/24
define KIT = 172.22.0.0/16
define WANDEV = enp0s3
# Alte Regeln löschen (flush)
flush ruleset
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 

        }
     

        chain output {
                type filter hook output priority filter; policy drop;
                ct state established,related accept
                ct state new accept
          }
}
 table inet nat {
  chain postrouting {
   type nat hook postrouting priority 100; policy accept;
        ip saddr $DMZ ip daddr $KIT return
        ip saddr $DMZ ip daddr 10.88.0.0/16 return
        ip saddr $DMZ oif $WANDEV snat to $WANIP
        ip saddr $LAN oif $WANDEV snat to $WANIP
        ip saddr $SERVER oif $WANDEV snat to $WANIP
        ip saddr $MGMT oif $WANDEV snat to $WANIP
     }
  }

Aktivieren und Kontrolliere

Aktivieren
  • nft -f /etc/nftables.conf
Kontrollieren
  • nft list ruleset

Wir schalten ping frei

  • cat /etc/nftables.conf
#!/usr/sbin/nft -f

# Variablen
define WANIP = <WANIP der Firewall>
define LAN = 172.26.2XX.0/24
define MGMT = 172.27.2XX.0/24
define SERVER = 10.2XX.1.0/24
define DMZ = 10.88.2XX.0/24
define KIT = 172.22.0.0/16
define WANDEV = enp0s3
# Alte Regeln löschen (flush)
flush ruleset
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 
        }
     

        chain output {
                type filter hook output priority filter; policy drop;
                ct state established,related accept
                ct state new accept
          }
}
 table inet nat {
  chain postrouting {
   type nat hook postrouting priority 100; policy accept;
        ip saddr $DMZ ip daddr $KIT return
        ip saddr $DMZ ip daddr 10.88.0.0/16 return
        ip saddr $DMZ oif $WANDEV snat to $WANIP
        ip saddr $LAN oif $WANDEV snat to $WANIP
        ip saddr $SERVER oif $WANDEV snat to $WANIP
        ip saddr $MGMT oif $WANDEV snat to $WANIP
     }
  }

Aktivieren und Kontrolliere

Aktivieren
  • nft -f /etc/nftables.conf
Kontrollieren
  • nft list ruleset

Wir loggen

  • Wir wollen die abgelehnten Pakete loggen.
  • Die Idee dahinter ist, wir schreiben eine Regel kurz bevor die Default Policy greift.
  • Neu: Wir fügen in jeder Kette eine log-Regel ein, um verworfene Pakete zu protokollieren
  • cat /etc/nftables.conf
#!/usr/sbin/nft -f

# Variablen
define WANIP = <WANIP der Firewall>
define LAN = 172.26.2XX.0/24
define MGMT = 172.27.2XX.0/24
define SERVER = 10.2XX.1.0/24
define DMZ = 10.88.2XX.0/24
define KIT = 172.22.0.0/16
define WANDEV = enp0s3
# Alte Regeln löschen (flush)
flush ruleset
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 accept
                ct state new oif "lo" accept
                ct state new accept
                 log prefix " --nftables-drop-output-- "
        }
}
 table inet nat {
  chain postrouting {
   type nat hook postrouting priority 100; policy accept;
        ip saddr $DMZ ip daddr $KIT return
        ip saddr $DMZ ip daddr 10.88.0.0/16 return
        ip saddr $DMZ oif $WANDEV snat to $WANIP
        ip saddr $LAN oif $WANDEV snat to $WANIP
        ip saddr $SERVER oif $WANDEV snat to $WANIP
        ip saddr $MGMT oif $WANDEV snat to $WANIP
     }
  }
  • nft -f /etc/nftables.conf
  • nft list ruleset
Checken von eurem Host
  • netcat -vz 192.168.HS.2XX 80
Kontrolle auf der firewall
  • journalctl -fkg nft

DHCP für das Lan freischalten

  • Neu: Wir schalten für das LAN UDP Port 67 frei
  • cat /etc/nftables.conf
#!/usr/sbin/nft -f

# Variablen
define WANIP = <WANIP der Firewall>
define LAN = 172.26.2XX.0/24
define MGMT = 172.27.2XX.0/24
define SERVER = 10.2XX.1.0/24
define DMZ = 10.88.2XX.0/24
define KIT = 172.22.0.0/16
define WANDEV = enp0s3
define LANDEV = enp0s9
# Alte Regeln löschen (flush)
flush ruleset
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 
                ct state new iif $LANDEV udp dport 67 accept
                log prefix " --nftables-drop-input-- "
        }
   
        chain output {
                type filter hook output priority filter; policy drop;
                ct state established,related accept
                ct state new oif "lo" accept
                ct state new accept
                log prefix " --nftables-drop-output-- "
        }
}
 table inet nat {
  chain postrouting {
   type nat hook postrouting priority 100; policy accept;
        ip saddr $DMZ ip daddr $KIT return
        ip saddr $DMZ ip daddr 10.88.0.0/16 return
        ip saddr $DMZ oif $WANDEV snat to $WANIP
        ip saddr $LAN oif $WANDEV snat to $WANIP
        ip saddr $SERVER oif $WANDEV snat to $WANIP
        ip saddr $MGMT oif $WANDEV snat to $WANIP
     }
  }

nftables Logging über journalctl

Erklärung
  • journalctl -k -f -g nftables
Nur Logtext ohne Metadaten
  • journalctl -k -f -g nftables -o cat
Logausgabe mit ISO-Zeitformat
  • journalctl -k -f -g nftables -o short-iso
Nur drop-input
  • journalctl -k -f -g nftables-drop-input

Aktivieren der Firewall beim Systemstart

  • systemctl enable nftables --now

Source oder Destination IP oder Netze

Hinweis für die Aufgaben.

Source Ips oder Netze werden mit einem ip saddr <IP> angeben

Destination Ips oder Netze werden mit einem ip daddr <IP> angeben

Beispiele
ct state new iif "enp0s9" ip saddr 172.26.213.0/24 tcp dport 22 accept

Aufgabe

Tip - Es werden nur Änderungen in der input Kette vorgenommen.
  • Grenzt den Zugriff auf die Firewall per ssh so ein das folgende Bereiche zugelassen:
    • DMZ
    • LAN
    • SERVER
    • HOST (Der Rechner vor dem sitzt)
Testet ob die Regel greifen positiv wie negativ :)

Handling

Regelsatz anzeigen
  • nft list ruleset
Regelsatz neuladen
  • systemctl restart nftables

oder

  • nft -f /etc/nftables.conf
Regelsatz löschen
  • systemctl stop nftables

oder

  • nft flush ruleset
Firewall für den System aktiveren
  • systemctl enable nftables
Ist die Firewall enabled?
  • systemctl is-enabled nftables
Firewall start
  • systemctl start nftables
Firewall start und enabled
  • systemctl enable nftables --now
Logging
  • journalctl -fkg nftables