Nftables Netze absichern: Unterschied zwischen den Versionen
| Zeile 1: | Zeile 1: | ||
| + | <span id="einleitung"></span> | ||
| + | = 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 = |
| − | + | ||
| − | + | * 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 = | ||
| − | |||
{{#drawio:netzplan-nftables-1}} | {{#drawio:netzplan-nftables-1}} | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | + | <span id="das-grundgerüst"></span> | |
| − | + | = 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--" | ||
| + | } | ||
| + | } | ||
| + | <span id="forwarding"></span> | ||
| + | = 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 | + | |
| − | *sysctl -p | + | * echo “net.ipv4.ip_forward = 1” >> /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. | ||
| + | |||
| + | <!-----> | ||
#!/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 = | + | define wandev = ens18 |
| − | define dmzdev = | + | define dmzdev = ens19 |
| − | define landev = | + | define landev = ens20 |
| − | define wanip = 10.82. | + | define wanip = 10.82.232.11 |
| − | define lan = | + | 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; | |
| − | + | 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; | |
| − | + | 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; | |
| − | + | 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;''' | |
'''}''' | '''}''' | ||
| − | + | '''chain postrouting {''' | |
| − | + | '''type nat hook postrouting priority srcnat; policy accept;''' | |
| − | + | '''oifname $wandev ip saddr $lan snat ip to $wanip''' | |
| − | + | '''}''' | |
'''}''' | '''}''' | ||
Neu verwendete Syntax: | Neu verwendete Syntax: | ||
| Zeile 127: | Zeile 161: | ||
<!-----> | <!-----> | ||
| − | + | oifname ‘’device name’’ | |
| − | + | ||
| + | <ul> | ||
| + | <li><p>IPv4-Adresse des Ursprungpaketes</p> | ||
| + | <p>ip saddr ’‘<source address>’’</p></li></ul> | ||
| − | |||
| − | |||
<span id="portforwarding"></span> | <span id="portforwarding"></span> | ||
| − | |||
== Portforwarding == | == Portforwarding == | ||
| − | |||
| − | |||
| − | + | <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> | |
| − | + | <li><p>Hierbei kann es ein anderer, nicht-standard Port der Firewall sein.</p> | |
| − | + | <p>#!/usr/sbin/nft -f</p> | |
| − | + | <p>flush ruleset</p> | |
| − | + | <p>flush ruleset define remote_tcp_ports = { 22,25,53,80,465,443 } define remote_udp_ports = { 53 } define local_tcp_ports = { 22,80,443 } define wandev = ens18 define dmzdev = ens19 define landev = ens20 define wanip = 10.82.232.11 define lan = 192.168.4.0/24 ’‘’define webserver = 192.168.4.12’’’</p> | |
| − | + | <p>table inet filter { chain input { type filter hook input priority filter; policy drop; ct state established,related accept iifname “lo” ct state new accept ct state new tcp dport 22 accept ct state new icmp type echo-request accept log prefix “–nftables-drop-input–”</p></li></ul> | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
<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. | + | define wanip = 10.82.232.11 |
| − | define lan = | + | define lan = 192.168.4.0/24 |
| − | define webserver = | + | define webserver = 192.168.4.12 |
table inet filter { | 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 { | 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 | |
} | } | ||
} | } | ||
| 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. | + | define wanip = 10.82.232.11 |
| − | define lan = | + | define lan = 192.168.4.0/24 |
| − | define webserver = | + | define webserver = 192.168.4.11 |
table inet filter { | 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 { | chain output { | ||
| − | + | type filter hook output priority filter; policy drop; | |
| − | + | ct state established,related,new accept | |
| − | + | log prefix "--nftables-drop-output--" | |
} | } | ||
| − | + | ||
chain forward { | 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 { | table inet nat { | ||
| − | + | chain prerouting { | |
| − | + | type nat hook prerouting priority dstnat; policy accept; | |
| − | + | ip daddr $wanip tcp dport 9922 dnat ip to $webserver:22 | |
| − | + | ip daddr $wanip tcp dport 80 dnat ip to $webserver:80 | |
} | } | ||
| − | + | ||
chain postrouting { | chain postrouting { | ||
| − | + | type nat hook postrouting priority srcnat; policy accept; | |
| − | + | 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. | + | define wanip = 10.82.232.11 |
| − | define lan = | + | define lan = 192.168.4.0/24 |
| − | define webserver = | + | define webserver = 192.168.4.11 |
table inet filter { | table inet filter { | ||
| − | + | 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 { | |
| − | + | 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 | |
| − | + | } | |
} | } | ||
<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> | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
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 | |
| − | + | ||
| − | … dass nur Pakete mit einer Ursprungs-IP von | + | … 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. | + | define wanip = 10.82.232.11 |
| − | define lan = | + | define lan = 192.168.4.0/24 |
| − | define | + | define vpn = 192.168.178.0/24 |
| − | define webserver = | + | define webserver = 192.168.4.11 |
table inet filter { | table inet filter { | ||
| − | + | chain input { | |
| − | + | 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; | |
| − | + | ct state established,related,new accept | |
| − | + | limit rate 5/minute log prefix "--nftables-drop-output--" | |
} | } | ||
| − | + | ||
chain forward { | chain forward { | ||
| − | + | type filter hook forward priority filter; policy drop; | |
| − | + | ct state established,related accept | |
| − | + | iifname $wandev meta nfproto ipv4 ip daddr $webserver tcp dport 22 accept | |
| − | + | iifname $wandev meta nfproto ipv4 ip daddr $webserver tcp dport 80 accept | |
| − | + | icmp type echo-request jump lan2wan | |
| − | + | udp dport 53 jump lan2wan | |
| − | + | tcp dport { 25, 53, 80, 143, 443, 465, 993 } jump lan2wan | |
| − | + | iifname $wandev ip saddr $vpn ct state new jump ipsec | |
| − | + | limit rate 5/minute log prefix "--nftables-drop-forward--" | |
} | } | ||
| − | + | ||
chain lan2wan { | chain lan2wan { | ||
| − | + | ct state new iifname $landev oifname $wandev ip saddr $lan accept | |
} | } | ||
| − | + | ||
chain ipsec { | chain ipsec { | ||
| − | + | accept | |
} | } | ||
} | } | ||
table inet nat { | 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 | + | Zum Vergleich die ‘’tcpdump’’-Analysen bei einem Ping auf einen der Rechner im VPN… |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | < | + | <ul> |
| − | + | <li><p>…ohne die Ziel-IPs auszuschließen: tcpdump -i ens18 icmp or esp</p> | |
| − | + | <p>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</p></li> | |
| − | + | <li><p>…wenn die Ziel-IPs auszuschließen werden: tcpdump -i ens18 icmp or esp</p> | |
| − | + | <p>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</p></li></ul> | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
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

