A default-drop ruleset that admits what you meant#
You will end up knowing exactly what your router's firewall does, on both address families, and able to add to it without cutting yourself off. Most Wheelhouse routers already have a default-drop ruleset — the installer writes one — so this guide is as much about reading what is there as about writing something new.
Before you start#
- The operator role and a licence, or console access.
- Know what you have:
bash
show configuration commands | match firewallAn empty answer on a box with a WAN is an emergency, not a preference.
What the installer wrote#
The firewall is written whenever the installer's Firewall box is left checked and there is a WAN. It does not need a LAN — a router with a WAN and no LAN is exactly the machine that must not accept what arrives on it.
set firewall global-options state-policy established action accept
set firewall global-options state-policy related action accept
set firewall global-options state-policy invalid action drop
set firewall ipv4 input filter default-action drop
set firewall ipv4 input filter rule 10 accept inbound-interface <LAN> (if there is a LAN)
set firewall ipv4 input filter rule 20 accept inbound-interface lo
set firewall ipv4 input filter rule 30 accept protocol icmp
set firewall ipv4 input filter rule 40 accept udp/68 on <WAN> (if the WAN is DHCP)
set firewall ipv4 input filter rule 50 accept source <management source> (if you gave one)
set firewall ipv4 forward filter default-action drop
set firewall ipv4 forward filter rule 10 accept inbound-interface <LAN> (if there is a LAN)
set firewall ipv6 input filter default-action drop
set firewall ipv6 input filter rule 10 accept inbound-interface <LAN> (if there is a LAN)
set firewall ipv6 input filter rule 20 accept inbound-interface lo
set firewall ipv6 input filter rule 30 accept protocol icmpv6
set firewall ipv6 input filter rule 40 accept udp/546 on <WAN>
set firewall ipv6 input filter rule 50 accept source <management source> (if you gave one)
set firewall ipv6 forward filter default-action drop
set firewall ipv6 forward filter rule 10 accept inbound-interface <LAN> (if there is a LAN)
set firewall ipv6 forward filter rule 20 accept protocol icmpv6Four things about it are decisions, and they are the ones to understand before you change anything.
1. Both families are filtered. A box filtered on one family and open on the other is
not filtered, and a provider can bring IPv6 up without being asked. If the image turns out
to have no firewall ipv6 node the installer says so at the end rather than committing a
v4-only ruleset silently — check for that message.
2. ICMP is accepted from anywhere, WAN included, on both families. On IPv4 that is a choice you can narrow: a router that does not answer ping is hard to diagnose. On IPv6 it is not a choice — neighbour discovery and path MTU discovery are ICMPv6, and a router that drops them loses its own default route and then breaks every large packet it forwards.
3. The DHCP client is admitted explicitly — udp/68 on the WAN for IPv4, udp/546 for IPv6 — rather than left to depend on connection tracking, so a lease renewal or a delegated prefix cannot be dropped by the default-deny rule.
4. Nothing here opens 8443 from the WAN. With a LAN, the web UI is reachable from the LAN. Without one, it is reachable from the console and from the management prefix you named at install, and nowhere else.
The two chains, and which one you want#
| Chain | Holds traffic that is | Rules you add here |
|---|---|---|
input | Addressed to the router itself | Reaching the web UI, SSH, DNS, DHCP, NTP, a VPN listener |
forward | Passing through the router to something else | Letting a segment out, admitting a port forward, blocking one VLAN from another |
Getting these the wrong way round is the most common firewall mistake here, and its symptom is a rule with a hit counter stuck on zero.
There is also an output chain for traffic the router originates. The installer does not
write one, and most routers do not want one.
Step 1 — Add a rule#
Network → Firewall, choose the family and the chain, then + Add rule.
The editor writes only what you set, and clearing a field in the editor becomes a delete
rather than being silently left behind. That means the same panel creates and edits — a
rule you narrow later loses exactly the leaf you cleared.
set firewall ipv4 input filter rule 60 action accept
set firewall ipv4 input filter rule 60 description 'ssh from management'
set firewall ipv4 input filter rule 60 protocol tcp
set firewall ipv4 input filter rule 60 destination port 22
set firewall ipv4 input filter rule 60 source address 192.0.2.0/28set firewall ipv4 forward filter rule 30 action accept
set firewall ipv4 forward filter rule 30 description 'guest out'
set firewall ipv4 forward filter rule 30 inbound-interface name eth0.30
set firewall ipv4 forward filter rule 30 outbound-interface name eth1The fields the editor offers, and what each one becomes:
| Field | Command |
|---|---|
| Action | action accept / drop / reject / jump / return / continue |
| Protocol | protocol tcp / udp / tcp_udp / icmp (icmpv6 on the v6 side) |
| Inbound / outbound interface | inbound-interface name <if>, outbound-interface name <if> |
| Source or destination address | source address <cidr>, destination address <cidr> |
| …or a group | source group address-group <name> — see Use groups instead of literals |
| Source or destination port | source port <p>, destination port <p> |
| …or a port group | destination group port-group <name> |
| State | state new, state established, and so on |
| Log | log |
| Disable | disable — keeps the rule and stops it matching |
An address and a group on the same side are mutually exclusive: choosing a group deletes the literal, and the editor handles that for you.
Step 2 — Choose the number carefully#
Rules are evaluated in numeric order and the first match wins. Leave gaps: the installer uses 10, 20, 30, so 15 fits between two of them and 60 goes on the end. The Firewall page shows which numbers are taken.
Step 3 — Commit with a confirm window#
Check it worked#
Hit counters. The Firewall page joins live nftables
counters onto each rule, read from the router's own firewall statistics. A rule that
should be matching and is not is a rule with a zero counter, and that is your answer.
show firewall statisticsTest the thing itself, from the side it should work from and from the side it should not:
# should work, from the management prefix
nc -vz 192.0.2.1 22
# should not, from anywhere else
nc -vz 203.0.113.2 22Turn on logging while you are debugging — tick Log on the rule — and watch the Logs page. Turn it off afterwards; a logging rule on a busy chain fills the journal.
What is not here#
Undoing it#
delete firewall ipv4 input filter rule 60Or disable it first, which keeps the rule and its number while you find out whether you needed it:
set firewall ipv4 input filter rule 60 disableIf a commit has already locked you out, see Locked out of the
UI — the answer is the console and rollback 1.
See also#
- Publish a service — the forward-chain accept a port forward needs
- Use groups instead of literals
- Harden a router that faces the internet
- What the firewall checkbox writes
- Firewall — rules
Checked against docs/security.md ·
docs/install.md ·
ui/src/pages/Firewall.tsx ·
agent/main.go