fill in mosquitto tls section
This commit is contained in:
		
							parent
							
								
									7311909609
								
							
						
					
					
						commit
						7f11e484bd
					
				| @ -1,65 +1,210 @@ | |||||||
| # Mosquitto TLS Setup | # Mosquitto TLS Setup | ||||||
| 
 | 
 | ||||||
| Ref: <https://www.chirpstack.io/docs/guides/mosquitto-tls-configuration.html> | There is an [official guide](https://www.chirpstack.io/docs/guides/mosquitto-tls-configuration.html) from ChirpStack, which you can cross-reference. It is fairly complete, so some details are omitted here for brevity. | ||||||
| 
 | 
 | ||||||
| You generate a certificate authority which has the following purposes: | In the previous guide, you set up a Caddy web server to proxy the ChirpStack web interface, and you saw that Caddy automatically sets up TLS for you. This secures traffic between web browsers and ChirpStack. | ||||||
| 
 | 
 | ||||||
| - Generate a Mosquitto server certificate so gateways can connect to it via TLS | However, you *also* need to secure traffic between gateways and ChirpStack. Because the communication protocol between the gateways and ChirpStack is MQTT and not HTTP, security is a little bit trickier. You will still use transport-layer security (TLS) to secure the traffic, but you need to create a certificate authority (CA). The CA is, itself, a certificate with corresponding secret key which you can use to issue certificates for the Mosquitto server and all the gateways connecting to it. | ||||||
| - Generate client certificates for gateways so they can prove their identity to the Mosquitto server |  | ||||||
| 
 | 
 | ||||||
| When you create the CA, three files are generated: | ## Create a CA | ||||||
|  | 
 | ||||||
|  | Start by installing the CloudFlare SSL tool: | ||||||
|  | 
 | ||||||
