Development

This commit is contained in:
Matthew Grotke 2026-06-07 14:21:40 -04:00
parent 99447b4987
commit 27f2356cd1
10 changed files with 241 additions and 6 deletions

View file

@ -242,6 +242,7 @@ def build_nft_config(data, dry_run=False):
all_except = rule_enabled(data.get("inter_vlan_exceptions", []))
banned_v4, banned_v6 = banned_ip_sets(data)
container_bridges = get_container_bridges()
captive_vlans = [v for v in vlans if v.get('restricted_vlan') == 'c']
L = [
"# Generated by core.py -- do not edit manually.",
@ -314,6 +315,14 @@ def build_nft_config(data, dry_run=False):
"",
]
if captive_vlans:
L += [
" set captive_allowed {",
" type ipv4_addr",
" }",
"",
]
# INPUT chain
L += [
" # INPUT -- traffic destined for this machine itself",
@ -439,7 +448,19 @@ def build_nft_config(data, dry_run=False):
L.append(f" iif \"{validation.derive_interface(vlan, data)}\" oif \"{wan}\" drop # {vlan['name']} -> WAN (quarantined)")
L.append("")
# TODO: captive portal VLANs ('c') - PREROUTING REDIRECT rules for HTTP/HTTPS + dynamic allow-set
if captive_vlans:
L.append(" # Allow authenticated captive clients -> WAN")
for vlan in captive_vlans:
iface = validation.derive_interface(vlan, data)
L.append(f" iif \"{iface}\" oif \"{wan}\" ip saddr @captive_allowed accept"
f" # {vlan['name']} authenticated -> WAN")
L.append("")
L.append(" # Block unauthenticated captive clients -> WAN")
for vlan in captive_vlans:
iface = validation.derive_interface(vlan, data)
L.append(f" iif \"{iface}\" oif \"{wan}\" drop"
f" # {vlan['name']} -> WAN (captive, unauthenticated)")
L.append("")
L += [
" # Allow Docker containers -> WAN (outbound internet access)",
@ -505,9 +526,28 @@ def build_nft_config(data, dry_run=False):
" type filter hook output priority filter; policy accept;",
" }",
"",
"}",
]
if captive_vlans:
http_port = data.get('captive_portal', {}).get('http_port', 8081)
L += [
" chain captive_prerouting {",
f" type nat hook prerouting priority dstnat + 1; policy accept;",
"",
]
for vlan in captive_vlans:
iface = validation.derive_interface(vlan, data)
L += [
f" # Captive portal redirect - {vlan['name']}",
f" iif \"{iface}\" ip saddr != @captive_allowed tcp dport 80"
f" redirect to :{http_port}",
f" iif \"{iface}\" ip saddr != @captive_allowed tcp dport 443 drop",
"",
]
L += [" }", ""]
L.append("}")
if banned_v6:
elements = ", ".join(banned_v6)
L += [