Compare commits
5 Commits
8bcc12ec96
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e552ae4e5c | ||
|
|
8aea87c3cd | ||
|
|
8f638bfa4f | ||
|
|
9ffe021354 | ||
|
|
b66ae2cc47 |
@@ -12,12 +12,27 @@ exposes three listeners, each with a different trust model:
|
||||
|
||||
| Port | Protocol | Auth | Who it's for |
|
||||
|------|----------|------|---------------|
|
||||
| `1883` | MQTT (plaintext) | username/password | internal services (e.g. the Laravel subscriber, Python publisher) |
|
||||
| `1883` | MQTT (plaintext, Compose network only) | username/password | internal backend service; not host-published |
|
||||
| `8883` | MQTT over TLS | **client certificate** | field devices |
|
||||
| `8884` | MQTT over TLS | username/password (server cert only) | scoped app clients and administrators |
|
||||
| `443` (`/mqtt` → loopback `9001`) | MQTT over WSS/TLS | username/password | scoped app clients |
|
||||
| `8884` | MQTT over TLS | username/password (server cert only) | scoped app clients and administrators on networks that expose the raw port |
|
||||
|
||||
The former anonymous WebSocket listener on `9001` is disabled. The current web portal receives
|
||||
live updates from the backend rather than connecting directly to Mosquitto.
|
||||
The former anonymous WebSocket listener on `9001` is now authenticated, uses the same ACL as the
|
||||
TLS listeners, and is bound to host loopback only. Nginx exposes it as WSS at `/mqtt` on port 443;
|
||||
the web portal itself continues to receive live updates from the backend.
|
||||
|
||||
The TLS listeners use `mosquitto/certs/public-fullchain.pem` and
|
||||
`mosquitto/certs/public-privkey.pem`, copied from the host's Let's Encrypt certificate during
|
||||
deployment with owner `1883:1883` and mode `0600`. These files are deployment secrets/artifacts
|
||||
and are excluded from Git.
|
||||
|
||||
The live password database is likewise outside Git at
|
||||
`/home/ubuntu/.config/ul-platform/mosquitto.passwd`, bind-mounted read-only as
|
||||
`/run/secrets/mosquitto_passwd`. The deployed ACL is copied to
|
||||
`/home/ubuntu/.config/ul-platform/mosquitto.acl` and bind-mounted beside it. Both files are owned
|
||||
by broker uid/gid 1883 with mode 0600. Provisioning updates the host password file and restarts Mosquitto; the
|
||||
tracked `mosquitto/config/passwd` is only a legacy/bootstrap sample and must not receive new
|
||||
organization credentials.
|
||||
|
||||
Device authentication happens on **port 8883**. A device presents a client
|
||||
certificate signed by the app's own Certificate Authority (CA); Mosquitto
|
||||
|
||||
@@ -11,14 +11,13 @@ services:
|
||||
mosquitto:
|
||||
image: eclipse-mosquitto:2
|
||||
ports:
|
||||
- "1883:1883"
|
||||
- "8883:8883"
|
||||
- "8884:8884"
|
||||
- "127.0.0.1:9001:9001"
|
||||
volumes:
|
||||
- ./mosquitto:/mosquitto
|
||||
# Publicly trusted server identity for app MQTTS. The device listener still
|
||||
# validates client certificates against /mosquitto/certs/ca.crt.
|
||||
- /etc/letsencrypt:/etc/letsencrypt:ro
|
||||
- /home/ubuntu/.config/ul-platform/mosquitto.passwd:/run/secrets/mosquitto_passwd:ro
|
||||
- /home/ubuntu/.config/ul-platform/mosquitto.acl:/run/secrets/mosquitto_acl:ro
|
||||
|
||||
backend:
|
||||
build:
|
||||
|
||||
@@ -2,8 +2,16 @@ per_listener_settings true
|
||||
|
||||
# Plain MQTT — internal services and clients authenticate with username/password on port 1883
|
||||
listener 1883 0.0.0.0
|
||||
password_file /mosquitto/config/passwd
|
||||
acl_file /mosquitto/config/devices.acl
|
||||
password_file /run/secrets/mosquitto_passwd
|
||||
acl_file /run/secrets/mosquitto_acl
|
||||
allow_anonymous false
|
||||
|
||||
# Authenticated MQTT over WebSocket for app clients. Docker binds this listener only to
|
||||
# host loopback; nginx supplies the public WSS/TLS endpoint at /mqtt on port 443.
|
||||
listener 9001 0.0.0.0
|
||||
protocol websockets
|
||||
password_file /run/secrets/mosquitto_passwd
|
||||
acl_file /run/secrets/mosquitto_acl
|
||||
allow_anonymous false
|
||||
|
||||
# TLS MQTT — devices authenticate with client certificates (port 8883)
|
||||
@@ -14,19 +22,19 @@ allow_anonymous false
|
||||
# since there's no config/cert hot-reload.
|
||||
listener 8883 0.0.0.0
|
||||
cafile /mosquitto/certs/ca.crt
|
||||
certfile /etc/letsencrypt/live/dev.hub.umagul.net/fullchain.pem
|
||||
keyfile /etc/letsencrypt/live/dev.hub.umagul.net/privkey.pem
|
||||
certfile /mosquitto/certs/public-fullchain.pem
|
||||
keyfile /mosquitto/certs/public-privkey.pem
|
||||
require_certificate true
|
||||
use_identity_as_username true
|
||||
allow_anonymous false
|
||||
acl_file /mosquitto/config/devices.acl
|
||||
acl_file /run/secrets/mosquitto_acl
|
||||
|
||||
# TLS MQTT — app/admin username+password access (port 8884). App usernames are orgIds;
|
||||
# devices.acl confines them to ul/{orgId}/app/... . No anonymous listener is exposed.
|
||||
listener 8884 0.0.0.0
|
||||
certfile /etc/letsencrypt/live/dev.hub.umagul.net/fullchain.pem
|
||||
keyfile /etc/letsencrypt/live/dev.hub.umagul.net/privkey.pem
|
||||
certfile /mosquitto/certs/public-fullchain.pem
|
||||
keyfile /mosquitto/certs/public-privkey.pem
|
||||
require_certificate false
|
||||
password_file /mosquitto/config/passwd
|
||||
password_file /run/secrets/mosquitto_passwd
|
||||
allow_anonymous false
|
||||
acl_file /mosquitto/config/devices.acl
|
||||
acl_file /run/secrets/mosquitto_acl
|
||||
|
||||
@@ -21,8 +21,16 @@ server {
|
||||
client_max_body_size 20m;
|
||||
|
||||
location /mqtt {
|
||||
# Anonymous MQTT-over-WebSocket was removed for Sprint 2 security criterion B1.
|
||||
return 410;
|
||||
# Authenticated, ACL-confined MQTT-over-WebSocket. Mosquitto is bound to loopback;
|
||||
# nginx terminates publicly trusted TLS so phones can use standard port 443.
|
||||
proxy_pass http://127.0.0.1:9001/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
location / {
|
||||
|
||||
Reference in New Issue
Block a user