NFtoggle
Every open port is an attack surface. Scanners map your network within minutes of a new IP appearing online. Most firewalls accept or reject — nftoggle does neither: ports stay completely invisible until a connection is authorized, then open for that IP only. No banner, no RST, no handshake for unauthorized sources. The port simply does not exist.
How it works
nftoggle is a Linux daemon written in Rust. It hooks into the kernel via nftables NFQUEUE, intercepting the very first packet before the TCP stack processes it:
- A client attempts to connect to a monitored port.
- An
nftablesrule redirects the initial packet to an NFQUEUE. - nftoggle intercepts it, extracts the source IP, and evaluates the configured rules.
- If authorized: it optionally sends a Wake-on-LAN frame to boot a sleeping machine, waits for it to come up, then issues an
ACCEPTverdict — the connection continues transparently. - If denied: the packet is silently
DROPped. The client sees nothing.
After the first authorized packet, the source IP is added to a temporary nftables set with a timeout, so subsequent packets in the session are handled at kernel line rate without going through user space again.
Features
- Port stealth — monitored ports produce no response to unauthorized scanners; they are invisible.
- Parental controls — restrict access to specific ports by time window (e.g. 14:00–18:00) or daily time allowance (e.g. 2 h/day).
- Wake-on-LAN — automatically power on a sleeping machine when a connection arrives; hold the packet until the machine is ready.
- Geofencing — optionally reject connections from specific countries using a local GeoIP database.
- Event hooks — run shell scripts or POST a JSON webhook on
session_started,session_ended, andaccess_deniedevents. - Activity statistics — log sessions and blocked attempts to a lightweight SQLite database.
- Embedded-friendly — Rust binary, minimal dependencies, runs on OpenWrt, Raspberry Pi, NAS.
Use cases
Parents: game ports on a schedule. Blocking a console’s full internet access breaks firmware updates and cloud saves. nftoggle targets only the game session ports (PlayStation Network, Nintendo Online) on a schedule — the console stays online for everything else, but can’t start a new session after 9 PM.
Homelab: on-demand game or media server. Your Minecraft server or Plex instance runs on a NAS that sleeps to save power. The moment a friend tries to connect, nftoggle intercepts the packet, sends a Magic Packet to wake the machine, and forwards the connection once it is ready. No manual intervention, no idle power draw.
Sysadmin: invisible SSH. Production SSH and admin APIs are permanently exposed to brute-force and vulnerability scanners. With nftoggle, the port is in full stealth mode. Authorized IPs (e.g. a corporate VPN range) get through; everything else gets silence — no banner to fingerprint, no surface to probe.
IoT containment. IP cameras and smart devices frequently probe other machines on the network. A compromised device cannot even attempt a handshake against your admin interfaces (Home Assistant, Zigbee2MQTT) — the packet is dropped before TCP state is created.
Components
nftoggle is the core daemon. It manages the NFQUEUE listener, evaluates rules, triggers WoL, fires hooks, and exposes a Unix socket at /run/nftoggle/daemon.sock for clients.
nftoggle-tui (planned) — terminal UI client that connects to the daemon socket and displays live sessions, statistics, and blocked attempts.
nftoggle-webui (planned) — local web UI server exposing the same live data in a browser.
Comparison
| Plain nftables | Port knocking (knockd) | fail2ban | nftoggle | |
|---|---|---|---|---|
| Ports invisible to scanners | No (RST/timeout) | Partial | No | Yes |
| Time-based rules | Manual scripting | No | No | Yes |
| Wake-on-LAN on first packet | No | No | No | Yes |
| Parental controls | No | No | No | Yes |
| Event hooks / webhooks | No | No | Partial | Yes |
| GeoIP filtering | No | No | Via plugin | Yes |
| Client modification needed | No | Yes (knock sequence) | No | No |
| Embedded / OpenWrt | Builtin | Difficult | No | Yes |
Origin
It started as a joke: someone mentioned “nftables toggle” in passing and the name nftoggle stuck. From there, looking for ideas that could actually fit the name led to this — a tool that genuinely toggles ports on and off at the kernel level, on demand.
Source code: codeberg.org/slundi/nftoggle