Nftables Netze absichern

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen

Einleitung

  • Nachdem wir ein Hostsystem abgesichert haben, kommen wir nun zum Absichern von Netzen.
  • Die Firewall agiert als Vermittler zwischen verschiedenen Netzen.
  • In unserem Beispiel haben wir 3 Netzbereiche.

WAN

  • Wide Area Net steht für alles was nicht die anderen beiden Netze betrifft

LAN

  • Local Area Net steht in der Regel für ein Netz das von aussen nicht erreichbar ist.
  • Meist ist es über Network Address Translation (NAT) angebunden.

DMZ

  • Demilitarized Zone ist ein Netz welches von außen erreichbar ist.
  • Die Zugriffe werden aber durch die Firewall abgesichert.
  • Dort werden meistens Dienste wie Mail oder Web gehostet. Teilweise auch Proxy Server.

Der Plan

Das Grundgerüst

  • Wir nutzen unsere Host Firewall als Ausgangsskript
  • Wir wollen aber von vorneherein verstärkt mit Variablen arbeiten.
  • Dies macht die Skripte universeller.
  • vim /etc/nftables.conf
#!/usr/sbin/nft -f
define wandev = enp0s3
define wanip = 192.168.5.113
define lan = 172.17.113.0/24
define server = 172.16.113.0/24
define mgmt = 172.18.113.0/24
define dmz = 10.88.113.0/24

define local_tcp_ports = { 22 }

flush ruleset
table inet filter {
        chain input {
                type filter hook input priority filter; policy drop;
                ct state established,related accept
                ct state new iifname "lo" accept
                ct state new tcp dport $local_tcp_ports accept
                ct state new icmp type echo-request accept
                log prefix "--nftables-drop-input--"
        }



        chain output {
                type filter hook output priority filter; policy drop;
                ct state established,related accept
                ct state new oifname "lo" accept
                ct state new accept
                log prefix "--nftables-drop-output--"
        }
}


table inet nat {
    chain postrouting {
        type nat hook postrouting priority 100; policy accept;

        oif $wandev ip saddr $lan snat to $wanip
        oif $wandev ip saddr $server snat to $wanip
        oif $wandev ip saddr $mgmt snat to $wanip
        # DMZ wird genattet, außer zu 10.88.0.0/16 und 10.82.89.0/24
        oif $wandev ip saddr $dmz ip daddr != { 10.88.0.0/16, 10.82.89.0/24 } snat to $wanip
    }

Forwarding

Damit Pakete weitergeleitet werden können, muss als erstes FORWARDING im Kernel aktiviert werden.

Aktivierung

* echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf * sysctl -p

Weitere Tabellen

* Eine Skizze über die Reihenfolge der Hooks. * Als erstes greift der Prerouting-Hook * Je nachdem wie geroutet wird greift dann entweder Input- oder Fowrward-Hook * Falls ein lokaler Prozess ein Paket sendet, dann greift der Output-Hook * Als letztes kann man das Paket mit dem Postrouting-Hook beeinflußen

SNAT

* Rechner in einem LAN können nicht ohne weiteres mit dem WAN kommunizieren, da an die lokale IP-Adresse der Rechner im LAN nicht von außen geroutet werden kann. * Um eine Internetverbindung aufzubauen, muss die Adresse aus dem LAN in eine öffentliche umgeschrieben werden. #!/usr/sbin/nft -f 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 iif "lo" ct state new accept ct state new tcp dport 22 accept ct state new icmp type echo-request accept log prefix "--nftables-drop-input--" } chain output { type filter hook output priority filter; policy drop; ct state established,related,new accept log prefix "--nftables-drop-output--" } chain forward { type filter hook forward priority filter; policy drop; ct state established,related accept 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; oif $wandev ip saddr $lan snat ip to $wanip } } Neu verwendete Syntax: * Definieren einer Variable define variable_name = value * Interface des herausgehenden Paketes: oif device_name * matche IPv4-Adresse des Ursprungpaketes ip saddr <source_ip> * Die Ursprungs-IP auf eine andere Adresse natten snat ip to <new_source_ip>

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 iif "lo" ct state new accept ct state new tcp dport 22 accept ct state new icmp type echo-request accept log prefix "--nftables-drop-input--" } chain output { type filter hook output priority filter; policy drop; ct state established,related,new accept log prefix "--nftables-drop-output--" } chain forward { type filter hook forward priority filter; policy drop; ct state established,related accept iif $wandev ip daddr $webserver tcp dport 22 accept iif $wandev ip daddr $webserver tcp dport 80 accept log prefix "--nftables-drop-forward--" } } table inet nat { chain prerouting { type nat hook prerouting priority dstnat; policy accept; ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80 } chain postrouting { type nat hook postrouting priority srcnat; policy accept; oif $wandev ip saddr $lan snat ip to $wanip } } * Nun kann man per SSH auf den Rechner hinter der Firewall über Port 9922 der Firewall zugreifen... * ssh user@WEBSERVER -p 9922 * ... und HTTP-Requests an den Rechner hinter der Firewall schicken * curl WEBSERVER Neu verwendete Syntax: * matche die Ziel IP-Adresse ip daddr <target_ip> * Ziel IP-Adresse auf eine andere natten dnat ip to <new_target_ip>

