Skip to content

RTFM · Healthchecks

lb.saphira.tls: will the handshake complete?

No HTTP, no body; just the TLS conversation itself: can this server still complete a handshake, and is its certificate about to expire? The check that catches the expired-certificate outage before the customers do.

Saphira Linux dragon mascot

What it proves

A full TLS handshake against real:$4 with a certificate actually served. Optionally, a certificate-expiry floor: LB_SAPHIRA_TLS_MIN_DAYS fails the check when the served certificate expires within N days; turning the classic 3 a.m. certificate outage into a balancer-visible degradation while there is still time to renew.

How it works

openssl s_client performs the handshake (optionally asserting an SNI hostname via LB_SAPHIRA_SNI); the check requires a certificate in the output, and when the day-floor is set, parses the not-after date and compares it to now. The whole openssl run is bounded by the shared timeout.

Configuration

Knobs
VariableDefaultMeaning
LB_SAPHIRA_SNI-SNI hostname to assert in the ClientHello
LB_SAPHIRA_TLS_MIN_DAYS-Fail when the certificate expires within N days
LB_SAPHIRA_TIMEOUT3Handshake deadline

Wiring it up

ldirectord
# /etc/ha.d/ldirectord.cf
virtual = 203.0.113.10:443
    protocol = tcp
    scheduler = wlc
    real = 192.168.20.11:443 gate 1
    checktype = external
    checkcommand = "/var/lib/lb/saphira/lb.saphira.tls"
HAProxy
# haproxy.cfg
global
    external-check

backend app_pool
    mode tcp
    option external-check
    external-check command "/var/lib/lb/saphira/lb.saphira.tls"
    server app1 192.168.20.11:443 check inter 5s fall 3 rise 2
Expiry floor
# Two-week warning on a certificate that should live longer
LB_SAPHIRA_TLS_MIN_DAYS=14 /var/lib/lb/saphira/lb.saphira.tls edge 443 192.168.20.11 443

Run it by hand

Manual run
/var/lib/lb/saphira/lb.saphira.tls 21 443 192.168.20.11 443
echo $?
# 0 = handshake completed, certificate served
# 1 = handshake failed, no certificate, or expiry floor breached

Failure modes

  • No certificate in the reply; the port answered but spoke something else (plain HTTP on a TLS port, a proxy with a dead upstream)
  • Handshake alert: protocol/cipher mismatch or certificate rejected at the TLS layer
  • Expiry floor: the service is technically up and about to break: the check votes unhealthy so traffic moves while renewal happens

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 →