NAT#
Security → NAT shows the router's nat subtree as three tables — port forwards
(destination NAT), 1:1 mappings (nat static) and source NAT — each row carrying the
packet and byte counts the router reports for it. Clicking a row opens an editor for that
rule; the two buttons in the header open the creation editors. Everything except the 1:1
editor stages set and delete commands for the Commit Bar; the 1:1 editor is switched
off on this platform build, for a reason the page states on itself and this section
explains in full.
Where the page gets its data#
| What | Call | Refresh |
|---|---|---|
| All three tables | GET /api/nat/rules — the whole nat subtree | on load, and after every commit |
| Counters | GET /api/nat/stats — show nat destination statistics and show nat source statistics | every 5 seconds |
| The CLI view | GET /api/config/commands?path=["nat"] | after every commit |
| The uplink model | GET /api/wan — used by the hairpin and 1:1 editors for the WAN address and the LAN side | on load; failures are tolerated |
| The forward chain | GET /api/firewall/rules — so the accept rule the forward editor offers cannot collide with an existing rule | on load |
The nat subtree is IPv4. Nothing on this page reads or writes an IPv6 NAT tree —
agent/main.go handleNatRules.
The three tables#
Port forwards (DNAT)#
Rules under nat destination rule <n>. Columns: #, Description, In (the
inbound interface, or any), Port (the matched destination port, or any),
Proto, Translates to (the translation address, with :port appended when the rule
translates the port too), Packets, Bytes.
The empty state gives you the four commands a minimal forward consists of, and says the sentence that matters most on this page: NAT alone does not permit the flow. See port forwards.
1:1 NAT (static)#
Rules under nat static rule <n>. Columns: Rule, Description, Inbound,
Public address, Inside address.
No counters: show nat … statistics is read for the destination and source tables only.
This table is read-only on this build; see 1:1 NAT for why, and for the
console commands the panel hands you instead.
Source NAT#
Rules under nat source rule <n>. Columns: #, Description, Out (the outbound
interface, or any), Source (the matched source address, or any), Translation
(the translation address, or the word masquerade when the rule has none), Packets,
Bytes. See source NAT.
How a row is read#
Each table row is built from one configuration object, with a few shapes normalised:
nat staticnames its inbound interface as a plain leaf —inbound-interface eth1— wherenat destinationusesinbound-interface name eth1. The page reads both.- The matched side depends on the direction: destination and static rules match on
destination address/destination port, source rules onsource address/source port. The editor relabels its fields to match. protocoldefaults toallin the table when the rule does not set one.- A source rule with no
translation addressis displayed asmasquerade.
Counters#
show nat destination statistics and show nat source statistics are parsed into rows
keyed by rule number, and joined onto the table by direction and number
(agent/opmode.go handleNatStats). Unlike the firewall page,
a failed read here is not distinguished from zero: both show 0. If a rule you expect to
be busy reads zero, check the counters on the router before concluding the rule is not
matching.
The rule editor#
Clicking a destination or source row opens a panel with:
- Live counters — packets and bytes for the rule.
- Edit — inbound or outbound interface, protocol, matched address, matched port, translation address, translation port, Log matches, Disabled, description.
- This stages — the commands your edits have produced.
- Config object — the rule as the router returned it, as JSON.
The footer has Stage n changes and Delete rule. The commands are built the same
way the firewall editor builds them: a changed field becomes a set, a cleared field
becomes a delete, an unchanged field produces nothing.
Everything the add editor can set, this panel can change. That is a deliberate repair: it
used to offer two fields — translation address and description — against an add editor with
ten, so a forward this product created could not be re-pointed at a different port from the
UI that made it (ui/src/pages/Nat.tsx).
The CLI view#
The CLI toggle replaces the three tables with the nat subtree rendered as set
commands by the router itself, through GET /api/config/commands. It is the fastest way to
copy a working configuration to another router, and the fastest way to see rules the tables
have normalised.
What you need to change anything#
+ Add forward is gated on the operator role. + Add 1:1 is gated on the operator role and on the static-NAT block, so it is disabled for everyone on this build, with the reason as its tooltip. Staging is refused server-side without the operator role and a usable licence.
Every path this page stages begins nat or, for the accept rule the forward editor offers,
firewall — both of which the Commit Bar treats as changes that can cut you off, so it
recommends commit-confirm for the batch
(ui/src/lib/format.ts isDangerousPath).
See also#
- Port forwards — the add-forward editor, the accept rule and hairpin.
- Source NAT — masquerade, fixed translation, and per-uplink rules.
- 1:1 NAT — the table that reads and the editor that is off.
- Firewall — rules — the other half of every published service.
- Worked rulesets — publishing a service, end to end.
- Publish a service — the guide.
- The HTTP API — the routes this page calls.
Checked against#
ui/src/pages/Nat.tsx,
ui/src/lib/api.ts,
ui/src/lib/format.ts,
agent/main.go,
agent/opmode.go,
agent/license.go.