So, I ran into a few issues and it took me a bit to work it out, but I got it. I’m also using nginx for the main Home Assistant page so I can do Alexa integration (which is awesome, can’t believe I put it off so long). At first I was trying to stick mosquitto in the sites-available like you did, but that directory by default is for HTTP connections, like websites. So it works for the Home Assistant site, but not for throwing the stream thing in there for MQTT, get errors about stream object in a bad spot. Ended up poking around your linked guide and just adding the stream config after the http config in the main nginx.conf file.
My other problem was I kept getting errors about “the shared memory zone ‘SSL’ is already declared for a different use in /etc/nginx/nginx.conf.” So, I removed all the SSL config stuff from the stream config. This produced a new error “no ‘ssl_certificate’ is defined in server listening on SSL port while SSL handshaking”. So, I went back and added in the ssl_certificate, ssl_certificate_key, and dhparam parameters to the stream config. They point to the same files I used for my main site access.
This is what I ended up with:
stream {
upstream mosquitto {
server servername:1883; # My MQTT server isn't on the same server
}
server {
listen 8883 ssl;
proxy_pass mosquitto;
ssl_certificate /etc/nginx/ssl/cert.crt;
ssl_certificate_key /etc/nginx/ssl/cert.key;
ssl_dhparam /etc/nginx/ssl/dhparams.pem;
}
}
Just wanted to share in case anyone else runs into those issues.
Note, I’m using a Ubuntu VM for Home Assistant and Nginx (same server) and CentOS VM for Mosquitto. So, I didn’t have to do anything special to use the stream directive. I’m also using Zanzito with the OwnTracks emulation with no issues. And I previously bought a wildcard SSL cert through ssl2buy.com (fairly cheap if you want to go that option vs letsencrypt or something similar).
UPDATE:
I did get it to work. For me the keys was learning where the hass.io add-on certbot stores the cert files. Also the mqtt config defaulted to the /ssl directory, so I had change my file path accordingly.
Here is my config …
I had the test_user for when I had 1883 port forward testing owntracks without having to fight TLS. I removed it after I got TLS (8883) working.
Also the cert that needs to be loaded on the owntracks client is in the same directory.
I copied the cert.perm to a different directory, then renamed it to mqtt_cert.perm.
I may play with and see if HA can connect TLS, then I can turn off 1883.
@lizaoreo
I followed your instructions and added the stream to .conf.
Seems to be working (dont know how to really test it but nginx is starting at least) but I`m having problem to connect with Zanzito.
Did you import the cert on your phone or how could you connect secure from Zanzito?
Also, how is the proxy_pass used?
Are you using a purchased SSL cert for your domain? I actually purchased a wildcard cert for the domain I own, so it might be a little different than if you use something like one of the common solutions people use here.
If I understand how NGINX works (I honestly don’t really), the proxy_pass line points to the upstream line, which points to your server for MQTT. In my example above, my MQTT server would be named servername (change to localhost if on same server as NGINX) and it would be listening on port 1883 for MQTT traffic. NGINX is listening on port 8883 for MQTT traffic, so when you hit the NGINX server, you want your traffic to be on port 8883.
In Zanzito, my MQTT connection settings are basically this:
Host: NGINX Server Name (ie, mqtt.homedomain.com)
Port: 8883
Security:
Username: MQTT Username (this is whatever you set up for mosquito, not NGINX/HomeAssistant)
Password: MQTT Password
SSL/TLS Connection: Checked
Don't worry about import CA I'm pretty sure (I didn't need to).
Everything else is variable based on preference (I have instant updates set, heartbeat enabled, and intervals at 90seconds). I don’t use Home host settings as I set up the same domain name environment at home and forward the outside name to the server, so basically same address hits server inside and outside.
Let me know if that helps. If you need help with the mosquito server, let me know and I drop my config in and explain it.
My yaml:
mqtt:
broker: 127.0.0.1
port: 1883
client_id: home-assistant-1
username: !secret mqtt_username
password: !secret mqtt_password
However, the port specification is done in the mosquito component, not in HASS.
If you are on hassio, you can just open the mosquito component and set plain websockets to true. In the ngynix config, (I use the addon from https://github.com/bestlibre/hassio-addons) I added an entry to point to the 1884 nginx websockets port.
Do you specify the clientid because that’s what HA is using to communicate to the service?
What I’m trying to do is, from the internet, access mqtt.example.com on port 80 and have that proxied over to 192.168.1.25:1883. Hassio and nginx are running on different machines. Once I get that working I’ll muck around with SSL and user authentication.
client id can be anything. Username and pass have to exist in the MQTT side. Also, HASS does NOT use websockets. You have to support BOTH WS and non WS comms in mqtt.
WS requires some additional work in nginx to work properly if you aren’t using the hassio addon.
I’m doing the exact same thing (except on https) for owntracks.
I’m also using the add-on. Thanks to your server block, I’m able to get http://mqtt.example.com working.
Now I want to get https working, but I must be missing something or CertBot failed me. My config block looks like
Since nginx is so new to me, im not 100% sure, but if you are using it for reverse proxy, then you don’t need to install certs on the target, correct? You can just run the service as http and nginx will force the client to use https using the cert installed in nginx and then proxy everything between the client and the target.
Last I checked, certbot didn’t support wildcard certs, so you need to make sure your cert covers mqtt.example.com You are correct about certs, mosquitto doesn’t need to know about them. I would however disable anonymous access. If you are able to access the mqtt service over http, you should be able to hit it over https if your certs are valid for that site.
I don’t think it does wildcards, but individual certs are so easy, why bother? I’m loving nginx and Certbot. Finally I can create as many subdomains I want for any service and have everything go over 80,443 without having to screw around with certs on the service itself. And no more having to remember port numbers! I just have to remember the subdomain and I’m golden. I’ve got about a dozen services I’m using with nginx now. I might even start using it for work for beta and internal sites. Why pay a few hundred bucks for a wildcard cert for ssl on test sites if I can get it for free?
I also want to hide my mqtt behind nginx on my hassbian install for zanzito.
but as soon I add a line with stram it hits me with ginx: [emerg] "stream" directive is not allowed here in /etc/nginx/sites-enabled/mosquitto.conf:x
It looks so straight forward - but I realy struggle hard
stream directive needs nginx 1.9 - 1.10.3 installed
when I add in the nginx.conf: load_module /usr/lib/nginx/modules/ngx_stream_module.so;
I ll get [emerg] module "ngx_stream_module" is already loaded in /etc/nginx/modules-enabled/50-mod-stream.conf:1 so the stream module is aparently loaded already.
here I hit rock bottom - out of ideas - So Ideas are most welcome
I’m running HAos and using NGINX Proxy Manager (0.11.0) to use ha.example.com to access HA with SSL. Works great.
I have an off-site OpenSprinkler that I want to use MQTT with. I have the Mosquitto broker addon installed. On my LAN using 192.168.xx.xx:1883 it works great. But when I move to offsite and try to use mqtt.example.com as the broker address, nothing works.
I have NGINX forwarding mqtt.example.com to 192.168.xx.xx:1883, but no luck. I’ve tried with the Sprinkler using a broker address of mqtt.example.com on both port 80 and 1883.