Need to set up TLS on Postfix

Civica Election Services insist they will only send mail to servers which use TLS and as I need to receive their mail at present for an election in progress that means I have to set up TLS on my incoming Postfix server.
I have tried my best to follow the guide at https://www.postfix.org/TLS_README.html for server configuration but I'm struggling to test the configuration.

My outgoing client isn't TLS-enabled so can only send in plain text and although I see the following lines (addresses munged) in the logs I'm not convinced as nothing has been received from outside with TLS:
Code:
Aug 22 22:17:47 mailin postfix/smtp[96183]: initializing the client-side TLS engine
Aug 22 22:17:47 mailin postfix/smtp[96183]: 0B0B71398A: to=<yyyy@zzzz.aaaa>, orig_to=<xxxx@xxxx.co.uk>, relay=master.localdomain[192.168.1.64]:25, delay=0.2, delays=0.1/0.06/0.02/0.03, tls=may:none, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 2DB152E0067)

If I try to enable TLS on my outgoing machine and everything then works, fine, but in all likelihood something will be wrong at at least one end and the problem will be troubleshooting that.

I have tried to use
openssl s_client to test but though this works well with https servers it seems unable to communicate with smtp and postfix complains "warning: non-SMTP command" when I follow online tutorials for validating TLS on mail servers using that.

Postfix is listening on port 25 and though I have forwarded ports 465 and 587 in my router and pf it isn't currently listening on them. There was no mention of needing them when using STARTTLS in the postfix README.

I must admit I'm out of my depth here as I've always had mail just work since setting up DKIM, SPF, and DMARC, but with Civica being so fussy I have to move on and get this extra layer of security working.
 
Civica Election Services insist they will only send mail to servers which use TLS and as I need to receive their mail at present for an election in progress that means I have to set up TLS on my incoming Postfix server.
I have tried my best to follow the guide at https://www.postfix.org/TLS_README.html for server configuration but I'm struggling to test the configuration.

I think you're mixing up some concepts of the SMTP protocol.
Please dont take that as an offense, this is often the case for longtime postmasters during long threads happening on mailing lists.

As you need to offer TLS for smtp clients (here: Civica Election Services), only smtpd_tls_* postfix's knobs are the ones you need to tweak for setting up TLS on smtpd(8) (smtpd whos listening on TCP/25, is the server process that is listening for incoming emails from outside):

Code:
# Opportunistic TLS: announce STARTTLS support to remote SMTP clients,
# but do not require that clients use TLS encryption.
smtpd_tls_security_level = may

# Supporting AUTH over TLS only
#
# Sending AUTH data over an unencrypted channel poses a security risk.
# When TLS layer encryption is required ("smtpd_tls_security_level = encrypt"),
# the Postfix SMTP server will announce and accept AUTH only after the TLS layer
# has been activated with STARTTLS.
# When TLS layer encryption is optional ("smtpd_tls_security_level = may"),
# it may however still be useful to only offer AUTH when TLS is active.
# To maintain compatibility with non-TLS clients, the default is to accept
# AUTH without encryption. In order to change this behavior, set "smtpd_tls_auth_only = yes".
smtpd_tls_auth_only = yes

# 0 Disable logging of TLS activity.
# 1 Log only a summary message on TLS handshake completion
# — no logging of client certificate trust-chain verification errors if client certificate
# verification is not required. With Postfix 2.8 and earlier, log the summary message,
# peer certificate summary information and unconditionally log trust-chain verification errors.
# 2 Also enable verbose logging in the Postfix TLS library, log session cache operations, and enable OpenSSL logging of the progress of the SSL handshake.
# 3 Also log hexadecimal and ASCII dump of TLS negotiation process.
# 4 Also log hexadecimal and ASCII dump of complete transmission after STARTTLS.
smtpd_tls_loglevel = 1

# SSL certificates
smtpd_tls_chain_files = /usr/local/etc/ssl/example.net/privkey.pem,/usr/local/etc/ssl/example.net/fullchain.pem

I have tried to use openssl s_client to test but though this works well with https servers it seems unable to communicate with smtp and postfix complains "warning: non-SMTP command" when I follow online tutorials for validating TLS on mail servers using that.

openssl-s_client(1) can of course use smtp:

Code:
% openssl s_client -connect smtp.example.org:25 -starttls smtp -crlf
Connecting to x.x.x.x
CONNECTED(00000005)
depth=3 C=US, O=Internet Security Research Group, CN=ISRG Root X2
verify return:1
depth=2 C=US, O=ISRG, CN=Root YE
verify return:1
depth=1 C=US, O=Let's Encrypt, CN=YE2
verify return:1
depth=0 CN=*.example.org
verify return:1
---
Certificate chain
 0 s:CN=*.example.org
   i:C=US, O=Let's Encrypt, CN=YE2
   a:PKEY: EC, (prime256v1); sigalg: ecdsa-with-SHA384
   v:NotBefore: Jul 11 02:29:46 2026 GMT; NotAfter: Oct  9 02:29:45 2026 GMT
 1 s:C=US, O=Let's Encrypt, CN=YE2
   i:C=US, O=ISRG, CN=Root YE
   a:PKEY: EC, (secp384r1); sigalg: ecdsa-with-SHA384
   v:NotBefore: Sep  3 00:00:00 2025 GMT; NotAfter: Sep  2 23:59:59 2028 GMT
 2 s:C=US, O=ISRG, CN=Root YE
   i:C=US, O=Internet Security Research Group, CN=ISRG Root X2
   a:PKEY: EC, (secp384r1); sigalg: ecdsa-with-SHA384
   v:NotBefore: May 13 00:00:00 2026 GMT; NotAfter: Sep  2 23:59:59 2032 GMT
 3 s:C=US, O=Internet Security Research Group, CN=ISRG Root X2
   i:C=US, O=Internet Security Research Group, CN=ISRG Root X1
   a:PKEY: EC, (secp384r1); sigalg: sha256WithRSAEncryption
   v:NotBefore: May 13 00:00:00 2026 GMT; NotAfter: Sep  2 23:59:59 2032 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
subject=CN=*.example.org
issuer=C=US, O=Let's Encrypt, CN=YE2
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ecdsa_secp256r1_sha256
Peer Temp Key: X25519, 253 bits
---
SSL handshake has read 4027 bytes and written 1672 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Protocol: TLSv1.3
Server public key is 256 bit
This TLS version forbids renegotiation.
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
250 DSN
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_256_GCM_SHA384
    Session-ID: [...]
    Session-ID-ctx:
    Resumption PSK: [...]
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    [...]

    Start Time: 1787442388
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK
EHLO client.example.net
250-smtp.example.org
250-SIZE 52428800
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
quit
221 2.0.0 Bye
closed

Postfix is listening on port 25 and though I have forwarded ports 465 and 587 in my router and pf it isn't currently listening on them. There was no mention of needing them when using STARTTLS in the postfix README.

I must admit I'm out of my depth here as I've always had mail just work since setting up DKIM, SPF, and DMARC, but with Civica being so fussy I have to move on and get this extra layer of security working.

TCP/465 (smtps) or TCP/587 (submission) are services and ports used only for authenticated users through SASL submitting emails by a MUA (Mail User Agent).
 
Back
Top