DEV Community

Daniel Holth
Daniel Holth

Posted on

Using nginx as a SSL offloading proxy to MQTT

nginx's stream_proxy and stream_ssl modules can be used to add tls/ssl support to mosquitto or any tcp server.

This can be useful because mosquitto only supports certain certificate types. The mbedTLS stack I was using on a microcontroller board wasn't able to understand my certificate loaded into mosquitto; but it was able to make https:// requests to nginx on the same server with the same certificate. Our nginx server supports, and has permission to read, these certificates.

For MQTT we will proxy tcp directly and we will not use http. Edit /etc/nginx/nginx.conf to add include /etc/nginx/conf.d/*.stream; at the top level, as /etc/nginx/conf.d/*.conf is loaded into the http section.

On Fedora 40, dnf install nginx-mod-stream to get the module.

/etc/nginx/conf.d/01-mqtt.stream::

stream {
        upstream backend {
                hash $remote_addr consistent;
                server localhost:1883;
        }
        server {
                listen       8883 ssl;
                listen       [::]:8883 ssl;
                server_name  hass;

                ssl_certificate "/etc/letsencrypt/live/hass/fullchain.pem";
                ssl_certificate_key "/etc/letsencrypt/live/hass/privkey.pem";
                ssl_session_cache shared:SSLB:1m;
                ssl_session_timeout  10m;
                ssl_ciphers PROFILE=SYSTEM;
                ssl_prefer_server_ciphers on;

                proxy_connect_timeout 1s;
                proxy_timeout 10m; # is default
                proxy_pass backend;
        }
}
Enter fullscreen mode Exit fullscreen mode

After a restart, nginx listens on the mqtt-tls port 8883, handles encryption, and forwards plain text to localhost:1883.

For mosquitto, the only configuration needed is

password_file /mosquitto/config/pwfile.conf
listener 1883
# or listener 1883 0.0.0.0 to listen on all interfaces
Enter fullscreen mode Exit fullscreen mode

Top comments (0)