AuthHound

authhound-probe: quickstart

Install the probe, tell your RADIUS server it exists, and run a real authentication from inside your network — in about a minute. Everything you enter stays on the host you run it on.

1. Install

A single static binary — no runtime, no dependencies. Pick your platform; every command downloads the latest signed release.

# download + unpack the latest release (amd64; use linux_arm64 on a Pi)
curl -sSL https://github.com/authhound/probe/releases/latest/download/authhound-probe_linux_amd64.tar.gz | tar xz
./authhound-probe version
# PowerShell — downloads the latest release zip and unpacks it here
Invoke-WebRequest -Uri https://github.com/authhound/probe/releases/latest/download/authhound-probe_windows_amd64.zip -OutFile authhound-probe.zip
Expand-Archive -Path authhound-probe.zip -DestinationPath authhound-probe -Force
.\authhound-probe\authhound-probe.exe version
# Apple Silicon (use darwin_amd64 on an Intel Mac)
curl -sSL https://github.com/authhound/probe/releases/latest/download/authhound-probe_darwin_arm64.tar.gz | tar xz
./authhound-probe version
# multi-arch distroless image — nothing to install on the host
docker run --rm ghcr.io/authhound/probe version
# build from source with a Go toolchain
go install github.com/authhound/probe/cmd/authhound-probe@latest
authhound-probe version

Every release is checksummed and keyless-signed with Sigstore cosign. Copy-paste verification steps are in the README — worth doing before you run it on a shared box.

2. Register the probe on your server (one time)

The probe acts as a NAS (a switch or access point), so your RADIUS server must know it as a client — otherwise the server silently drops its requests and every check times out. Add the probe's IP and a dedicated shared secret:

FreeRADIUS — add to clients.conf, then restart:

client authhound-probe {
    ipaddr = 10.20.0.50      # the probe's IP
    secret = <shared secret>
}

Windows NPS — PowerShell (elevated), or NPS console → RADIUS Clients → New:

New-NpsRadiusClient -Name "authhound-probe" -Address "10.20.0.50" -SharedSecret "<shared secret>"

Cloud / hosted RADIUS — register the probe's IP and secret in the vendor's admin UI, per their docs.

💡 If NAT sits between the probe and the server, register the post-NAT source IP — the address the server actually sees. Use a least-privilege test account, never a real admin login. If you skip this step, the probe detects the first-run timeout and prints this exact snippet with your detected source IP already filled in. More in troubleshooting.

3. Run your first test

Keep secrets and passwords off the command line, where they leak into shell history and ps. The probe reads the shared secret from AUTHHOUND_RADIUS_SECRET (or --secret-file), and prompts for any auth password with no echo:

# keep the shared secret off the command line — out of shell history and `ps`
export AUTHHOUND_RADIUS_SECRET='the-secret-you-registered'

# no credentials needed: reachability, shared-secret, cert and BlastRADIUS checks
authhound-probe radius test --server radius.corp.com

# add a real PEAP-MSCHAPv2 login — you're prompted for the password (no echo)
authhound-probe radius test --server radius.corp.com --peap alice

# machine-readable output for a script or RMM
authhound-probe radius test --server radius.corp.com --json

Add --pap alice (PAP), --ttls alice (EAP-TTLS), or --client-cert/--client-key (EAP-TLS) for other methods. Every credential form has a safe variant — see the flag reference.

4. What the output means

Each check prints one line with a verdict, then a plain-English reason and — when something's wrong — the next thing to check. Three verdicts:

  • PASS The check succeeded and proved something concrete — e.g. the reply signature verified, so the shared secret is definitely correct.
  • WARN Working now, but worth attention — a certificate expiring soon, a missing Message-Authenticator (BlastRADIUS), or server-name validation skipped. Not a failure unless you pass --strict.
  • FAIL The check failed — auth was rejected, an assertion like --expect-vlan didn't hold, or the server never answered.

The process exit code makes this scriptable — the contract is stable, so RMM tools and Task Scheduler can depend on it:

Exit codeMeaning
0All checks passed (warnings allowed unless --strict).
1A check FAILED — or, under --strict, a WARN (e.g. a cert expiring soon).
2Usage error (bad flags or missing --server).

With --json the same result is machine-readable: .summary.fail / .summary.warn counts and per-check .results[].status. The versioned schema is documented in the repo.

Next

  • Flag reference

    Every flag for radius test and radsec test, generated from the binary.

  • Troubleshooting the probe

    First-run timeouts, the NAT source-IP trap, --bind on multi-homed hosts, EAP-TLS cert errors.

  • RADIUS attribute & VSA reference

    What the attributes in an Access-Accept actually carry — VLAN, Filter-Id, and the vendor AV-pairs.

  • vs eapol_test and radtest

    A factual comparison — including a working eapol_test PEAP config and when the classics are still the better tool.

  • Log analyzer

    Already staring at a radiusd -X or NPS log? Paste it in — it runs in your browser, nothing uploaded.

Running the probe by hand answers "is it working right now?". AuthHound is building monitoring that runs these same checks on a schedule from every site and alerts you when one drifts — early access:

No spam, no sharing — one email when it's ready, and you can reply to be removed anytime.