mosquitto icon indicating copy to clipboard operation
mosquitto copied to clipboard

BUG: Enabling SSL/TLS requires definition of certfile and keyfile

Open bryant-ferguson opened this issue 5 years ago • 3 comments

mosquitto version 1.6.12 OS Ubuntu 18.04 (actually Linux Mint)

The mosquitto.conf documentation specifies that cafile or capath are required to enable TLS. It does not say that a certfile or keyfile are required, but in order to enable TLS it seems they are required.

Steps to reproduce:

  1. Create a config file in /etc/mosquitto/test.conf with the following content:
listener 8883
capath /etc/ssl/certs
  1. Send a message with mosquitto_sub without enabling encryption:
mosquitto_pub -h "<broker hostname> " -t "test" -m "test" -p 8883

This should fail as mosquitto_pub is not using TLS, but it succeeds.

  1. Send a message with an mqtt client with TLS enabled, but server validation off. This fails. I used mqtt-explorer to do this step as the mosquitto_pub client is exhibiting a separate bug with it's --insecure flag not working in conjunction with the --capath flag. That is, this command fails in all cases, but that's a separate problem:
mosquitto_pub -h "<broker hostname> " -t "test" -m "test" -p 8883 --capath "/etc/ssl/certs" --insecure
  1. Add "certfile" and "keyfile" to the config file and observe the inverse behavior of steps 2 and 3.

Perhaps this is not actually a bug and mosquitto does not support unauthenticated TLS, but in that case, it seems like the fall-back to no encryption shouldn't be happening and/or the documentation should be clarified to specify that TLS is only supported in "server auth" or "mutual auth" configurations and explicitly state that "certfile" and "keyfile" are also required to enable TLS.

bryant-ferguson avatar Oct 03 '20 19:10 bryant-ferguson

You're quite right, and happily I had already pushed a change to how this works and is documented just over a week before your report: https://github.com/eclipse/mosquitto/commit/54b95715165f5d15f5911f9a9653ba70d52fee93

The intention of this originally was to say that cafile/capath are the options that are required to have that listener go into TLS mode. The missing requirement for certfile and keyfile was because of the incorrect assumption that "everybody" would know you need a certificate and key for the server.

ralight avatar Oct 14 '20 09:10 ralight

I am not sure if that would be a new feature for consideration, but I my findings are the following:

  • If according to current state of art not all three options (certfile, keyfile, cafile), mosquitto does not enable TLS on port 8883. One would expect that mosquitto at least complains in the log file that for example "certfile was specified but keyfile is missing: SSL is disabled", or even fail because necessary file is not specified.
  • If the option require_certificate is not provided I see no reason why cafile is a must. It should be obligatory only if require_certificate is true. This should be clearly reported to log file.
  • Very often (at least many application servers I know) support combined cert+key file in one file which has the following structure:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----

which makes the option keyfile also optional.

  • Client that tries to initialize SSL connection for non-SSL-enabled port, is reported as Client <unknown> disconnected due to protocol error to the log file. This is confusing as it looks like that the client succeeded TLS negotiation but misbehaves with respect to MQTT protocol. Would be nice if mosquitto could detect the attempt to enable SSL for the port with is not configured for that and report to log something like "The client tries to start SSL on the port which is not SSL enabled".

Altogether:

  • mosquitto should check that provided certfile file is a combined file. If not, then keyfile should be required.
  • mosquitto should check that cafile is accesible/readable only if require_certificate is true.
  • mosquitto should fail when SSL is intended to be enabled, but on some reason it is not.

dmak avatar Dec 12 '20 22:12 dmak

Thanks-- this is extremely helpful!

I do think we should implement @dmak suggestion about not allowing cafile without certfile, and ensuring that the broker doesn't start with invalid configuration. Or at least have the important aspects of the configuration be in the log at a debug level. Connecting via TLS to a non-TLS listener produces a protocol error message that is impossible to figure out unless you attach a debugger

gbronner avatar Oct 09 '24 14:10 gbronner

The broker now produces an error for invalid combinations of cafile/capath/certfile/keyfile.

ralight avatar Feb 27 '25 13:02 ralight

Connecting via TLS to a non-TLS listener produces a protocol error message that is impossible to figure out unless you attach a debugger

I am not an expert, but TLS follows a specific handshake pattern and starts with a ClientHello message. A packet might look like this:

16 03 03 ...

where

16    → Handshake Protocol (0x16)
03 03 → TLS 1.2 (0x0303)

More details in Illustrated TLS 1.2 Connection.

mosquitto can capture this pattern on non-TLS port.

dmak avatar Mar 03 '25 00:03 dmak