swaks: The SMTP Swiss Army Knife That Replaced Three Hours of openssl s_client

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.

Key Takeaway: Stop hand-typing SMTP into openssl — swaks turns any TLS/auth/DSN/attachment combination into a one-line, scriptable, fully-logged transaction.

All newsletters