RTFM · Healthchecks
lb.saphira.smtp: will it take a letter?
The check says EHLO to your mail server and hangs up before sending anything: greeting verified, SMTP state machine entered, no message created. Exactly what a mail balancer needs and nothing that could pollute a queue.
What it proves
The front half of an SMTP session: the 220 greeting, a successful EHLO (which proves the server negotiated its capability list), and a clean QUIT. The check stops before DATA; no mail is created, no queue grows, no spam filter learns anything. Read-only by construction.
How it works
curl speaks the session: it connects, reads the greeting, sends EHLO with the healthcheck address, then closes. The HELO/EHLO name defaults to saphira.invalid; deliberately unroutable, so a server that somehow accepted a message for it would be advertising the failure, not hiding it.
Configuration
| Variable | Default | Meaning |
|---|---|---|
| LB_SAPHIRA_SMTP_EHLO | saphira.invalid | The EHLO identity presented |
| LB_SAPHIRA_TIMEOUT | 3 | Session deadline |
| (target port) | $4, else 25 | SMTP, submission (587) and TLS-wrapped (465) all work; the greeting is the test |
On 465 (implicit TLS) the TLS handshake is part of the same session; the check exercises it end to end.
Wiring it up
# ldirectord.cf - the MailDragon SMTP pool
virtual = 203.0.113.10:25
protocol = tcp
scheduler = lc
real = 192.168.20.25:25 gate 1
real = 192.168.20.26:25 gate 1
checktype = external
checkcommand = "/var/lib/lb/saphira/lb.saphira.smtp"
# haproxy.cfg
global
external-check
backend mail_smtp
mode tcp
option external-check
external-check command "/var/lib/lb/saphira/lb.saphira.smtp"
server maildragon 192.168.20.25:25 check inter 5s fall 3 rise 2
Run it by hand
/var/lib/lb/saphira/lb.saphira.smtp mail-pool 25 192.168.20.25 25
echo $?
# 0 = greeting + EHLO + QUIT all clean
# 1 = no greeting, EHLO rejected, or session stalled
Failure modes
- No 220 greeting: service dead or a firewall answered instead of the MTA
- EHLO rejected: greylisting misconfigurations and overloaded MTAs show up as 4xx chatter here
- Timeout: the MTA accepted the socket and then stopped speaking: the failure mode port checks love and this check catches
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.