Devices cannot connect after FreeBSD 13 update due to TLS issue

A client has a number of devices that email a report at the end of the day. Several years ago (2021?) they stopped receiving the emails so, as a favor (they've been a good client), I built a spare FreeBSD server in my office to act as a mail server. It receives the automated messages from their devices then sends them successfully. I'm using OpenSMTPD and Dovecot.

It has been working flawlessly on FreeBSD 12.x until I recently updated the machine to FreeBSD 13. I can manually send emails just fine and they show up in my Gmail so I know the mail server is working. But it looks like the incoming messages from the devices are being rejected because in /var/log/maillog I see a bunch of:

smtp disconnected reason="io-error: handshake failed: error:14209102:SSL routines:tls_early_post_process_client_hello:unsupported protocol

I'm not sure what version of TLS the devices are using but I THOUGHT it was TLS 1.2 because in my dovecot.conf (which has been working for years) I have:
ssl_min_protocol = TLSv1.2

Is FreeBSD enforcing a TLS version higher than v1.2 ?? How can I check?

Is there a way I can see exactly how the devices are trying to connect?

Is there something I can change temporarily to see if the messages start coming through?

Obviously I'm sure many things changed going from FreeBSD 12.4 to 13 but how can I pinpoint exactly what caused my mail server to stop accepting the messages?

Any ideas are appreciated! Thanks!!
 
Is FreeBSD enforcing a TLS version higher than v1.2 ?? How can I check?
This has nothing to do with FreeBSD, but pretty much all services default to TLS 1.2 and higher nowadays and disable lower versions because they are known to be insecure.

You *could* re-enable insecure protocol versions (see 'protocols' an 'ciphers' in smtpd.conf(5)), but you really *should* urge your client to update those ancient devices that only support insecure TLS versions.
 
This has nothing to do with FreeBSD, but pretty much all services default to TLS 1.2 and higher nowadays and disable lower versions because they are known to be insecure.

You *could* re-enable insecure protocol versions (see 'protocols' an 'ciphers' in smtpd.conf(5)), but you really *should* urge your client to update those ancient devices that only support insecure TLS versions.
Thanks and I agree, however not everyone has the means to replace a bunch of expensive equipment. I have my firewall set to only allow connections from their IP and I'm not using the mail server for anything else.

I'm guessing Dovecot wasn't following my ssl_min_protocol = TLSv1.2 line in my config file or it was in the wrong file or something. I wish I could figure out exactly what changed to prevent it from working.
 
Dovecot only handles IMAP (and POP3 if you use that...), you need to set the minimum supported TLS protocol for the SMTP server.
However, I just checked the FreeBSD manpage for smtpd.conf and it seems OpenSMTPD on FreeBSD doesn't offer the 'protocols' and 'ciphers' options. I've only used OpenSMTPD on OpenBSD and that's where I earlier checked the manpage for those options... So I suspect it just uses the defaults, which is >TLS1.2 nowadays.

Any chance you can switch to postfix on that server?
 
There's an additional configuration file /usr/local/etc/dovecot/conf.d/10-ssl.conf and mine currently looks like:

ssl = yes ssl_cert = </usr/local/etc/letsencrypt/live/pulp7.design215.com/cert.pem ssl_key = </usr/local/etc/letsencrypt/live/pulp7.design215.com/privkey.pem #ssl_ca = </usr/local/etc/apache24/ssl.crt/<apache ssl cca bundle>.ca-bundle #ssl_protocols = !SSLv3 # SSL DH parameters # Generate new params with `openssl dhparam -out /etc/dovecot/dh.pem 4096` # Or migrate from old ssl-parameters.dat file with the command dovecot # gives on startup when ssl_dh is unset. ssl_dh = </usr/local/etc/dovecot/dh.pem # Minimum SSL protocol version to use. Potentially recognized values are SSLv3, # TLSv1, TLSv1.1, and TLSv1.2, depending on the OpenSSL version used. ssl_min_protocol = TLSv1 # SSL ciphers to use, the default is: ssl_cipher_list = ALL:!kRSA:!SRP:!kDHd:!DSS:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4:!ADH:!LOW@STRENGTH # To disable non-EC DH, use: #ssl_cipher_list = ALL:!DH:!kRSA:!SRP:!kDHd:!DSS:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4:!ADH:!LOW@STRENGTH #ssl_require_crl = yes #ssl_client_ca_dir = #ssl_client_ca_file = #ssl_verify_client_cert = no #ssl_cert_username_field = commonName #ssl_dh_parameters_length = 1024 #ssl_cipher_list = ALL:!LOW:!SSLv2:!EXP:!aNULL #ssl_prefer_server_ciphers = no #ssl_crypto_device = #ssl_options =

So, first of all, this explains why my ssl_min_protocol = TLSv1.2 line in the main config file was ignored, because this file has always had ssl_min_protocol = TLSv1.

But what do I need to change in this file for it to allow TLSv1 again? Do I need to get rid of !LOW@STRENGTH ??
 
UPDATE 6 March 2024,

I've been trying to update the openssl.cnf file to allow TLS 1.0 but so far I have not been successful. I found a couple of articles online where people were able to get it working in Ubuntu and I also followed the config docs on openssl.org but I have not been able to make it work on my FreeBSD 13 box.

Any ideas would be super helpful!! This server is specifically set up to connect to these legacy devices and my firewall is set to only allow those devices to connect. This was working perfectly with FreeBSD 12.4.

I also looked at the software versions that WERE WORKING previously:

dovecot upgraded from 2.3.21 to 2.3.21_3
opensmtpd upgraded from 7.3.0_2,1 to 7.3.0_3,1

So I don't see any huge changes there.

Thanks!
 
There's an additional configuration file /usr/local/etc/dovecot/conf.d/10-ssl.conf
dovecot does not handle the incoming smtp connections.

This was working perfectly with FreeBSD 12.4.
Because OpenSSL 1.1.1 had those insecure TLS versions still enabled by default, OpenSSL3 defaults to TLS1.2+


What happens if you specify ciphers in smtpd.conf(5)?
Those are only the ciphers, not the TLS version used.
OpenSMTPD does not have the 'protocols' option on FreeBSD. I suspect its simply set to the default of the OpenSSL version it is built against, i.e. >=TLS1.2


But why aren't those clients simply follow the standards/RFCs and try to connect unencrypted via plain SMTP without STARTTLS? True, that's not secure, but the standards for email delivery are littered with highly questionable fallbacks for brain-damaged implementations of all the involved protocols (*cough*microsoft*cough*) and the primary goal is usually to get everything delivered.

However, (IMHO) the easiest workaround seems to be switching to postfix, which allows for setting all the allowed TLS versions (down to old, rotten SSLv3). You can also quite easily set up a dedicated listener on another port for only those clients, even locked down via strict _restriction rules to e.g. only allow submission to a single recipient or domain on that port.
 
However, I just checked the FreeBSD manpage for smtpd.conf
The pkg man page contains protocols that are not explained on the web.
Code:
protocols protostr
                     Define the protocol versions to be used for TLS sessions.
                     Refer to the tls_config_parse_protocols(3) manpage for
                     the format of protostr.
work/opensmtpd-7.3.0p2/openbsd-compat/libtls/tls_config.c
Code:
                if (strcasecmp(p, "all") == 0 ||
                    strcasecmp(p, "legacy") == 0)
                        proto = TLS_PROTOCOLS_ALL;
                else if (strcasecmp(p, "default") == 0 ||
                    strcasecmp(p, "secure") == 0)
                        proto = TLS_PROTOCOLS_DEFAULT;
                if (strcasecmp(p, "tlsv1") == 0)
                        proto = TLS_PROTOCOL_TLSv1;
                else if (strcasecmp(p, "tlsv1.0") == 0)
                        proto = TLS_PROTOCOL_TLSv1_0;
                else if (strcasecmp(p, "tlsv1.1") == 0)
                        proto = TLS_PROTOCOL_TLSv1_1;
                else if (strcasecmp(p, "tlsv1.2") == 0)
                        proto = TLS_PROTOCOL_TLSv1_2;
                else if (strcasecmp(p, "tlsv1.3") == 0)
                        proto = TLS_PROTOCOL_TLSv1_3;
 
Back
Top