RTFM · Healthchecks
lb.saphira.https: the HTTP transaction, over TLS
Everything the http check proves, plus the full TLS handshake to the real server: protocol negotiated, cipher agreed, certificate served. Built for backends that terminate TLS themselves; the pass-through architecture.
What it proves
A complete HTTPS transaction against real:$4: TCP connect, TLS handshake, HTTP request, HTTP response, status (or body) verified. On a pass-through design: HAProxy or LVS forwarding encrypted bytes, webDragon owning the certificate; this is the honest end-to-end check: it exercises exactly the path a real client exercises.
Certificate verification: off by default, and why
The check does not verify the certificate chain by default. That is deliberate: backends frequently terminate TLS with service certificates issued by an internal CA, or with a name that differs from the address we dial. The check's promise is the transaction, not public PKI validation. When the backend presents a certificate the check must validate, set the knob; the failure then becomes visible instead of silent.
| Variable | Default | Meaning |
|---|---|---|
| LB_SAPHIRA_TLS_VERIFY | 0 | 1 = enforce certificate verification (drop curl's -k) |
| LB_SAPHIRA_HTTP_PATH | / | Path to request |
| LB_SAPHIRA_HTTP_HOST | - | Host: header; also drives SNI via curl |
| LB_SAPHIRA_HTTP_OK | ^(2|3)[0-9][0-9]$ | Status-class regex (status mode) |
| LB_SAPHIRA_HTTP_EXPECT | - | Body regex: switches to body mode when set |
| LB_SAPHIRA_TIMEOUT | 3 | Whole-transaction --max-time |
Wiring it up
# /etc/ha.d/ldirectord.cf
virtual = [2001:db8:10::10]:443
protocol = tcp
scheduler = wlc
real = [2001:db8:20::11]:443 gate 1
checktype = external
checkcommand = "/var/lib/lb/saphira/lb.saphira.https"
# haproxy.cfg
global
external-check
backend app_pool
mode tcp
option external-check
external-check command "/var/lib/lb/saphira/lb.saphira.https"
server app1 192.168.20.30:443 check inter 5s fall 3 rise 2
Dual-stack works naturally: hand the check a bracketed IPv6 literal as $3 and curl talks to it directly.
Run it by hand
LB_SAPHIRA_HTTP_HOST=www.example.com \
/var/lib/lb/saphira/lb.saphira.https web-tls 443 192.168.20.30 443
echo $?
# 0 = TLS + HTTP transaction completed within the status class
# 1 = handshake failure, protocol failure, or status/body mismatch
Failure modes
- Handshake alert: expired/missing certificate, no common TLS version: the TLS layer broke, tcp alone would have passed
- Status outside the class: the app failed behind a healthy TLS layer
- With TLS_VERIFY=1: chain or hostname failures; the certificate story changed
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.