router.firewall.nat replaces the dnat/toPort/hairpin fields of the filter rules. Filter rules gain natOnly, and may use wan with log and rate limit in the web UI. The Firewall page edits the NAT table and can add the matching allow rule. Settings schema 1 (migrations/1.jq) converts old forwards. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AeFqV9dZrK6nipHkPfyM4F
22 lines
1.0 KiB
Plaintext
22 lines
1.0 KiB
Plaintext
# Port forwards move from `firewall.rules` (dnat, toPort, hairpin) to
|
|
# `firewall.nat`; the allow rule that went with them stays as a rule of its
|
|
# own, limited to translated connections (natOnly). The rest of a rule
|
|
# (rateLimit, log, sources) stays on the allow rule.
|
|
def natRow:
|
|
{type: "dnat", from: .from, to: .to, protocol: .protocol, ports: .ports, toAddress: .destination}
|
|
+ (if .toPort != null then {toPort: .toPort} else {} end)
|
|
+ (if ((.sources // []) | length) > 0 then {sources: .sources} else {} end)
|
|
+ (if .hairpin == true then {hairpin: true} else {} end);
|
|
|
|
def allowRule:
|
|
del(.dnat, .hairpin, .toPort)
|
|
+ {natOnly: true}
|
|
+ (if .toPort != null then {ports: [.toPort]} else {} end);
|
|
|
|
if ((.router.firewall.rules // []) | any(.dnat == true or .hairpin != null or .toPort != null)) then
|
|
.router.firewall.nat = ((.router.firewall.nat // []) + [.router.firewall.rules[] | select(.dnat == true) | natRow])
|
|
| .router.firewall.rules |= map(if .dnat == true then allowRule else del(.dnat, .hairpin, .toPort) end)
|
|
else
|
|
.
|
|
end
|