Skip to content

RTFM · Healthchecks

lb.saphira.sni: does it serve THIS name?

One address, dozens of certificates: TLS routes by name. The SNI check announces which hostname it came to see, exactly as a browser does, and proves the server picked the right certificate for it.

Saphira Linux dragon mascot

What it proves

A TLS handshake in which the ClientHello asserts a specific hostname (Server Name Indication), and the server responds with a certificate. With LB_SAPHIRA_SNI_MATCH=1 the check goes further and verifies the served certificate's CN/SAN actually contains that hostname. This is the named capability for name-based TLS routing: a generic tls check can pass against the wrong vhost; this one cannot.

How it works

openssl s_client -servername <hostname> performs the handshake; the check requires a certificate. In match mode the certificate is decoded and the hostname must appear as the CN or a DNS SAN. Practical use: health-checking each tenant on a shared TLS edge, or a pass-through SNI proxy where each backend owns its certificate.

Configuration

Knobs
VariableDefaultMeaning
LB_SAPHIRA_SNI(required)The asserted hostname: without it the check exits 2
LB_SAPHIRA_SNI_MATCH01 = also verify CN/SAN contains the hostname
LB_SAPHIRA_TIMEOUT3Handshake deadline

Wiring it up

ldirectord
# ldirectord.cf - tenant routing on one edge address
virtual = 203.0.113.10:443
    protocol = tcp
    scheduler = sh
    real = 192.168.20.41:443 gate 1
    real = 192.168.20.42:443 gate 1
    checktype = external
    checkcommand = "/var/lib/lb/saphira/lb.saphira.sni"
Per-service tenant assertion
# /etc/saphira/lb-healthchecks.d/sni/tenant-a.conf
LB_SAPHIRA_SNI=tenant-a.example.com
LB_SAPHIRA_SNI_MATCH=1

Run it by hand

Manual run
LB_SAPHIRA_SNI=www.example.com LB_SAPHIRA_SNI_MATCH=1 \
  /var/lib/lb/saphira/lb.saphira.sni edge 443 192.168.20.11 443
echo $?
# 0 = a certificate was served for that SNI (and matches, in match mode)
# 1 = handshake failed or wrong certificate served
# 2 = LB_SAPHIRA_SNI not set

Failure modes

  • Handshake succeeded, wrong certificate; the classic name-based routing bug: the default vhost answered for a name it does not own
  • exit 2: no SNI configured: the check refuses to guess

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 →