Absichern von Netzen

Momentan wird nichts vom LAN zum WAN weitergeleitet. Um nur bestimmte Anwendungen zu erlauben kann man die für diese designierten Ports freischalten. #!/usr/sbin/nft -f flush ruleset define remote_tcp_ports = { 22,25,53,80,465,443 } define remote_udp_ports = { 53 } define local_tcp_ports = { 22,80,443 } define wandev = ens18 define dmzdev = ens19 define landev = ens20 define lan = 192.168.4.0/24 define wanip = 10.82.232.11 define webserver = 192.168.4.12 table inet filter { chain input { type filter hook input priority filter; policy drop; ct state established,related accept iif "lo" ct state new accept ct state new tcp dport 22 accept ct state new icmp type echo-request accept log prefix "--nftables-drop-input--" } chain output { type filter hook output priority filter; policy drop; ct state established,related,new accept log prefix "--nftables-drop-output--" } chain forward { type filter hook forward priority filter; policy drop; ct state established,related accept iif $wandev ip daddr $webserver tcp dport 22 accept iif $wandev ip daddr $webserver tcp dport 80 accept ct state new iif $landev oif $wandev ip saddr $lan icmp type echo-request accept ct state new iif $landev oif $wandev ip saddr $lan udp dport 53 accept ct state new iif $landev oif $wandev ip saddr $lan tcp dport { 25, 53, 80, 143, 443, 465, 993 } accept log prefix "--nftables-drop-forward--" } } table inet nat { chain prerouting { type nat hook prerouting priority dstnat; policy accept; ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80 } chain postrouting { type nat hook postrouting priority srcnat; policy accept; oif $wandev ip saddr $lan snat ip to $wanip } } Neu verwendete Syntax: Bestimmte Ziel-Ports angeben transport_protocol dport { port_number_1,port_number_2,... }

Eigene Ketten

Man kann auch Ketten ohne Default Policy oder Hooks erstellen, die mehrere Regeln zusammenfassen. In diese Ketten gelangt man durch die Basisketten. #!/usr/sbin/nft -f flush ruleset define wandev = ens18 define dmzdev = ens19 define landev = ens20 define wanip = 10.82.232.11 define lan = 192.168.4.0/24 define webserver = 192.168.4.12 table inet filter { chain input { type filter hook input priority filter; policy drop; ct state established,related accept ct state new iif "lo" accept ct state new tcp dport 22 accept ct state new icmp type echo-request accept log prefix "--nftables-drop-input--" } chain output { type filter hook output priority filter; policy drop; ct state established,related,new accept log prefix "--nftables-drop-output--" } chain forward { type filter hook forward priority filter; policy drop; ct state established,related accept ct state new iif $wandev ip daddr $webserver tcp dport 22 accept ct state new iif $wandev ip daddr $webserver tcp dport 80 accept ct state new icmp type echo-request jump lan2wan udp dport 53 jump lan2wan tcp dport { 25, 53, 80, 143, 443, 465, 993 } jump lan2wan log prefix "--nftables-drop-forward--" } chain lan2wan { ct state new iif $landev oifname $wandev ip saddr $lan accept } } table inet nat { chain prerouting { type nat hook prerouting priority dstnat; policy accept; ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80 } chain postrouting { type nat hook postrouting priority srcnat; policy accept; oif $wandev ip saddr $lan snat ip to $wanip } } Neu verwendete Syntax: Springe in eine andere Kette jump target

Limits setzten

* Man kann die Anzahl die eine Regel annimmt zeitlich begrenzen. * Dafür fügt man limit rate in die Regel ein. * Falls nur 5 Pakete pro Minute geloggt werden sollen: #!/usr/sbin/nft -f flush ruleset define remote_tcp_ports = { 22,25,53,80,465,443 } define remote_udp_ports = { 53 } define local_tcp_ports = { 22,80,443 } define wandev = ens18 define dmzdev = ens19 define landev = ens20 define lan = 192.168.4.0/24 define wanip = 10.82.232.11 define webserver = 192.168.4.12 table inet filter { chain input { type filter hook input priority filter; policy drop; ct state established,related accept iif "lo" ct state new accept ct state new tcp dport 22 accept ct state new icmp type echo-request accept limit rate 5/minute log prefix "--nftables-drop-input--" } chain output { type filter hook output priority filter; policy drop; ct state established,related,new accept limit rate 5/minute log prefix "--nftables-drop-output--" } chain forward { type filter hook forward priority filter; policy drop; ct state established,related accept iif $wandev ip daddr $webserver tcp dport 22 accept iif $wandev ip daddr $webserver tcp dport 80 accept icmp type echo-request jump lan2wan udp dport 53 jump lan2wan tcp dport { 25, 53, 80, 143, 443, 465, 993 } jump lan2wan limit rate 5/minute log prefix "--nftables-drop-forward--" } chain lan2wan { ct state new iif $landev oif $wandev ip saddr $lan accept } } table inet nat { chain prerouting { type nat hook prerouting priority dstnat; policy accept; ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22 ip daddr $wanip tcp dport 80 dnat ip to $webserver:80 } chain postrouting { type nat hook postrouting priority srcnat; policy accept; oif $wandev ip saddr $lan snat ip to $wanip } }