Skip to content

RTFM · Healthchecks

lb.saphira.radius: ask the server if it is serving

RADIUS has a health question built into the protocol: Status-Server. The check sends it, verifies the answer, and never fakes a user login; the credential-free way to keep Wi-Fi and VPN authentication pools honest.

Saphira Linux dragon mascot

What it proves

A RADIUS round-trip using the Status-Server packet (RFC 5997): the check announces itself as a status probe (Service-Type Status-Server, Message-Authenticator computed), and the server must answer Access-Accept or Access-Challenge. Access-Reject and silence are unhealthy. No user authentication happens; the shared secret authenticates the probe, not a person.

How it works

The probe engine builds the packet: random authenticator, Status-Server attribute, HMAC-MD5 Message-Authenticator under the shared secret. The secret arrives only via LB_SAPHIRA_RADIUS_SECRET (env or conf file) and is never echoed; a check without a secret exits 2 rather than guessing.

Sites where the NAS equipment cannot do Status-Server can opt into LB_SAPHIRA_RADIUS_PAP=1: a PAP Access-Request with configured credentials instead. That is a real login attempt; use a dedicated health-check user, and expect the server's logs to show it.

Configuration

Knobs
VariableDefaultMeaning
LB_SAPHIRA_RADIUS_SECRET(required)Shared secret: env/conf only, never echoed; missing → exit 2
LB_SAPHIRA_RADIUS_PAP01 = PAP Access-Request instead of Status-Server
LB_SAPHIRA_RADIUS_USER-PAP username (with PAP=1)
LB_SAPHIRA_RADIUS_PASSWORD-PAP password: env only
LB_SAPHIRA_TIMEOUT3Round-trip deadline
(target port)$4, else 1812Accounting ports (1813) need a different probe shape

Wiring it up

ldirectord
# ldirectord.cf - WLAN AAA pool
virtual = 203.0.113.10:1812
    protocol = udp
    scheduler = sh
    real = 192.168.20.81:1812 gate 1
    real = 192.168.20.82:1812 gate 1
    checktype = external
    checkcommand = "/var/lib/lb/saphira/lb.saphira.radius"
The secret lives in the conf layer
# /etc/saphira/lb-healthchecks.d/radius.conf  (chmod 600, admin-owned)
LB_SAPHIRA_RADIUS_SECRET=••••••••••••

Run it by hand

Manual run
LB_SAPHIRA_RADIUS_SECRET=$(cat /etc/radius/hc-secret) \
  /var/lib/lb/saphira/lb.saphira.radius aaa-pool 1812 192.168.20.81 1812
echo $?
# 0 = Access-Accept or Access-Challenge
# 1 = Reject, timeout, or malformed reply
# 2 = no secret configured

Failure modes

  • Access-Reject: the server is alive but refuses the probe: usually a missing client stanza for the director's address
  • Timeout: UDP loss or a wedged worker; verify with ipvsadm that traffic is reaching the server at all
  • exit 2: the secret never arrived: check the conf file path and permissions

Did we miss something?

If this page left something unanswered, found an error, or there is another subject you would like documented, tell us. Saphira’s documentation grows from real problems people need to solve.

Send feedback or request a new section →

Prefer not to do it yourself?

Everything needed to do the work yourself is documented here and remains free; we charge for human time, not for withholding knowledge. Sometimes the missing resource is simply time. The same people who build Saphira can provide paid professional help with implementation, migration, troubleshooting and administration.

Ask about professional support →