|  | ```sh | ||||||
|  | sudo apt install golang-cfssl | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Run these commands wherever you like (your home folder is fine) to create a few files: | ||||||
|  | 
 | ||||||
|  | ```sh | ||||||
|  | # Certificate Signing Request (CSR) to create CA | ||||||
|  | # The "request" is local; no third-party involved. | ||||||
|  | cat <<EOF > ca-csr.json | ||||||
|  | { | ||||||
|  |   "CN": "ChirpStack CA", | ||||||
|  |   "key": { | ||||||
|  |     "algo": "rsa", | ||||||
|  |     "size": 4096 | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | EOF | ||||||
|  | 
 | ||||||
|  | # Settings for CA creation | ||||||
|  | cat <<EOF > ca-config.json | ||||||
|  | { | ||||||
|  |   "signing": { | ||||||
|  |     "default": { | ||||||
|  |       "expiry": "8760h" | ||||||
|  |     }, | ||||||
|  |     "profiles": { | ||||||
|  |       "server": { | ||||||
|  |         "expiry": "8760h", | ||||||
|  |         "usages": [ | ||||||
|  |           "signing", | ||||||
|  |           "key encipherment", | ||||||
|  |           "server auth" | ||||||
|  |         ] | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | EOF | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | With those files in place, generate the CA: | ||||||
|  | 
 | ||||||
|  | ```sh | ||||||
|  | cfssl gencert -initca ca-csr.json | cfssljson -bare ca | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | This creates three files: | ||||||
| 
 | 
 | ||||||
| - `ca.csr` | - `ca.csr` | ||||||
| - `ca.pem` | - `ca.pem` | ||||||
| - `ca-key.pem` | - `ca-key.pem` | ||||||
| 
 | 
 | ||||||
| Then when you create the MQTT cert, three more files are generated: | You can discard `ca.csr`. | ||||||
|  | 
 | ||||||
|  | ## (Re-)Configure ChirpStack | ||||||
|  | 
 | ||||||
|  | Copy the remaining two files to a more permanent place and set ownership/permissions: | ||||||
|  | 
 | ||||||
|  | ```sh | ||||||
|  | mkdir -p /etc/chirpstack/certs | ||||||
|  | cp ca.pem /etc/chirpstack/certs | ||||||
|  | cp ca-key.pem /etc/chirpstack/certs | ||||||
|  | chown -R chirpstack:chirpstack /etc/chirpstack/certs | ||||||
|  | chmod 400 /etc/chirpstack/certs/* | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Then configure ChirpStack to use the CA by modifying `/etc/chirpstack/chirpstack.toml` to have the following: | ||||||
|  | 
 | ||||||
|  | ```toml | ||||||
|  | [gateway] | ||||||
|  |   client_cert_lifetime="12months" | ||||||
|  |   ca_cert="/etc/chirpstack/certs/ca.pem" | ||||||
|  |   ca_key="/etc/chirpstack/certs/ca-key.pem" | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | The official guide also recommends editing the `[integration.mqtt.client]` section, but you don't need to in this setup. **TODO learn about and explain [downlinks](https://www.chirpstack.io/docs/chirpstack/integrations/mqtt.html#scheduling-a-downlink)** | ||||||
|  | 
 | ||||||
|  | Finally, restart Chirpstack to use the updated configuration: | ||||||
|  | 
 | ||||||
|  | ```sh | ||||||
|  | sudo systemctl restart chirpstack | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Generate MQTT Server Certificate | ||||||
|  | 
 | ||||||
|  | Create a CSR for the MQTT server in the same place you created the CA, ensuring you replace the CN with your own site name: | ||||||
|  | 
 | ||||||
|  | ```sh | ||||||
|  | cat <<EOF > mqtt-server.json | ||||||
|  | { | ||||||
|  |     "CN": "your.site.name", | ||||||
|  |     "hosts": [ | ||||||
|  |         "your.site.name" | ||||||
|  |     ], | ||||||
|  |     "key": { | ||||||
|  |         "algo": "rsa", | ||||||
|  |         "size": 4096 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | EOF | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Generate the certificate: | ||||||
|  | 
 | ||||||
|  | ```sh | ||||||
|  | cfssl gencert -ca ca.pem -ca-key ca-key.pem -config ca-config.json -profile server mqtt-server.json | cfssljson -bare mqtt-server | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Three more files are generated: | ||||||
| 
 | 
 | ||||||
| - `mqtt-server.csr` | - `mqtt-server.csr` | ||||||
| - `mqtt-server.pem` | - `mqtt-server.pem` | ||||||
| - `mqtt-server-key.pem` | - `mqtt-server-key.pem` | ||||||
| 
 | 
 | ||||||
| Then you add the CA (with its key) to the ChirpStack config. Make sure to change ownership to `chirpstack` when copying certs to `/etc/chirpstack/certs`. | You can discard `mqtt-server.csr`. | ||||||
| 
 | 
 | ||||||
| Then create a folder for MQTT cert and copy files. | ## Configure MQTT Server | ||||||
| 
 | 
 | ||||||
| Set ownership and permission on the key: | You need to move the other two files, as well as the CA certificate, to a place where Mosquitto can access them: | ||||||
| 
 | 
 | ||||||
| ```sh | ```sh | ||||||
|  | mkdir -p /etc/mosquitto/certs | ||||||
|  | cp ca.pem /etc/mosquitto/certs | ||||||
|  | cp mqtt-server.pem /etc/mosquitto/certs | ||||||
|  | cp mqtt-server-key.pem /etc/mosquitto/certs | ||||||
| chown root:mosquitto /etc/mosquitto/certs/mqtt-server-key.pem | chown root:mosquitto /etc/mosquitto/certs/mqtt-server-key.pem | ||||||
| chmod 640 /etc/mosquitto/certs/mqtt-server-key.pem | chmod 640 /etc/mosquitto/certs/mqtt-server-key.pem | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Once set up, you can create a Gateway in ChirpStack and generate a TLS certificate. It is only shown after being created; clicking the TLS tab again later will not show the cert but will let you generate a new one. Certs don't seem to be stored anywhere. | Next, add a configuration for Mosquitto to use a local, non-TLS listener (for use by ChirpStack and for debugging) and an internet-accessible TLS listener that uses the certificate files you just copied: | ||||||
| 
 | 
 | ||||||
| Don't forget to allow `8883` in the firewall. | ```sh | ||||||
|  | per_listener_settings true | ||||||
| 
 | 
 | ||||||
| ## Gateway Bridge Config | listener 1883 127.0.0.1 | ||||||
|  | allow_anonymous true | ||||||
| 
 | 
 | ||||||
| Create `/etc/chirpstack-gateway-bridge/certs` folder and copy certs in. Make everything owned by `gatewaybridge`. Set permission to `640`. | listener 8883 0.0.0.0 | ||||||
|  | cafile /etc/mosquitto/certs/ca.pem | ||||||
|  | certfile /etc/mosquitto/certs/mqtt-server.pem | ||||||
|  | keyfile /etc/mosquitto/certs/mqtt-server-key.pem | ||||||
|  | allow_anonymous false | ||||||
|  | require_certificate true | ||||||
|  | use_identity_as_username true | ||||||
|  | acl_file /etc/mosquitto/acl | ||||||
|  | ``` | ||||||
| 
 | 
 | ||||||
| Modify the config, ref: <https://www.chirpstack.io/docs/chirpstack-gateway-bridge/configuration.html> | The `acl_file` setting references an access control list that doesn't exist yet but which will prevent gateways from reading/writing topics that don't belong to them. Create the file by running the following: | ||||||
| 
 | 
 | ||||||
| Don't forget to change `tcp` to `ssl` in the server list. | ```sh | ||||||
|  | cat <<EOF > /etc/mosquitto/acl | ||||||
|  | pattern readwrite +/gateway/%u/# | ||||||
|  | pattern readwrite application/%u/# | ||||||
|  | EOF | ||||||
|  | ``` | ||||||
| 
 | 
 | ||||||
| Check `journalctl` on both the bridge and Mosquitto to see that the connection is established. | With the configuration files in place, restart Mosquitto: | ||||||
| 
 | 
 | ||||||
| Be sure to set the Gateway ID in both the `chirpstack-gateway-bridge` and `packet-forwarder` configs (though this doesn't seem to matter? Need to experiment). Also be sure the UDP port matches between the two. | ```sh | ||||||
|  | sudo systemctl restart mosquitto | ||||||
|  | ``` | ||||||
| 
 | 
 | ||||||
| ## Troubleshooting | Finally, if your server is running `ufw`, allow external traffic in to the port you configured Mosquitto to use for TLS: | ||||||
| 
 | 
 | ||||||
| Install `mosquitto-clients` on the Gateway. | ```sh | ||||||
|  | sudo ufw allow 8883 | ||||||
|  | ``` | ||||||
| 
 | 
 | ||||||
| Send a message to the `test` topic: | ## Testing/Troubleshooting | ||||||
|  | 
 | ||||||
|  | Once set up, you can create a Gateway in ChirpStack and generate a TLS certificate. The certificate is only shown after being created; clicking the TLS tab again later will not show the cert but will let you generate another one. ChirpStack does not store these generated certs anywhere **(TODO confirm)**. **TODO add screenshots** | ||||||
|  | 
 | ||||||
|  | Save the certs as `ca.crt`, `cert.crt`, and `cert.key` onto a test machine such as your local computer or a different cloud instance. | ||||||
|  | 
 | ||||||
|  | Install `mosquitto-clients` onto the test machine. | ||||||
|  | 
 | ||||||
|  | On the ChirpStack server, open a terminal window and subscribe to all messages: | ||||||
|  | 
 | ||||||
|  | ```sh | ||||||
|  | mosquitto_sub  -h localhost -t "#" -v -d | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Keep the terminal open, and on the test machine, send a message to the `us915_1/gateway/<GATEWAY_ID>/test` topic, substituting `<GATEWAY_ID>` accordingly: | ||||||
| 
 | 
 | ||||||
| ```sh | ```sh | ||||||
| mosquitto_pub \ | mosquitto_pub \ | ||||||
|   -h chirpstack.roeber.dev \ |   -h your.site.name \ | ||||||
|   -p 8883 \ |   -p 8883 \ | ||||||
|   --cafile /etc/chirpstack-gateway-bridge/certs/ca.crt \ |   --cafile ca.crt \ | ||||||
|   --cert /etc/chirpstack-gateway-bridge/certs/cert.crt \ |   --cert cert.crt \ | ||||||
|   --key /etc/chirpstack-gateway-bridge/certs/cert.key \ |   --key cert.key \ | ||||||
|   -t "test" \ |   -t "us915_1/gateway/<GATEWAY_ID>/test" \ | ||||||
|   -d \ |   -d \ | ||||||
|   -m "hello" |   -m "hello" | ||||||
| ``` | ``` | ||||||
|  | 
 | ||||||
|  | In the terminal window on the ChirpStack server, you should see a message show up. **TODO add troubleshooting procedures and other expected output** | ||||||
|  | |||||||
| @ -74,9 +74,8 @@ Experience with the following is recommended but not required if you are able to | |||||||
|   - Rent compute from a cloud vendor |   - Rent compute from a cloud vendor | ||||||
|   - Secure shell (SSH) |   - Secure shell (SSH) | ||||||
|   - Caddy web server |   - Caddy web server | ||||||
|   - TLS certificate generation |   - Transport Layer Security (TLS) | ||||||
|     - Let's Encrypt |     - Certificates and secret keys | ||||||
|       - DNS-01 protocol |  | ||||||
|     - Self-generated certificate authority |     - Self-generated certificate authority | ||||||
|       - [`cfssl`](https://github.com/cloudflare/cfssl) |       - [`cfssl`](https://github.com/cloudflare/cfssl) | ||||||
|   - Mosquitto MQTT |   - Mosquitto MQTT | ||||||
|  | |||||||
| @ -58,4 +58,16 @@ Add/change some values: | |||||||
| ```toml | ```toml | ||||||
| event_topic_template="us915_1/gateway/{{ .GatewayID }}/event/{{ .EventType }}" | event_topic_template="us915_1/gateway/{{ .GatewayID }}/event/{{ .EventType }}" | ||||||
| command_topic_template="us915_1/gateway/{{ .GatewayID }}/command/#" | command_topic_template="us915_1/gateway/{{ .GatewayID }}/command/#" | ||||||
| ```` | ``` | ||||||
|  | 
 | ||||||
|  | ## Gateway Bridge Config | ||||||
|  | 
 | ||||||
|  | Create `/etc/chirpstack-gateway-bridge/certs` folder and copy certs in. Make everything owned by `gatewaybridge`. Set permission to `640`. | ||||||
|  | 
 | ||||||
|  | Modify the config, ref: <https://www.chirpstack.io/docs/chirpstack-gateway-bridge/configuration.html> | ||||||
|  | 
 | ||||||
|  | Don't forget to change `tcp` to `ssl` in the server list. | ||||||
|  | 
 | ||||||
|  | Check `journalctl` on both the bridge and Mosquitto to see that the connection is established. | ||||||
|  | 
 | ||||||
|  | Be sure to set the Gateway ID in both the `chirpstack-gateway-bridge` and `packet-forwarder` configs (though this doesn't seem to matter? Need to experiment). Also be sure the UDP port matches between the two. | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user