Test SMTP and LMTP TLS with posttls-finger
posttls-finger lets you inspect a mail server's greeting, STARTTLS handshake, certificate and cipher choice without sending a single message. Allow about 10 minutes for a known test endpoint. The examples use Postfix 3.8.6, installed here as package version 3.8.6-1ubuntu0.1.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a shell, the posttls-finger executable and network access to the service. A normal user is enough for a remote TCP probe. Connecting to a protected local UNIX socket may need the service account or elevated privileges, but do not reach for sudo just because a remote probe failed.
1. Confirm the Installed Tool
Check the Postfix version and the command's usage text before copying examples. This matters because the manual describes posttls-finger as an unsupported test program, so option compatibility is not promised between releases.
$ postconf mail_version
mail_version = 3.8.6
$ command -v posttls-finger
/usr/sbin/posttls-finger
$ posttls-finger -h 2>&1 | head -n 4
posttls-finger: option requires an argument -- 'h'
usage: posttls-finger [-acCfSvw] ...
That final command deliberately asks for help with an option that needs a value. The useful result is the usage line, not the diagnostic. If the executable is missing, install it through your normal package-management process rather than guessing at a replacement.
Checkpoint
You have a version number and a working executable. The rest of this guide assumes the 3.8 option set.
2. Probe an SMTP Service
Start with a host you are authorised to test. The default SMTP destination uses the service name from /etc/services, normally port 25. When the destination is a domain, Postfix may perform an MX lookup: useful for checking delivery routing, but it may not test the particular host you had in mind.
$ posttls-finger -c -t 10 -T 10 mail.example.net
- -c suppresses the SMTP chat and leaves TLS-related information in the log.
- -t covers the TCP connection and greeting. An unresponsive endpoint cannot hold your terminal forever.
- -T covers EHLO, STARTTLS and QUIT. Same timeout idea, later in the conversation.
These are ordinary, read-only diagnostics. They do not submit mail. A successful run normally shows a connection or greeting, server capabilities, TLS protocol and cipher information, then certificate verification details, though exact wording varies with the server, OpenSSL and Postfix build. A refusal or timeout is still useful evidence: the port may be closed, a firewall may have intervened, or the endpoint is not the service you expected.
Checkpoint
Confirm that the destination, address family and port match the service you meant to inspect. A successful TCP connection is not proof that certificate verification succeeded.
3. Test One Exact Host Instead of MX Routing
Put a hostname in square brackets to disable MX lookup. This is also required when the destination is an IP address. Append a port when the service is not on the default SMTP port.
$ posttls-finger -c -t 10 -T 10 '[mx1.example.net]:587'
$ posttls-finger -c -t 10 -T 10 '[203.0.113.25]:2525'
These commands address one endpoint directly. They do not make the certificate name valid: a certificate for mail.example.net may not match an address literal. To test a server by address while still checking the expected name, add the name as a match argument or pick a security level whose matching rules fit the test.
IPv6 destinations use the Postfix form [ipv6:2001:db8::25]:25. That address is reserved documentation space and is not expected to connect.
4. Read Certificate and Trust Results
If TLS and STARTTLS are available, the tool attempts a handshake and verifies the peer according to the selected security level. With DNSSEC support, the default -l level is dane; otherwise it is secure. That default is environmental, so record it when comparing two hosts.
$ posttls-finger -c -L routine,certmatch mail.example.net
$ posttls-finger -c -L peercert,certmatch mail.example.net
The default logging is routine,certmatch. certmatch reports certificate names and which one matched. peercert adds a compact subject, issuer and fingerprint summary. Use -C when you need the remote trust chain in PEM form:
$ posttls-finger -cC -L none mail.example.net
With -C, leave -F and -P unset if the goal is to see the chain the remote server actually sends. Use -F /path/to/ca-bundle.pem or -P /path/to/ca-directory only when you intentionally want to test a particular trust store. Do not paste private keys into a command line or add a key file to this diagnostic unless the remote service explicitly requires client authentication.
Use -s server.example.net to send a specific TLS Server Name Indication value. SNI is not sent by default, except that DANE handling can derive it from the TLSA base domain. A hostname mismatch is often a sign that the test omitted the SNI name or hit the wrong endpoint, not proof the server has no valid certificate.
5. Make the Security Policy Explicit
For a repeatable check, name the level you mean instead of relying on the host's DNSSEC state. This asks for the secure policy:
$ posttls-finger -c -l secure mail.example.net
The fingerprint level can test a certificate or public-key fingerprint before a policy is deployed. Match arguments mean different things at each level:
- verify and secure read match arguments as certificate DNS names.
- fingerprint reads them as certificate or public-key digests.
- dane and dane-only ignore explicit match names in favour of the hostname and nexthop strategies.
The none, may and encrypt levels are poor choices for learning about peer certificates, since they skip the same certificate checks. In particular, may and encrypt can negotiate anonymous TLS where the server allows it. A handshake alone is not a trust result.
For a narrow protocol test, -p '>=TLSv1' is the default protocol policy. The syntax follows Postfix TLS configuration. Check the installed manpage for a deliberate include or exclude policy; do not infer a protocol name from a server banner.
6. Check TLS Session Reuse
To test whether a cacheable TLS session is reused, give a positive reconnect delay:
$ posttls-finger -c -r 2 -m 3 mail.example.net
The tool closes the connection, waits two seconds, and reconnects. It reports cache operations and whether the session was reused. -m 3 limits retries when a load balancer sends the reconnect to a different backend; the default maximum is 5. A changing EHLO server name is a useful clue that the load balancer, not TLS itself, explains the result.
This remains a probe, not a production performance test. It keeps its TLS session cache in private process memory and never talks to tlsmgr or any other Postfix daemon.
7. Probe LMTP When the Protocol Is Different
Use -S to disable SMTP and speak LMTP. A TCP LMTP service uses port 24 by default; a local service can use a UNIX socket.
$ posttls-finger -S -c 'inet:lmtp.example.net:24'
$ posttls-finger -S -c 'unix:/run/example/lmtp.sock'
Use the socket path supplied by the service configuration. The second command may need access to that socket, but changing its permissions or restarting the service sits outside this diagnostic. For TCP LMTP, the inet: prefix removes ambiguity and makes the protocol choice visible in a runbook.
Common traps and recovery
- An MX result is not a direct-host result. Re-run with square brackets when you need one specific host.
- A successful handshake is not a trusted certificate. Re-run with an explicit
-llevel and inspect the certificate match. - A timeout is not fixed by elevated privileges. Check DNS, routing, firewall rules and the selected port instead.
The command changes no Postfix configuration, tables or daemon state, so there is nothing to undo. If your investigation involved a temporary local trust file or client key, remove it using your normal change-control process once you have confirmed no other service uses it.
Done means
- You confirmed the installed version and syntax. Postfix and posttls-finger both checked out.
- You know your routing. Whether the probe used MX routing or one exact host and port.
- You recorded the TLS details. Protocol, cipher, certificate name match and trust result all noted.
- You made the security level explicit whenever the result needed to be repeatable.
- You used
-ronly when session reuse was the actual question. - You left everything else alone. No configuration change, no service restart, no mail sent.