Hi, all! My apologies if I've gotten anything wrong below.
Version
-------
3.4.13-0ubuntu1 (from Ubuntu 20.04.2)
(although I suspect this affects all versions >= 3.4)
Configuration
-------------
/etc/postfix/main.cf:
smtpd_tls_security_level = may
tls_server_sni_maps = texthash:/etc/postfix/tls_server_sni
/etc/postfix/tls_server_sni:
mail.example.net /etc/letsencrypt/live/mail.example.net/privkey.pem,
/etc/letsencrypt/live/mail.example.net/fullchain.pem
Expected
--------
When smtpd receives STARTTLS with an SNI of mail.example.net, TLS should
start.
What actually happens
---------------------
When smtpd receives STARTTLS with an SNI of mail.example.net, this is
logged:
postfix/smtpd[1994543]: warning: table
texthash:/etc/postfix/tls_server_sni: key mail.example.net: malformed
BASE64 value: /etc/letsencrypt/live/mail.exa
postfix/smtpd[1994543]: warning: tls_server_sni_maps:
mail.example.net map lookup problem
postfix/smtpd[1994543]: SSL_accept error from
mail.example.com[10.10.10.10]: -1
postfix/smtpd[1994543]: warning: TLS library problem:
error:1422E0EA:SSL routines:final_server_name:callback
failed:../ssl/statem/extensions.c:1006:
postfix/smtpd[1994543]: lost connection after STARTTLS from
mail.example.com[10.10.10.10]
postfix/smtpd[1994543]: disconnect from
mail.example.com[10.10.10.10] ehlo=1 starttls=0/1 commands=1/2
Workaround
----------
Use a hash table:
tls_server_sni_maps = hash:/etc/postfix/tls_server_sni
and create it with:
sudo postmap -F /etc/postfix/tls_server_sni
Details
-------
According to the docs, smtpd should read the tls_server_sni texthash
file on startup, then read the two .pem files, base64-encode their
concatenated contents, and store that base64 as the value for the
"mail.example.net" key. Based on the error message above it appears to
be skipping the base64 steps, and when it receives STARTTLS and should
be base64-decoding the file contents, it instead attempts to
base64-decode the incorrectly-stored '/etc/letsencrypt/live/mail.exa...'
string.
You can see here where postmap does some syntax checking, and then
correctly deals with the base64 case, and stores the results:
https://github.com/vdukhovni/postfix/blob/c0e76bc1f16273f24a4820020f0958d62804a4f2/postfix/src/postmap/postmap.c#L512-L544
I think (not sure) the issue is in dict_thash.c. It does that same
syntax checking, but despite the earlier comment "This duplicates the
parser in postmap.c", it skips the base64 case before storing the
results:
https://github.com/vdukhovni/postfix/blob/c0e76bc1f16273f24a4820020f0958d62804a4f2/postfix/src/util/dict_thash.c#L170-L183
In any case, thanks for taking a look!
Regards,
Chris