Allow more than 4 IPs on your ASUS router's admin access-restriction allowlist (Web UI + SSH source filter) on Asuswrt-Merlin — past the GUI's JavaScript-only 4-entry cap. Additive and lock-out-safe. Developed on the RT-BE92U.
ASUS routers have an admin access restriction feature (Administration → System → Enable access restriction): a source-IP allowlist that says "only these IPs may reach the router's Web UI and SSH." It's a great hardening step — but the GUI's add-a-row form stops you at 4 entries. If you run more than a handful of trusted machines (a couple of workstations, a phone, a jump host, a VPN endpoint…), four isn't enough, and the official answer tends to be "you shouldn't need more than four."
The 4-entry limit is enforced only by the GUI's JavaScript. The add-a-row form caps itself at 4 — but nothing underneath does:
- the nvram list (
restrict_rulelist) stores as many entries as you give it; - the GUI displays more than 4 when they're present;
- the firmware's iptables backend (
write_access_restriction()inrc/firewall.c, which builds theACCESS_RESTRICTIONchain) has no cap — it iterates the whole list.
Verified live on an RT-BE92U (Merlin 3006.102.x) by injecting a 5th entry into nvram: it both enforced and showed up in the GUI. And the old "nvram is too small" rationale doesn't apply — the whole list is ~120 bytes against tens of KB free.
So there's nothing to hack or patch. This tool just writes the entries the GUI won't let you type, using the mechanism the firmware already honors.
A single busybox sh script (/jffs/scripts/accessctl) that manages the
extra admin-allowed IPs — the ones beyond the GUI's own list — from a small
config file, access-extra.conf (one <ip> <web|ssh|both> per line):
accessctl add 192.168.1.50 both # allow a host for Web UI + SSH
accessctl add 192.168.1.51 ssh # SSH only
accessctl del 192.168.1.50 # remove (config-managed IPs only)
accessctl list # show the managed extras
accessctl status # config vs nvram vs the live iptables chain
accessctl apply # re-sync nvram + firewall from the config
add/del/apply write the config's IPs into nvram (restrict_rulelist, plus
http_clientlist for display parity) and run service restart_firewall, so the
firmware rebuilds the ACCESS_RESTRICTION chain with your extra IPs
included — GUI-visible and backend-enforced.
This is the whole point, so it's worth being explicit:
- Additive only. accessctl only ever touches the IPs in its own config. It never modifies or removes the GUI's own base entries.
delrefuses any IP it doesn't manage — so it can't remove the base entry that is your escape hatch.addrefuses any IP that's already a GUI-managed rule (present in nvram but not in accessctl's config) — it won't silently "capture" one of your base entries.- It never touches the master toggle (
enable_acc_restriction). Turning restriction on is the one action that can lock someone out (if their own IP isn't allowed yet), so that stays a deliberate GUI action. - Reboot-persistent for free: your entries live in nvram, which survives
reboots; the firmware rebuilds the chain from it at boot. A
firewall-starthook only kicks in for the rare case where a GUI "Apply" truncates your extra IPs back out of nvram — it detects the gap and restores them (recursion-guarded).
Golden rule: always keep at least one always-reachable admin IP in the GUI's own list as your escape hatch. accessctl never touches it.
If you ever do lock yourself out, from any still-allowed host (a VPN whose IP is allowed, a jump host, a LAN machine on the list):
nvram set enable_acc_restriction=0; nvram commit; service restart_firewallThat disables the whole restriction (any IP can reach admin again).
enable_acc_restriction is the flag the firewall backend actually reads.
- Asuswrt-Merlin — the tool uses Merlin's
user-script hooks (
/jffs/scripts/,firewall-start), which stock ASUSWRT doesn't offer. The access-restriction feature itself is stock ASUS; only the automation needs Merlin. - JFFS custom scripts enabled: Administration → System → Enable JFFS custom scripts and configs = Yes.
- SSH access to the router (Administration → System → Enable SSH = LAN only).
- "Enable access restriction" = Yes, with your own admin IP already in the GUI list, before you add extras — so you can't lock yourself out.
curl -fsSL https://raw.githubusercontent.com/deviationist/asuswrt-merlin-accessctl/main/setup.sh | shIt asks for your router's address and SSH username (ssh prompts for the password if you haven't set up keys), checks the router is ready, detects whether accessctl is already installed, and offers install / reinstall / uninstall / show-status. Safe to run any number of times.
Over an SSH session on the router itself:
curl -fsSL https://raw.githubusercontent.com/deviationist/asuswrt-merlin-accessctl/main/install.sh | shThe installer verifies JFFS scripts are enabled, fetches accessctl into
/jffs/scripts/, and appends a one-line hook to firewall-start (creating it
if absent) — idempotent, safe to re-run.
# from a clone of this repo, copy the tool to the router
scp scripts/accessctl <user>@<router>:/jffs/scripts/
ssh <user>@<router> 'chmod 755 /jffs/scripts/accessctl'
# add the firewall-start hook (restores your IPs if a GUI "Apply" truncates nvram)
ssh <user>@<router> '
FS=/jffs/scripts/firewall-start
[ -f "$FS" ] || printf "#!/bin/sh\n" > "$FS"
chmod 755 "$FS"
grep -q "accessctl firewall" "$FS" || echo "[ -x /jffs/scripts/accessctl ] && /jffs/scripts/accessctl firewall" >> "$FS"
'Then, on the router: make sure your own admin IP is in the GUI list and
Enable access restriction is on, and start adding extras with
accessctl add.
# on the router:
/jffs/scripts/accessctl uninstall # strips our IPs from nvram (keeps GUI base)
sh install.sh uninstall # ...and removes the tool + hook + config
# or from your computer:
curl -fsSL https://raw.githubusercontent.com/deviationist/asuswrt-merlin-accessctl/main/uninstall.sh | shUninstalling removes our extra IPs from nvram (your GUI base entries stay),
deletes the firewall-start hook line, the tool, and access-extra.conf.
Nothing else on your router is touched.
| Path | What it is |
|---|---|
/jffs/scripts/accessctl |
the tool (one busybox sh script) |
/jffs/scripts/access-extra.conf |
your list of extra IPs (<ip> <web|ssh|both>) |
one line in /jffs/scripts/firewall-start |
the truncation-recovery hook |
nvram restrict_rulelist / http_clientlist |
your extras, merged with the GUI's own entries |
Tip: keep access-extra.conf in your own version control off the router — JFFS
survives firmware updates but is wiped by a factory reset. After a reset, copy
accessctl + access-extra.conf back and run accessctl apply.
restrict_rulelist entries are <enable>ip>type, where type is a bitmask:
1 = Web UI, 2 = SSH, 3 = both (7 would add Telnet). The firmware's
write_access_restriction() reads this list, gated on enable_acc_restriction=1,
and builds the ACCESS_RESTRICTION iptables chain — no entry limit in the C
code. accessctl status shows all three layers side by side so you can see
config → nvram → live chain agree.
- Firmware-specific. The nvram var names and the
ACCESS_RESTRICTIONchain are how current AsusWRT/Merlin builds implement this; verified on the RT-BE92U. Other models/firmware very likely match (it's long-standing ASUS plumbing), but ifaccessctl statusshows your extras in nvram yet not in the chain, your build differs — please open an issue with model + firmware. http_clientlistis legacy. The current backend enforces fromrestrict_rulelist; we still writehttp_clientlistfor GUI/older-firmware display parity. Don't rely on it for enforcement.- Not affiliated with ASUS, Broadcom, or the Asuswrt-Merlin project. This just uses documented nvram + the firmware's own access-restriction backend.
If you're on an RT-BE92U (or another Broadcom ASUS unit) and a Wi-Fi client loses specific LAN hosts after a band roam, see asuswrt-merlin-flowcache-doctor.