Can testssl.sh Test Non-HTTP Services with STARTTLS? Protocol Support Guide
Yes, testssl.sh fully supports testing non-HTTP services like SMTP, FTP, and XMPP via STARTTLS, performing complete TLS handshakes after protocol-specific upgrades using the -t flag.
The drwetter/testssl.sh repository extends its HTTPS auditing capabilities to any service that upgrades plaintext connections to TLS through the STARTTLS mechanism. This allows security teams to evaluate cipher suites, certificate validity, and vulnerabilities across mail servers, file transfers, and databases using the same comprehensive test suite applied to web servers.
How STARTTLS Works in testssl.sh
The STARTTLS implementation spans multiple components within the codebase, coordinating command-line parsing, protocol translation, and OpenSSL invocation.
Command-Line Parsing and Protocol Detection
In testssl.sh at lines 21540‑21545, the -t (or --starttls) option triggers the STARTTLS workflow. When detected, the tool stores the chosen protocol in the STARTTLS_PROTOCOL variable and sets internal flags to initiate the plaintext-to-TLS upgrade sequence.
Protocol-to-OpenSSL Translation
At lines 12373‑12386 in testssl.sh, a case "$STARTTLS_PROTOCOL" block translates user-friendly protocol names into OpenSSL -starttls arguments. For example, smtp becomes -starttls smtp, while XMPP handling includes special logic for the --xmpphost parameter required for XMPP domain specification.
OpenSSL Client Invocation
The actual TLS handshake execution occurs in utils/checkcert.sh at lines 5‑7, where the tool invokes openssl s_client $STARTTLS -connect $HOST:$PORT. The $STARTTLS variable expands to the appropriate -starttls <protocol> flag when testing non-HTTP services, or remains empty for native TLS ports like 443 or 465.
Supported STARTTLS Protocols
testssl.sh recognizes the following protocols for STARTTLS testing:
- ftp – File Transfer Protocol (explicit TLS on port 21)
- smtp – Simple Mail Transfer Protocol (port 25)
- pop3 – Post Office Protocol v3 (port 110)
- imap – Internet Message Access Protocol (port 143)
- xmpp – Extensible Messaging and Presence Protocol client-to-server (port 5222)
- xmpp-server – XMPP server-to-server federation (port 5269)
- sieve – Mail filtering protocol
- telnet – Telnet with TLS option
- ldap – Lightweight Directory Access Protocol (port 389)
- irc – Internet Relay Chat
- lmtp – Local Mail Transfer Protocol
- nntp – Network News Transfer Protocol
- postgres – PostgreSQL database connections
- mysql – MySQL database connections
Testing Non-HTTP Services: Practical Examples
Use the -t flag followed by the protocol name to test non-HTTP services. All examples produce the same detailed output as HTTPS scans, including cipher grades, protocol versions, and vulnerability assessments.
SMTP Mail Servers
Test SMTP STARTTLS on the standard port 25:
testssl.sh -t smtp smtp.example.com:25
FTP with Explicit TLS
Test FTP STARTTLS on port 21 (distinct from implicit TLS on port 990):
testssl.sh -t ftp ftp.example.com:21
XMPP with Domain Specification
XMPP testing requires the --xmpphost flag to specify the domain for the STARTTLS flow:
testssl.sh -t xmpp xmpp.example.com:5222 --xmpphost example.com
Automated MX Record Testing
Scan all Mail Exchange records for a domain automatically using the --mx flag, which implicitly applies SMTP STARTTLS testing:
testssl.sh --mx example.org
STARTTLS Grading and Detection Logic
When testssl.sh detects a plain TLS port (such as 465 for SMTPS or 990 for FTPS), it skips the STARTTLS handshake and tests native TLS directly. For services requiring STARTTLS, the tool attempts the protocol-specific upgrade and falls back to plaintext detection if the handshake fails.
According to the documentation in doc/testssl.1.md, STARTTLS-specific scans receive a maximum grade cap of T (as opposed to A+ for pure TLS services), reflecting the additional attack surface introduced by the plaintext upgrade mechanism. However, all standard tests—including cipher suite evaluation, Heartbleed detection, and client simulation—execute normally after the TLS upgrade completes.
Summary
- testssl.sh supports 14 non-HTTP protocols via STARTTLS, including SMTP, FTP, XMPP, LDAP, and databases like PostgreSQL and MySQL.
- The
-tflag (or--starttls) activates protocol-specific handling defined intestssl.shlines 21540‑21545 and 12373‑12386. - OpenSSL invocation with the correct
-starttlsargument occurs inutils/checkcert.shusing the$STARTTLSvariable expansion. - All standard TLS tests apply to STARTTLS services after the handshake upgrade, though grades are capped at T to account for plaintext upgrade risks.
- Special flags like
--mx(for mail servers) and--xmpphost(for XMPP) automate protocol-specific configuration requirements.
Frequently Asked Questions
What STARTTLS protocols does testssl.sh support?
testssl.sh supports ftp, smtp, pop3, imap, xmpp, xmpp-server, sieve, telnet, ldap, irc, lmtp, nntp, postgres, and mysql. According to the source code in testssl.sh around line 12373, each protocol maps to a specific OpenSSL -starttls argument or custom handling logic for the handshake sequence.
How do I test an XMPP server with STARTTLS using testssl.sh?
Use the -t xmpp flag combined with --xmpphost to specify the domain. For example: testssl.sh -t xmpp server.example.com:5222 --xmpphost example.com. The --xmpphost parameter is required because XMPP STARTTLS negotiations depend on the domain name for proper stream initialization, as implemented in the protocol-specific case block at lines 12373‑12386.
Does testssl.sh support STARTTLS for databases like MySQL and PostgreSQL?
Yes. Both postgres and mysql are valid arguments for the -t flag. The tool sends the appropriate STARTTLS commands for these database protocols and then performs the standard TLS cipher suite and certificate validation tests, allowing database administrators to audit encryption configurations without dedicated database security tools.
What is the difference between using -t smtp and scanning port 465 directly?
Port 465 typically uses implicit TLS (TLS from connection start), while port 25 with -t smtp uses STARTTLS (plaintext upgraded to TLS). When you specify -t smtp, testssl.sh sends the STARTTLS command before the TLS handshake. Direct port 465 scans skip this step. The tool automatically detects native TLS ports and adjusts behavior, but explicit -t usage ensures the correct protocol sequence for ports running plaintext services.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →