Development

This commit is contained in:
Matthew Grotke 2026-05-31 23:17:30 -04:00
parent 5575b06b64
commit 6cd41dff1a
4 changed files with 56 additions and 33 deletions

View file

@ -261,7 +261,11 @@
"input_type": "number", "input_type": "number",
"layout": "inline", "layout": "inline",
"value": "%DDNS_GEN_LOG_MAX_KB%", "value": "%DDNS_GEN_LOG_MAX_KB%",
"min": "64" "min": "64",
"hint": "Log will automatically be cleared when it reaches this size."
},
{
"type": "hr"
}, },
{ {
"type": "field", "type": "field",

View file

@ -143,29 +143,35 @@
"type": "field_row", "type": "field_row",
"cols": 3, "cols": 3,
"items": [ "items": [
{
"type": "field_row",
"cols": 2,
"items": [
{
"type": "field",
"label": "Dest Port Range",
"name": "dst_port_min",
"input_type": "number",
"min": 1,
"max": 65535,
"hint": "This exception only applies to traffic over this port range and protocol."
},
{
"type": "field",
"label": "",
"name": "dst_port_max",
"input_type": "number",
"min": 1,
"max": 65535
}
]
},
{ {
"type": "field", "type": "field",
"label": "Protocol", "label": "Protocol",
"name": "protocol", "name": "protocol",
"input_type": "select", "input_type": "select",
"options": "%PROTOCOL_OPTIONS%" "options": "%PROTOCOL_OPTIONS%"
},
{
"type": "field",
"label": "Port Min",
"name": "dst_port_min",
"input_type": "number",
"min": 1,
"max": 65535,
"hint": "This exception only applies to traffic over this port range and protocol."
},
{
"type": "field",
"label": "Port Max",
"name": "dst_port_max",
"input_type": "number",
"min": 1,
"max": 65535
} }
] ]
}, },

View file

@ -760,7 +760,7 @@ def collect_tokens():
'<th class="table-header">Applied</th>' '<th class="table-header">Applied</th>'
'<th class="table-header">Change</th>' '<th class="table-header">Change</th>'
'<th class="table-header">Fields</th>' '<th class="table-header">Fields</th>'
'<th class="table-header">Group</th>' '<th class="table-header">Change ID</th>'
'<th class="table-header">User</th>' '<th class="table-header">User</th>'
'</tr></thead>' '</tr></thead>'
f'<tbody>{hist_rows}</tbody>' f'<tbody>{hist_rows}</tbody>'

View file

@ -67,10 +67,9 @@ Validation:
must be valid. Protocol must be tcp, udp, or both. must be valid. Protocol must be tcp, udp, or both.
Generates DNAT rules only; no forward chain rules needed Generates DNAT rules only; no forward chain rules needed
since redirect_to is always a local IP (INPUT handles it). since redirect_to is always a local IP (INPUT handles it).
inter_vlan_exceptions -- src_ip_or_subnet and dst_ip_or_subnet must be valid IPv4 addresses declared in the vlans array. inter_vlan_exceptions -- src_ip_or_subnet and dst_ip_or_subnet may be a single IPv4 address
inter_vlan_exceptions -- src_ip_or_subnet and dst_ip_or_subnet must be valid IPv4 addresses or a CIDR network. dst_port_min/dst_port_max are optional (1-65535).
or networks. dst_port must be valid (1-65535). Protocol Protocol must be tcp, udp, or both.
must be tcp, udp, or both.
Usage: Usage:
sudo python3 core.py --apply Apply config fast: restart running services only sudo python3 core.py --apply Apply config fast: restart running services only
@ -1559,15 +1558,22 @@ def build_nft_config(data, dry_run=False):
line(" # -- Inter-VLAN exceptions ------------------------------------------") line(" # -- Inter-VLAN exceptions ------------------------------------------")
line() line()
for r in all_except: for r in all_except:
src = r["src_ip_or_subnet"] src = r["src_ip_or_subnet"]
dst = r.get("dst_ip_or_subnet") or r.get("dst_ip", "") dst = r.get("dst_ip_or_subnet") or r.get("dst_ip", "")
port = r.get("dst_port") min_p = r.get("dst_port_min") or r.get("dst_port")
max_p = r.get("dst_port_max")
if min_p and max_p and str(min_p) != str(max_p):
port_spec = f"{min_p}-{max_p}"
elif min_p:
port_spec = str(min_p)
else:
port_spec = None
for proto, _, suffix in expand_protocols(r): for proto, _, suffix in expand_protocols(r):
line(f" # {r['description']}{suffix}") line(f" # {r['description']}{suffix}")
if port is not None: if port_spec is not None:
line(f" ip saddr {src} ip daddr {dst} {proto} dport {port} ct state new accept") line(f" ip saddr {src} ip daddr {dst} {proto} dport {port_spec} ct state new accept")
else: else:
line(f" ip saddr {src} ip daddr {dst} ct state new accept") line(f" ip saddr {src} ip daddr {dst} {proto} ct state new accept")
line() line()
if all_fwd: if all_fwd:
@ -1731,10 +1737,17 @@ def apply_nftables(data, dry_run=False):
print() print()
print("Active inter-VLAN exceptions:") print("Active inter-VLAN exceptions:")
for r in active_except: for r in active_except:
src = r["src_ip_or_subnet"] src = r["src_ip_or_subnet"]
dst = r.get("dst_ip_or_subnet") or r.get("dst_ip", "") dst = r.get("dst_ip_or_subnet") or r.get("dst_ip", "")
port = r.get("dst_port") min_p = r.get("dst_port_min") or r.get("dst_port")
dst_str = f"{dst}:{port}" if port is not None else dst max_p = r.get("dst_port_max")
if min_p and max_p and str(min_p) != str(max_p):
port_str = f":{min_p}-{max_p}"
elif min_p:
port_str = f":{min_p}"
else:
port_str = ""
dst_str = f"{dst}{port_str}"
print(f" [{r['protocol'].upper():<4}] {src} -> {dst_str} ({r['description']})") print(f" [{r['protocol'].upper():<4}] {src} -> {dst_str} ({r['description']})")
def show_rules(): def show_rules():