snortal
Detects captive portal login page URLs on a Linux network.
When connecting to a WiFi network with a captive portal, the browser redirect often fails to appear on Linux. This tool inspects the network using several strategies and prints a ranked list of URLs likely to be the portal login page.
Usage
# Detect captive portal URLs on the current network
snortal
# Show verbose output (includes SSID, detectors with no results)
snortal --verbose
# Output as JSON
snortal --json
# Install optional system dependencies ahead of time
snortal install-deps
Overrides
The built-in defaults for each detector can be overridden via flags. When an override is supplied it replaces the defaults entirely; omit it to use the built-in list.
HTTP probe endpoints (-e / --probe-endpoint)
Replace the 6 built-in connectivity-check URLs with your own:
snortal -e http://captive.apple.com/ -e http://connectivity-check.ubuntu.com./
Built-in defaults:
http://connectivity-check.ubuntu.com./http://captive.apple.com/http://www.gstatic.com/generate_204http://detectportal.firefox.com/success.txthttp://nmcheck.gnome.org/check_network_status.txthttp://network-test.debian.org/nm
DHCP lease files (-d / --dhcp-file)
Check specific lease files instead of the built-in paths:
snortal -d /var/lib/dhcp/dhclient.leases -d /custom/path/leases
Built-in defaults (tried in order):
/var/lib/dhcp/dhclient.leases(Debian/Ubuntu)/var/lib/dhclient/dhclient.leases(RHEL/Fedora/CentOS)/var/lib/dhclient/dhclient6.leases/var/lib/NetworkManager/dhclient.conf
Gateway IP (-g / --gateway-ip)
Skip /proc/net/route auto-detection and probe a specific gateway directly:
snortal --gateway-ip 192.168.0.1
Useful when the default route lookup fails or you know the portal is hosted on a non-default-gateway IP.
Detection strategies
All detectors run concurrently and fail gracefully if the required file or binary is absent — the tool is fully usable even before running install-deps.
| Confidence | Strategy | Requires |
|---|---|---|
| 95 | DHCP option 114 — router explicitly advertised the portal URI | nothing |
| 90 | NetworkManager device file — NM parsed DHCP and stored the URI | nothing |
| 85 | HTTP redirect probe — 6 known connectivity-check endpoints redirected to portal | network |
| 70 | NM connectivity conf — reads the configured check URI | nothing |
| 60 | Gateway HTTP probe — decodes /proc/net/route, probes the default gateway |
network |
| — | nmcli status — confirms CONNECTIVITY=portal but provides no URL |
nmcli |
| — | WPA supplicant — SSID/state context printed in --verbose mode |
wpa_cli |
HTTP probes use redirect detection (reqwest with Policy::none()): a 3xx response means the portal intercepted the request and its Location header is the login page URL.
Install dependencies
The tool works without any additional packages. Two optional system binaries add extra detection context:
nmcli— reportsCONNECTIVITY=portalstatus (from NetworkManager)wpa_cli— shows SSID and connection state in--verbosemode
To install them:
snortal install-deps
This detects your package manager (apt, dnf, pacman, zypper, apk) and runs the appropriate install command with sudo. Missing binaries are skipped.
Install
AUR (Arch Linux)
paru -S snortal-bin
crates.io
cargo install snortal
Binary download
Pre-built binaries for Linux (x86_64, aarch64, armv7, i686, musl, MIPS, RISC-V) and macOS are on the releases page.
Building from source
cargo build --release
cargo install --path .
No runtime dependencies beyond libc — reqwest with rustls-tls is statically compiled in.
Example output
On a network with a captive portal:
Captive portal URLs detected:
────────────────────────────────────────────────────────────
95 http://192.168.1.1/portal [dhcp-lease]
85 http://192.168.1.1/login.html [http-probe: connectivity-check.ubuntu.com]
85 http://192.168.1.1/login.html [http-probe: captive.apple.com]
60 http://192.168.1.1/ [gateway-probe: 192.168.1.1]
────────────────────────────────────────────────────────────
Status: nmcli reports CONNECTIVITY=portal (captive portal confirmed)
On a normal connected network:
No captive portal URLs detected.