Nftables Host absichern
Version vom 10. November 2022, 12:16 Uhr von Thomas.will (Diskussion | Beiträge) (→Connection Tracking)
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
- cat /etc/nftables.conf
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0;
}
chain forward {
type filter hook forward priority 0;
}
chain output {
type filter hook output priority 0;
}
}
Laden der Konfigurationsdatei
- nft -f /etc/nftables.conf
Listen der aktuellen Konfiguration
- nft list ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy accept;
}
chain forward {
type filter hook forward priority filter; policy accept;
}
chain output {
type filter hook output priority filter; policy accept;
}
}
Welchen Zustand haben wir denn nun?
- Ein Paket geht grundsätzlich nur durch eine filter Kette.
- Ist das Paket für den Rechner selbst bestimmt, ist es die input Kette.
- Wird das Paket von einem lokalen Prozess generiert geht es durch die output Kette raus.
- Kommt es von einem anderen Rechner und wird es weitergeleietet ist es die forward Kette.
Funktionsweise
Regeln
- Jede dieser Kette hat nun eine Aneinanderreihung von Regeln.
- Diese werden von oben nach unten durchlaufen.
- Trift eine wird sie angewandt, das bedeutet das sie nicht weiter geprüft wird.
- 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
| filter table | |||||
|---|---|---|---|---|---|
| input | output | forward | |||
| rule 1 | rule 1 | rule 1 | |||
| rule 2 | rule 2 | rule 2 | |||
| rule 3 | rule 3 | ||||
| rule 4 | |||||
| DEFAULT POLICY | DEFAULT POLICY | DEFAULT POLICY | |||
Wir ändern nun die Default Policy auf drop
- cat /etc/nftables.conf
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
}
chain forward {
type filter hook forward priority filter; policy drop;
}
chain output {
type filter hook output priority filter; policy drop;
}
}
Ü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.
- Dazu braucht man helper Module(prüfen)
- 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
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
}
chain output {
type filter hook output priority filter; policy drop;
ct state established,related accept
}
}
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 zugelassen werden tcp 22,25,53,80,465,443, udp 53 und icmp
- Auf den Rechner soll per "ssh, http und https" zugegriffen werden können.
Die erste sinnvolle Konfiguration
- 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 }
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
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
}
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
}
}
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
#!/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
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--"
}
}
Wir schauen und die Log Datei an
- tail -f /var/log/syslog
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
Aktivieren der Firewall beim Systemstart
- systemctl enable nftables --now
