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