spr-networks / super

📡 SPR: Open Source, secure, user friendly and fast wifi routers for your home. One wifi password per device. Ad Blocking & Privacy Blocklists. Policy Based Network Access
https://www.supernetworks.org/
BSD 3-Clause "New" or "Revised" License
198 stars 13 forks source link

conntrack hardening #375

Closed lts-rad closed 1 month ago

lts-rad commented 1 month ago

reviewing https://www.anvilsecure.com/wp-content/uploads/2024/10/Conntrack-Spoofing-Internal-Packets-Whitepaper-1.pdf we are somewhat affected by conntrack.

1) internal UDP/TCP services on SPR can not be accessed this way so SPR is not vulnerable to that aspect of the attack. the firewall mappings are bound by uplink or lan status in the wan_tcp_accept/lan_tcp_accept/wan_udp_accept/lan_udp_accept maps.

2) if a port is exposed externally then IP source spoofing is possible, due to conntrack. to address this the following changes should be made:

+++ b/base/scripts/nft_rules.sh
@@ -246,6 +246,10 @@ table inet filter {
     iifname @uplink_interfaces log prefix "wan:in " group 0
     iifname != @uplink_interfaces log prefix "lan:in " group 0

+    # block lan ranges from uplink interfaces
+    iifname @uplink_interfaces ip saddr @supernetworks goto DROPLOGINP
+    iifname @uplink_interfaces ip daddr @supernetworks goto DROPLOGINP
+
     # Drop input from the site to site output interfaces. They are only a sink,
     # Not a source that can connect into SPR services
     counter iifname @outbound_sites goto DROPLOGINP
@@ -270,7 +274,6 @@ table inet filter {
     $(if [ "$VIRTUAL_SPR_API_INTERNET" ]; then echo "" ;  elif [[ "$WAN_NET" ]]; then echo "counter iifname @uplink_interfaces tcp dport 80, 443 ip saddr != $WAN_NET drop"; fi)
     $(if [ "$VIRTUAL_SPR_API_INTERNET" ]; then echo "" ;  elif [[ "$WAN_NET" ]]; then echo "counter iifname @uplink_interfaces udp dport 53, 67 ip saddr != $WAN_NET drop"; fi)

-    counter jump F_EST_RELATED

     # DHCP Allow rules
     # Wired lan
@@ -284,6 +287,8 @@ table inet filter {
     # Prevent MAC Spoofing from LANIF, wired interfaces
     iifname @lan_interfaces jump DROP_MAC_SPOOF

+    counter jump F_EST_RELATED
+
     # DNS Allow rules
     # Docker can DNS
     $(if [ "$DOCKERIF" ]; then echo "iif $DOCKERIF ip saddr $DOCKERNET udp dport 53 counter accept"; fi)
@@ -343,6 +348,13 @@ table inet filter {
     # Allow DNAT for port forwarding
     counter ct status dnat accept

+    # block lan ranges from uplink interfaces
+    iifname @uplink_interfaces ip saddr @supernetworks goto DROPLOGINP
+    iifname @uplink_interfaces ip daddr @supernetworks goto DROPLOGINP
+
+    # Verify MAC addresses for LANIF/WIPHYs
+    iifname @lan_interfaces jump DROP_MAC_SPOOF
+
     counter jump F_EST_RELATED

     # Do not forward from uplink interfaces after dnat
@@ -355,8 +367,6 @@ table inet filter {
     oifname @uplink_interfaces log prefix "wan:out " group 0
     oifname != @uplink_interfaces log prefix "lan:out " group 0

-    # Verify MAC addresses for LANIF/WIPHYs
-    iifname @lan_interfaces jump DROP_MAC_SPOOF

     # After MAC SPOOF check, but before rfc1918 check
     # These rules allow permits via endpoint verdict maps

These improvements will A) prevent INPUTs with internal subnet sources or destinations B) stop internal LAN devices from spoofing each other with conntrack by enforcing the MAC filter check before F_EST_RELATED for INPUTs and FORWARD

lts-rad commented 1 month ago

the FORWARD table can't block a destination as the internal lan if NAT is supposed to work for clients.

lts-rad commented 1 month ago

addressed in v1.0.1