2026-06-19
Every sysadmin has done the dance: an email isn't arriving, so you fire up openssl s_client -starttls smtp -connect mx:587, type EHLO me, copy-paste a base64'd password, hand-craft MAIL FROM:, miss a CRLF, get disconnected, start over. swaks — the Swiss Army Knife for SMTP, a single Perl script by John Jetmore — has been doing all of that for you since 2003. It's packaged in Debian, Ubuntu, Fedora, Homebrew, and the BSDs.
The simplest invocation is just a sanity check that a server accepts mail for an address:
swaks --to [email protected] --server mx1.example.com
You get a full, color-coded transcript of every SMTP verb, the server's banner, the EHLO capabilities, and the final 250 — or whatever error actually killed it. No more squinting at /var/log/mail.log hoping the MTA wrote enough.
Where it really earns its keep is the awful matrix of TLS + AUTH + submission ports. Test a Gmail-style submission with STARTTLS and LOGIN auth in one line:
swaks --to [email protected] --from [email protected] \
--server smtp.example.com:587 \
--tls --auth LOGIN \
--auth-user [email protected] \
--auth-password 'app-specific-password'
Need implicit TLS on 465 instead? Swap --tls for --tlsc. Need to force a specific auth mech? --auth CRAM-MD5. Need a client cert? --tls-cert / --tls-key. Need to pin a CA? --tls-ca-path.
The killer flag nobody mentions is --quit-after. You can probe whether a server would accept a recipient without actually delivering anything — perfect for testing relay/anti-spoof rules without spamming real people:
# Will mx.example.com relay for this address? Don't actually send.
swaks --to [email protected] --server mx.example.com --quit-after RCPT
Valid checkpoints are CONNECT, BANNER, FIRST-HELO, TLS, AUTH, MAIL, RCPT, DATA, DOT, and QUIT. Want to verify your STARTTLS cert chain without ever authenticating? --quit-after TLS.
Attachments work the way you'd hope a 2003 Perl script wouldn't:
swaks --to [email protected] --server mx --attach @report.pdf \
--header "Subject: nightly run" --body "see attached"
The @ means "file"; without it, the argument is treated as literal content. Same trick works for --body @message.txt and --data @full-rfc822.eml if you want to inject a pre-built message verbatim, headers and all — invaluable for reproducing a customer's bounced message.
A few one-liners that pay rent in my ~/.bash_history:
# Show literally every byte on the wire, including TLS handshake summary
swaks --to x@y --server mx -tls --show-raw-text
# Test DSN (delivery status notification) requests
swaks --to x@y --server mx --dsn SUCCESS,FAILURE --dsn-ret HDRS
# Pipeline 5 messages in one connection to test rate limits
swaks --to x@y --server mx --pipeline -n 5
# Use it as a smoke test from cron, exit nonzero on any SMTP error
swaks --to monitor@y --server mx --silent 2 || page-oncall
Compare to the alternatives: mail(1) hands off to the local MTA and you've lost visibility; sendmail -bs only talks to localhost; telnet can't do TLS; openssl s_client can do TLS but you're typing protocol by hand. swaks is the one tool that gives you scriptable, repeatable, full-fidelity SMTP — exactly the conversation a real client would have, with a transcript you can paste into a bug report.
swaks turns any TLS/auth/DSN/attachment combination into a one-line, scriptable, fully-logged transaction.
