Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow MQTT connection to be TLS encrypted #90

Open
dicer opened this issue Feb 2, 2024 · 7 comments
Open

Allow MQTT connection to be TLS encrypted #90

dicer opened this issue Feb 2, 2024 · 7 comments

Comments

@dicer
Copy link

dicer commented Feb 2, 2024

I have a MQTT server which allows access via TLS only. Just setting the port to 8883 results in a lot of complaining by the server as hms-mqtt-publisher seems to reconnect really fast and often, but not with TLS enabled.

Is there a way this could be implemented and exposed to the config.toml?

@DennisOSRM
Copy link
Owner

Sure, this can be implemented. Probably wouldn't even take that long. Biggest barrier would be to setup a server with TLS support for testing. Is there some good tutorial how to do that?

@dicer
Copy link
Author

dicer commented Feb 2, 2024

I tried to implement this myself, but this is the first time I fumble with rust, so I couldn't get thinks very far...
This is what I came up with after reading lots of docs, but I couldn't get it to compile yet:

In rumqttc_wrapper.rs:

        let root_cert_store = rustls::RootCertStore {
            roots: webpki_roots::TLS_SERVER_ROOTS.iter().cloned().collect(),
        };

        let client_config = tokio_rustls::rustls::ClientConfig::builder()
          //  .with_safe_defaults()
            .with_root_certificates(root_cert_store)
            .with_no_client_auth();

        mqttoptions.set_transport(Transport::tls_with_config(client_config.into()));

I think webpki_roots is a good idea, cause in a docker environment there might not be any certs available for rust to load.

Regarding a TLS supported MQTT server you could try testing with https://www.hivemq.com/products/mqtt-cloud-broker/
They offer a free cloud server.
Alternatively you could use the official mosquitto docker container, get some LetsEncrypt certs and configure it something like this:

listener 8883
protocol mqtt
cafile   /mosquitto/config/ca.crt
certfile /mosquitto/config/server.crt
keyfile  /mosquitto/config/server.key
tls_version tlsv1.2

@DennisOSRM
Copy link
Owner

I think I got this to work. The code change is PR #93, but it needs testing. As of writing it is only tested on macOS/X86. And should work, but with TLS things might be funny on other platforms.

Btw, I implemented this using a free instance from hivemq and their web client.

Bildschirmfoto 2024-02-03 um 15 25 59

@DennisOSRM
Copy link
Owner

Also tested on rPi4/Ubuntu successfully

@dicer
Copy link
Author

dicer commented Feb 3, 2024

Thanks! This does not work for me, but I think it is because of my self-signed cert I'm currently running with :( I have all the certs in the right place, but something is going wrong. The server is showing me
OpenSSL Error[0]: error:1403F418:SSL routines:ACCEPT_SR_FINISHED:tlsv1 alert unknown ca.
Well, not up to you to debug. Just writing this here so you know I'm trying to test but I'm not quite there yet...

What I did notice though: When running in the docker container, there are no system CAs installed in /etc/ssl/certs. Have you tried running this PR in a container? I added a RUN apt-get update && apt-get -y install ca-certificates but as written above I'm not able to verify if this is necessary or not.

@DennisOSRM
Copy link
Owner

What I did notice though: When running in the docker container, there are no system CAs installed in /etc/ssl/certs. Have you tried running this PR in a container? I added a RUN apt-get update && apt-get -y install ca-certificates but as written above I'm not able to verify if this is necessary or not.

Haven't tried to run it in a container, yet. But adding system CAs sounds like a necessary step.

@dicer
Copy link
Author

dicer commented Feb 12, 2024

I had some time to test this and can confirm this works with a mosquitto server using letsencrypt certificates.
The one thing missing for me: The supplied Dockerfile does not come with CAs, so TLS with the official docker image is not working at all at the moment. I fixed this by building the container with the following addition to the Dockerfile:

...
# Copy the installed application from the build image to the smaller image.
COPY --from=builder /usr/local/cargo/bin/hms-mqtt-publish /usr/local/bin/hms-mqtt-publish

# Install ca-certificates to support TLS connections
RUN apt-get update && apt-get -y install ca-certificates

# Generate the config file from given environment variables
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants