Url rewrite for mqtt

Afternoon all,
I’m running HomeAssistant and I want to be able to setup a URL rewrite for the mqtt service. Someone very kindly pointed me in the right direction for sorting out my http to https connection upgrades, which was great. but I cannot seem to get a handle on this one. In my config file I have the following, The certificate is valid and working ok, but the mqtt clients cannot connect. Am I missing something? Thanks

server {
    listen 443;
    server_name mqtt.example.com;

    ssl on;
    ssl_certificate /config/keys/letsencrypt/fullchain.pem;
    ssl_certificate_key /config/keys/letsencrypt/privkey.pem;
    ssl_dhparam /config/nginx/dhparams.pem;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    ssl_prefer_server_ciphers on;
	
	client_max_body_size 0;

    proxy_buffering off;

	location / {
        proxy_pass http://192.168.12.201:1883/;
        proxy_set_header Host $host;
        proxy_redirect http:// https://;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}

Try:
listen 443 ssl;

Thanks rg305, I believe you helped me out before!

That is in there, but i’m getting the following error on my mqtt client:

14:10:32 MQT: Connect failed to mqtt.example.com:443, rc -1. Retry in 10 sec

:slight_smile:

Is the domain accessible from the Internet?
Does the MQT client require any specific cipher or protocol?

Yup. All my other reverse proxies are working as expected to varying ports on various dockers internally.

I’m not sure, I know i can change the port number and the host:

Does my existing config forward websockets, not sure if that needs to be included or not.

Is there anything useful in the nginx access or error logs?

I’ve got references to mqtt but just lots of these:

194.80.20.10 - - [09/Dec/2018:02:33:02 +0000] "\x10^\x00\x04MQTT\x04\xEE\x00" 400 173 "-" "-"

194.80.20.10 - - [11/Dec/2018:14:29:45 +0000] "\x10V\x00\x04MQTT\x04\xEE\x00" 400 173 "-" "-"

400 is bad request error.
The request could not be understood by the server due to malformed syntax.

Not sure why that is there:

I would briefly try:
#ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:...';
ssl_ciphers ALL;
#proxy_redirect http:// https://;

Thanks rg305.

194.80.20.10 - - [11/Dec/2018:14:44:36 +0000] "\x10^\x00\x04MQTT\x04\xEE\x00" 400 173 "-" "-"
194.80.20.10 - - [11/Dec/2018:14:44:37 +0000] "\x10V\x00\x04MQTT\x04\xEE\x00" 400 173 "-" "-"
194.80.20.10 - - [11/Dec/2018:14:44:47 +0000] "\x10^\x00\x04MQTT\x04\xEE\x00" 400 173 "-" "-"
194.80.20.10 - - [11/Dec/2018:14:44:48 +0000] "\x10V\x00\x04MQTT\x04\xEE\x00" 400 173 "-" "-"

I’m not sure the MQTT client is capable of TLS (SSL).
Just because you can change the port doesn’t mean it can encrypt the conversation.
Perhaps the conversation is already encrypted… over all ports - and there is no need to a cert.
I don’t know, but it would explain the hex code like connections.

Look into proxying “streams”.

I’m happy to run it over a port 80, i don’t need it encrypted, it has to log onto the mqtt server anyway. just annoying that i can’t figure it out.

Thanks. I saw this and started looking at it, but was totally lost.

NGINX can proxy just about anything: DNS, LDAP, IMAP, RDP, POP, etc.
It can do some as HTTP and even some as HTTPS.
But the ones that don’t fix into those nice and neat little boxes, can sometimes be processed as “streams”.

Here is there load balanced proxied mqtt stream example:

stream {
    upstream mqtt_cluster {
        server 10.0.0.1:18831;
        server 10.0.0.2:18832;
        server 10.0.0.3:18833;
    }
    server {
        listen 1883; # (tcp)
        proxy_pass mqtt_cluster;
    }
}

You can strip that down (if you only have one server); as:

stream {
   server {
        listen 1883; # (tcp)
        proxy_pass 10.0.0.1:18831;
    }
}

I tired this earlier but got the error, it wasnt that stipped back
it looked more like this:

stream {
    upstream mqtt_cluster {
        server 192.168.12.201:1883
    }
    server {
        listen 80; # (tcp)
        proxy_pass mqtt_cluster;
    }
}

But i got this error:

nginx: [emerg] "stream" directive is not allowed here in /config/nginx/site-confs/default:534

This configuration…

server {
    listen 80;
    server_name mqtt.example.com;
    location / {
        proxy_pass 192.168.12.201:1883/;
        proxy_connect_timeout 1s;
    }
}

…gives me a new error:

nginx: [emerg] invalid URL prefix in /config/nginx/site-confs/default:570

Try wrapping it in a stream:

stream {
    server {
        listen 80;
        server_name mqtt.example.com;
        location / {
            proxy_pass 192.168.12.201:1883/;
            proxy_connect_timeout 1s;
        }
    }
}

And also try removing the location:

stream {
    server {
        listen 80;
        server_name mqtt.example.com;
        proxy_pass 192.168.12.201:1883/;
        proxy_connect_timeout 1s;
    }
}

I get errors telling me the stream isn’t allowed here.

on a side note SSL is not supported: