From d325afc65337f44cf54efd19a21c7fbd4b6cc59b Mon Sep 17 00:00:00 2001 From: nyagamunene Date: Tue, 21 May 2024 02:07:34 +0300 Subject: [PATCH 1/7] Updated mqtt and http Signed-off-by: nyagamunene --- docs/messaging.md | 66 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/docs/messaging.md b/docs/messaging.md index a1e10ef9..bd738d0b 100644 --- a/docs/messaging.md +++ b/docs/messaging.md @@ -1,11 +1,20 @@ # Messaging -Once a channel is provisioned and thing is connected to it, it can start to publish messages on the channel. The following sections will provide an example of message publishing for each of the supported protocols. +Once a channel is provisioned and thing is connected to it, it can start to publish messages on the channel. The following sections will provide an example of message publishing for each of the supported protocols, with the examples being shown without TLS, with TLS, and with mTLS. ## HTTP -To publish message over channel, thing should send following request: +The following environmental variables are used to enable or disable HTTP with TLS and MTLS: `MG_HTTP_ADAPTER_CERT_FILE`,`MG_HTTP_ADAPTER_KEY_FILE`, `MG_HTTP_ADAPTER_SERVER_CA_FILE`, `MG_HTTP_ADAPTER_CLIENT_CA_FILE`, `MG_HTTP_ADAPTER_CERT_VERIFICATION_METHODS`, `MG_HTTP_ADAPTER_OCSP_RESPONDER_URL`. These can be located in the `docker/.env` file. +### Without TLS +To use magistala http without TLS, comment out all of the listed environment variables provided above. To publish message over channel, thing should send following request: +```bash +curl -s -S -i -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " https://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' +``` + +### With TLS + +To use magistala http with TLS, uncomment the following environment variables`MG_HTTP_ADAPTER_CERT_FILE`,`MG_HTTP_ADAPTER_KEY_FILE` and comment out the rest.To publish message over channel, thing should send following request: ```bash curl -s -S -i --cacert docker/ssl/certs/ca.crt -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " https://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' ``` @@ -17,19 +26,50 @@ For more information about the HTTP messaging service API, please check out the ## MQTT To send and receive messages over MQTT you could use [Mosquitto tools][mosquitto], or [Paho][paho] if you want to use MQTT over WebSocket. +The following environmental variables are used to enable or disable MQTT with TLS and MTLS: `MG_MQTT_ADAPTER_CERT_FILE`, `MG_MQTT_ADAPTER_KEY_FILE`, `MG_MQTT_ADAPTER_SERVER_CA_FILE`, `MG_MQTT_ADAPTER_CLIENT_CA_FILE`, `MG_MQTT_ADAPTER_CERT_VERIFICATION_METHODS`, `MG_MQTT_ADAPTER_OCSP_RESPONDER_URL`. + +### Without TLS + +To use magistala mqtt without TLS, comment all of the listed environment variables provided above. To publish message over channel, thing should call following command: + +```bash +mosquitto_pub --id-prefix magistrala -u -P -t channels//messages -h localhost -m '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' +``` + +To subscribe to channel, thing should call following command: + +```bash +mosquitto_sub --id-prefix magistrala -u -P -t channels//messages -h localhost +``` -To publish message over channel, thing should call following command: +### With TLS + +To use magistala mqtt with TLS, uncomment the following environment variables: `MG_MQTT_ADAPTER_CERT_FILE`, `MG_MQTT_ADAPTER_KEY_FILE` and comment out the rest. To publish message over channel, thing should call following command: ```bash -mosquitto_pub -u -P -t channels//messages -h localhost -m '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' +mosquitto_pub --id-prefix magistrala --cafile docker/ssl/certs/ca.crt -u -P -t channels//messages -h localhost -m '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' ``` To subscribe to channel, thing should call following command: ```bash -mosquitto_sub -u -P -t channels//messages -h localhost +mosquitto_sub --id-prefix magistrala --cafile docker/ssl/certs/ca.crt -u -P -t channels//messages -h localhost +``` + +### With MTLS +Uncomment out all of the above mentioned environment variables to enable MTLS certificates. Here is an example of how you would publish: +```bash +mosquitto_pub --id-prefix magistrala -u -P -t channels//messages -h localhost -m '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' --cafile docker/ssl/certs/ca.crt --cert docker/ssl/certs/thing.crt --key docker/ssl/certs/thing.key + +``` +>The `thing.crt` and `thing.crt` can be genarated by running `make thing_cert` + +Here is how you would subscribe: +```bash +mosquitto_sub --id-prefix magistrala -u -P -t channels//messages -h localhost --cafile docker/ssl/certs/ca.crt --cert docker/ssl/certs/thing.crt --key docker/ssl/certs/thing.key ``` + If you want to use standard topic such as `channels//messages` with SenML content type (JSON or CBOR), you should use following topic `channels//messages`. If you are using TLS to secure MQTT connection, add `--cafile docker/ssl/certs/ca.crt` @@ -185,6 +225,8 @@ i.e. connection URL should be `ws:///mqtt`. For quick testing you can use [HiveMQ UI tool][websocket-client]. +The following environmental variables are used to enable or disable MQTT-over-WS with TLS and MTLS: `MG_MQTT_ADAPTER_WS_CERT_FILE`,`MG_MQTT_ADAPTER_WS_KEY_FILE`, `MG_MQTT_ADAPTER_WS_SERVER_CA_FILE`, `MG_MQTT_ADAPTER_WS_CLIENT_CA_FILE`,`MG_MQTT_ADAPTER_WS_CERT_VERIFICATION_METHODS`, `MG_MQTT_ADAPTER_WS_OCSP_RESPONDER_URL`. + Here is an example of a browser application connecting to Magistrala server and sending and receiving messages over WebSocket using MQTT.js library: ```javascript @@ -245,6 +287,20 @@ client = new Paho.MQTT.Client(loc.hostname, Number(loc.port), "clientId"); // Connect the client client.connect({ onSuccess: onConnect }); ``` +## Mproxy + +### Without TLS +Comment out all of the above mentioned environment variables to disable TLS certificates. +Here is an example of how you would publish and subscribe: + +### With TLS +Uncomment out the following environment variables: `MG_MQTT_ADAPTER_WS_CERT_FILE`,`MG_MQTT_ADAPTER_WS_KEY_FILE` and comment out the rest to enable TLS certificates. +Here is an example of how you would publish and subscribe: + +### With MTLS +Uncomment out all of the above mentioned environment variables to enable MTLS certificates. +Here is an example of how you would publish and subscribe: + ## Subtopics From 9cd7822ec22994f00ac462edbee625d4823d1897 Mon Sep 17 00:00:00 2001 From: nyagamunene Date: Tue, 21 May 2024 02:15:46 +0300 Subject: [PATCH 2/7] Updated mqtt and http Signed-off-by: nyagamunene --- docs/messaging.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/messaging.md b/docs/messaging.md index bd738d0b..41663e55 100644 --- a/docs/messaging.md +++ b/docs/messaging.md @@ -19,6 +19,12 @@ To use magistala http with TLS, uncomment the following environment variables`MG curl -s -S -i --cacert docker/ssl/certs/ca.crt -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " https://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' ``` +### With MTLS +To use magistala http with MTLS, uncomment all of the environment variables listed above. To publish message over channel, thing should send following request: +```bash +curl -s -S -i --cacert docker/ssl/certs/ca.crt --cert docker/ssl/certs/thing.crt --key docker/ssl/certs/thing.key -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " https://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' +``` + Note that if you're going to use senml message format, you should always send messages as an array. For more information about the HTTP messaging service API, please check out the [API documentation][http-api]. From 196d9c64ac7810cfe4766c408473a6b243f086ae Mon Sep 17 00:00:00 2001 From: nyagamunene Date: Tue, 21 May 2024 12:31:32 +0300 Subject: [PATCH 3/7] Updated mqtt over ws Signed-off-by: nyagamunene --- docs/messaging.md | 356 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 344 insertions(+), 12 deletions(-) diff --git a/docs/messaging.md b/docs/messaging.md index 41663e55..3b844f4e 100644 --- a/docs/messaging.md +++ b/docs/messaging.md @@ -4,10 +4,12 @@ Once a channel is provisioned and thing is connected to it, it can start to publ ## HTTP -The following environmental variables are used to enable or disable HTTP with TLS and MTLS: `MG_HTTP_ADAPTER_CERT_FILE`,`MG_HTTP_ADAPTER_KEY_FILE`, `MG_HTTP_ADAPTER_SERVER_CA_FILE`, `MG_HTTP_ADAPTER_CLIENT_CA_FILE`, `MG_HTTP_ADAPTER_CERT_VERIFICATION_METHODS`, `MG_HTTP_ADAPTER_OCSP_RESPONDER_URL`. These can be located in the `docker/.env` file. +The following environmental variables are used to enable or disable HTTP with TLS and MTLS: `MG_HTTP_ADAPTER_CERT_FILE`,`MG_HTTP_ADAPTER_KEY_FILE`, `MG_HTTP_ADAPTER_SERVER_CA_FILE`, `MG_HTTP_ADAPTER_CLIENT_CA_FILE`. These can be located in the `docker/.env` file. + ### Without TLS To use magistala http without TLS, comment out all of the listed environment variables provided above. To publish message over channel, thing should send following request: + ```bash curl -s -S -i -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " https://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' ``` @@ -15,12 +17,15 @@ curl -s -S -i -X POST -H "Content-Type: application/senml+json" -H "Authorizatio ### With TLS To use magistala http with TLS, uncomment the following environment variables`MG_HTTP_ADAPTER_CERT_FILE`,`MG_HTTP_ADAPTER_KEY_FILE` and comment out the rest.To publish message over channel, thing should send following request: + ```bash curl -s -S -i --cacert docker/ssl/certs/ca.crt -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " https://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' ``` ### With MTLS + To use magistala http with MTLS, uncomment all of the environment variables listed above. To publish message over channel, thing should send following request: + ```bash curl -s -S -i --cacert docker/ssl/certs/ca.crt --cert docker/ssl/certs/thing.crt --key docker/ssl/certs/thing.key -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " https://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' ``` @@ -32,7 +37,7 @@ For more information about the HTTP messaging service API, please check out the ## MQTT To send and receive messages over MQTT you could use [Mosquitto tools][mosquitto], or [Paho][paho] if you want to use MQTT over WebSocket. -The following environmental variables are used to enable or disable MQTT with TLS and MTLS: `MG_MQTT_ADAPTER_CERT_FILE`, `MG_MQTT_ADAPTER_KEY_FILE`, `MG_MQTT_ADAPTER_SERVER_CA_FILE`, `MG_MQTT_ADAPTER_CLIENT_CA_FILE`, `MG_MQTT_ADAPTER_CERT_VERIFICATION_METHODS`, `MG_MQTT_ADAPTER_OCSP_RESPONDER_URL`. +The following environmental variables are used to enable or disable MQTT with TLS and MTLS: `MG_MQTT_ADAPTER_CERT_FILE`, `MG_MQTT_ADAPTER_KEY_FILE`, `MG_MQTT_ADAPTER_SERVER_CA_FILE`, `MG_MQTT_ADAPTER_CLIENT_CA_FILE`. ### Without TLS @@ -53,29 +58,32 @@ mosquitto_sub --id-prefix magistrala -u -P -t channels To use magistala mqtt with TLS, uncomment the following environment variables: `MG_MQTT_ADAPTER_CERT_FILE`, `MG_MQTT_ADAPTER_KEY_FILE` and comment out the rest. To publish message over channel, thing should call following command: ```bash -mosquitto_pub --id-prefix magistrala --cafile docker/ssl/certs/ca.crt -u -P -t channels//messages -h localhost -m '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' +mosquitto_pub --id-prefix magistrala --cafile docker/ssl/certs/ca.crt -u -P -t channels//messages -h localhost -p 1883 -m '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' ``` To subscribe to channel, thing should call following command: ```bash -mosquitto_sub --id-prefix magistrala --cafile docker/ssl/certs/ca.crt -u -P -t channels//messages -h localhost +mosquitto_sub --id-prefix magistrala --cafile docker/ssl/certs/ca.crt -u -P -t channels//messages -h localhost -p 1883 ``` ### With MTLS + Uncomment out all of the above mentioned environment variables to enable MTLS certificates. Here is an example of how you would publish: + ```bash -mosquitto_pub --id-prefix magistrala -u -P -t channels//messages -h localhost -m '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' --cafile docker/ssl/certs/ca.crt --cert docker/ssl/certs/thing.crt --key docker/ssl/certs/thing.key +mosquitto_pub --id-prefix magistrala -u -P -t channels//messages -h localhost -p 1883 -m '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' --cafile docker/ssl/certs/ca.crt --cert docker/ssl/certs/thing.crt --key docker/ssl/certs/thing.key ``` ->The `thing.crt` and `thing.crt` can be genarated by running `make thing_cert` + +> The `thing.crt` and `thing.crt` can be genarated by running `make thing_cert` Here is how you would subscribe: + ```bash -mosquitto_sub --id-prefix magistrala -u -P -t channels//messages -h localhost --cafile docker/ssl/certs/ca.crt --cert docker/ssl/certs/thing.crt --key docker/ssl/certs/thing.key +mosquitto_sub --id-prefix magistrala -u -P -t channels//messages -h localhost -p 1883 --cafile docker/ssl/certs/ca.crt --cert docker/ssl/certs/thing.crt --key docker/ssl/certs/thing.key ``` - If you want to use standard topic such as `channels//messages` with SenML content type (JSON or CBOR), you should use following topic `channels//messages`. If you are using TLS to secure MQTT connection, add `--cafile docker/ssl/certs/ca.crt` @@ -231,7 +239,7 @@ i.e. connection URL should be `ws:///mqtt`. For quick testing you can use [HiveMQ UI tool][websocket-client]. -The following environmental variables are used to enable or disable MQTT-over-WS with TLS and MTLS: `MG_MQTT_ADAPTER_WS_CERT_FILE`,`MG_MQTT_ADAPTER_WS_KEY_FILE`, `MG_MQTT_ADAPTER_WS_SERVER_CA_FILE`, `MG_MQTT_ADAPTER_WS_CLIENT_CA_FILE`,`MG_MQTT_ADAPTER_WS_CERT_VERIFICATION_METHODS`, `MG_MQTT_ADAPTER_WS_OCSP_RESPONDER_URL`. +The following environmental variables are used to enable or disable MQTT-over-WS with TLS and MTLS: `MG_MQTT_ADAPTER_WS_CERT_FILE`,`MG_MQTT_ADAPTER_WS_KEY_FILE`, `MG_MQTT_ADAPTER_WS_SERVER_CA_FILE`, `MG_MQTT_ADAPTER_WS_CLIENT_CA_FILE`. Here is an example of a browser application connecting to Magistrala server and sending and receiving messages over WebSocket using MQTT.js library: @@ -293,20 +301,344 @@ client = new Paho.MQTT.Client(loc.hostname, Number(loc.port), "clientId"); // Connect the client client.connect({ onSuccess: onConnect }); ``` + ## Mproxy ### Without TLS + Comment out all of the above mentioned environment variables to disable TLS certificates. -Here is an example of how you would publish and subscribe: +Here is an example of how you would publish: + +```go +package main + +import ( + "crypto/tls" + "fmt" + + mqtt "github.com/eclipse/paho.mqtt.golang" +) + +var ( + brokerAddress = "ws://localhost/mqtt" + thingID = "1255616f-d9ff-4fb4-b2d9-f72a7c99438e" + thingSecret = "91f6e004-9f9e-4f95-9b72-a04befbdf584" + channelID = "17c1bb45-7dc7-44eb-a2b4-57a16e4bc05b" + topic = "channels/" + channelID + "/messages" +) + +func main() { + opts := mqtt.NewClientOptions() + opts.AddBroker(brokerAddress) + opts.SetClientID(thingID) + opts.SetUsername(thingID) + opts.SetPassword(thingSecret) + + client, err := Connect(opts, nil) + if err != nil { + panic(err) + } + + publish(client) + client.Disconnect(250) +} + +func Connect(opts *mqtt.ClientOptions, tlsCfg *tls.Config) (mqtt.Client, error) { + fmt.Println("Connecting to broker") + if tlsCfg != nil { + opts.SetTLSConfig(tlsCfg) + } + + client := mqtt.NewClient(opts) + + if token := client.Connect(); token.Wait() && token.Error() != nil { + fmt.Println("Failed to connect to broker") + return client, token.Error() + } + return client, nil +} + +func publish(client mqtt.Client) { + fmt.Println("Publishing message") + text := "MQTT over WS Demo" + token := client.Publish(topic, 0, false, text) + token.Wait() + if token.Error() != nil { + fmt.Printf("Failed to publish to topic") + panic(token.Error()) + } +} + +``` ### With TLS + Uncomment out the following environment variables: `MG_MQTT_ADAPTER_WS_CERT_FILE`,`MG_MQTT_ADAPTER_WS_KEY_FILE` and comment out the rest to enable TLS certificates. -Here is an example of how you would publish and subscribe: +Here is an example of how you would publish: + +```go +package main + +import ( + "crypto/tls" + "crypto/x509" + "errors" + "fmt" + "os" + + mqtt "github.com/eclipse/paho.mqtt.golang" +) + +var ( + brokerAddress = "wss://localhost/mqtt" + thingID = "1255616f-d9ff-4fb4-b2d9-f72a7c99438e" + thingSecret = "91f6e004-9f9e-4f95-9b72-a04befbdf584" + channelID = "17c1bb45-7dc7-44eb-a2b4-57a16e4bc05b" + topic = "channels/" + channelID + "/messages" + certFile = "" + keyFile = "" + serverCAFile = "docker/ssl/certs/ca.crt" + clientCAFile = "" + errLoadCerts = errors.New("failed to load certificates") + errLoadServerCA = errors.New("failed to load Server CA") + errLoadClientCA = errors.New("failed to load Client CA") + errAppendCA = errors.New("failed to append root ca tls.Config") +) + +func main() { + opts := mqtt.NewClientOptions() + opts.AddBroker(brokerAddress) + opts.SetClientID(thingID) + opts.SetUsername(thingID) + opts.SetPassword(thingSecret) + + tlsCfg, err := LoadTLS(certFile, keyFile, serverCAFile, clientCAFile) + if err != nil { + panic(err) + } + + client, err := Connect(opts, tlsCfg) + if err != nil { + panic(err) + } + + publish(client) + client.Disconnect(250) +} + +func Connect(opts *mqtt.ClientOptions, tlsCfg *tls.Config) (mqtt.Client, error) { + if tlsCfg != nil { + opts.SetTLSConfig(tlsCfg) + } + + client := mqtt.NewClient(opts) + + if token := client.Connect(); token.Wait() && token.Error() != nil { + fmt.Println("Failed to connect to broker") + return client, token.Error() + } + return client, nil +} + +func publish(client mqtt.Client) { + text := "MQTT over WS Demo" + token := client.Publish(topic, 0, false, text) + token.Wait() + if token.Error() != nil { + fmt.Printf("Failed to publish to topic") + panic(token.Error()) + } +} + +// Load return a TLS configuration that can be used in TLS servers +func LoadTLS(certFile, keyFile, serverCAFile, clientCAFile string) (*tls.Config, error) { + tlsConfig := &tls.Config{} + + // Load Certs and Key if available + if certFile != "" || keyFile != "" { + certificate, err := tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + return nil, errors.Join(errLoadCerts, err) + } + tlsConfig = &tls.Config{ + Certificates: []tls.Certificate{certificate}, + } + tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert + } + + // Load Server CA if available + rootCA, err := loadCertFile(serverCAFile) + if err != nil { + return nil, errors.Join(errLoadServerCA, err) + } + if len(rootCA) > 0 { + if tlsConfig.RootCAs == nil { + tlsConfig.RootCAs = x509.NewCertPool() + } + if !tlsConfig.RootCAs.AppendCertsFromPEM(rootCA) { + return nil, errAppendCA + } + } + + // Load Client CA if available + clientCA, err := loadCertFile(clientCAFile) + if err != nil { + return nil, errors.Join(errLoadClientCA, err) + } + if len(clientCA) > 0 { + if tlsConfig.ClientCAs == nil { + tlsConfig.ClientCAs = x509.NewCertPool() + } + if !tlsConfig.ClientCAs.AppendCertsFromPEM(clientCA) { + return nil, errAppendCA + } + } + return tlsConfig, nil +} + +func loadCertFile(certFile string) ([]byte, error) { + if certFile != "" { + return os.ReadFile(certFile) + } + return []byte{}, nil +} + +``` ### With MTLS + Uncomment out all of the above mentioned environment variables to enable MTLS certificates. -Here is an example of how you would publish and subscribe: +Here is an example of how you would publish: + +```go +package main + +import ( + "crypto/tls" + "crypto/x509" + "errors" + "fmt" + "os" + + mqtt "github.com/eclipse/paho.mqtt.golang" +) + +var ( + brokerAddress = "wss://localhost/mqtt" + thingID = "1255616f-d9ff-4fb4-b2d9-f72a7c99438e" + thingSecret = "91f6e004-9f9e-4f95-9b72-a04befbdf584" + channelID = "17c1bb45-7dc7-44eb-a2b4-57a16e4bc05b" + topic = "channels/" + channelID + "/messages" + certFile = "ssl/certs/thing.crt" + keyFile = "ssl/certs/thing.key" + serverCAFile = "ssl/certs/ca.crt" + clientCAFile = "" + errLoadCerts = errors.New("failed to load certificates") + errLoadServerCA = errors.New("failed to load Server CA") + errLoadClientCA = errors.New("failed to load Client CA") + errAppendCA = errors.New("failed to append root ca tls.Config") +) + +func main() { + opts := mqtt.NewClientOptions() + opts.AddBroker(brokerAddress) + opts.SetClientID(thingID) + opts.SetUsername(thingID) + opts.SetPassword(thingSecret) + + tlsCfg, err := LoadTLS(certFile, keyFile, serverCAFile, clientCAFile) + if err != nil { + panic(err) + } + + client, err := Connect(opts, tlsCfg) + if err != nil { + panic(err) + } + + publish(client) + client.Disconnect(250) +} + +func Connect(opts *mqtt.ClientOptions, tlsCfg *tls.Config) (mqtt.Client, error) { + if tlsCfg != nil { + opts.SetTLSConfig(tlsCfg) + } + + client := mqtt.NewClient(opts) + + if token := client.Connect(); token.Wait() && token.Error() != nil { + fmt.Println("Failed to connect to broker") + return client, token.Error() + } + return client, nil +} + +func publish(client mqtt.Client) { + text := "MQTT over WS Demo" + token := client.Publish(topic, 0, false, text) + token.Wait() + if token.Error() != nil { + fmt.Printf("Failed to publish to topic") + panic(token.Error()) + } +} + +// Load return a TLS configuration that can be used in TLS servers +func LoadTLS(certFile, keyFile, serverCAFile, clientCAFile string) (*tls.Config, error) { + tlsConfig := &tls.Config{} + + // Load Certs and Key if available + if certFile != "" || keyFile != "" { + certificate, err := tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + return nil, errors.Join(errLoadCerts, err) + } + tlsConfig = &tls.Config{ + Certificates: []tls.Certificate{certificate}, + } + tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert + } + // Load Server CA if available + rootCA, err := loadCertFile(serverCAFile) + if err != nil { + return nil, errors.Join(errLoadServerCA, err) + } + if len(rootCA) > 0 { + if tlsConfig.RootCAs == nil { + tlsConfig.RootCAs = x509.NewCertPool() + } + if !tlsConfig.RootCAs.AppendCertsFromPEM(rootCA) { + return nil, errAppendCA + } + } + + // Load Client CA if available + clientCA, err := loadCertFile(clientCAFile) + if err != nil { + return nil, errors.Join(errLoadClientCA, err) + } + if len(clientCA) > 0 { + if tlsConfig.ClientCAs == nil { + tlsConfig.ClientCAs = x509.NewCertPool() + } + if !tlsConfig.ClientCAs.AppendCertsFromPEM(clientCA) { + return nil, errAppendCA + } + } + return tlsConfig, nil +} + +func loadCertFile(certFile string) ([]byte, error) { + if certFile != "" { + return os.ReadFile(certFile) + } + return []byte{}, nil +} + + +``` ## Subtopics From a26874f315c5120f0200845fe441aa40b8d88691 Mon Sep 17 00:00:00 2001 From: nyagamunene Date: Tue, 21 May 2024 13:00:01 +0300 Subject: [PATCH 4/7] Update http command Signed-off-by: nyagamunene --- docs/messaging.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/messaging.md b/docs/messaging.md index 3b844f4e..4a4e688f 100644 --- a/docs/messaging.md +++ b/docs/messaging.md @@ -11,7 +11,7 @@ The following environmental variables are used to enable or disable HTTP with TL To use magistala http without TLS, comment out all of the listed environment variables provided above. To publish message over channel, thing should send following request: ```bash -curl -s -S -i -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " https://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' +curl -s -S -i -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " http://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' ``` ### With TLS @@ -302,7 +302,7 @@ client = new Paho.MQTT.Client(loc.hostname, Number(loc.port), "clientId"); client.connect({ onSuccess: onConnect }); ``` -## Mproxy +## Examples using Eclipse Paho lib in Go. ### Without TLS From 387db81277c00fa50e023183e3d9ff5da16aca32 Mon Sep 17 00:00:00 2001 From: nyagamunene Date: Tue, 21 May 2024 13:02:59 +0300 Subject: [PATCH 5/7] changed http casing Signed-off-by: nyagamunene --- docs/messaging.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/messaging.md b/docs/messaging.md index 4a4e688f..14725f09 100644 --- a/docs/messaging.md +++ b/docs/messaging.md @@ -8,7 +8,7 @@ The following environmental variables are used to enable or disable HTTP with TL ### Without TLS -To use magistala http without TLS, comment out all of the listed environment variables provided above. To publish message over channel, thing should send following request: +To use magistala HTTP without TLS, comment out all of the listed environment variables provided above. To publish message over channel, thing should send following request: ```bash curl -s -S -i -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " http://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' @@ -16,7 +16,7 @@ curl -s -S -i -X POST -H "Content-Type: application/senml+json" -H "Authorizatio ### With TLS -To use magistala http with TLS, uncomment the following environment variables`MG_HTTP_ADAPTER_CERT_FILE`,`MG_HTTP_ADAPTER_KEY_FILE` and comment out the rest.To publish message over channel, thing should send following request: +To use magistala HTTP with TLS, uncomment the following environment variables`MG_HTTP_ADAPTER_CERT_FILE`,`MG_HTTP_ADAPTER_KEY_FILE` and comment out the rest.To publish message over channel, thing should send following request: ```bash curl -s -S -i --cacert docker/ssl/certs/ca.crt -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " https://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' @@ -24,7 +24,7 @@ curl -s -S -i --cacert docker/ssl/certs/ca.crt -X POST -H "Content-Type: applica ### With MTLS -To use magistala http with MTLS, uncomment all of the environment variables listed above. To publish message over channel, thing should send following request: +To use magistala HTTP with MTLS, uncomment all of the environment variables listed above. To publish message over channel, thing should send following request: ```bash curl -s -S -i --cacert docker/ssl/certs/ca.crt --cert docker/ssl/certs/thing.crt --key docker/ssl/certs/thing.key -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " https://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' From 7ac3954d39fe02ab084ae56391dcf5bdb0f0e867 Mon Sep 17 00:00:00 2001 From: nyagamunene Date: Tue, 21 May 2024 15:03:15 +0300 Subject: [PATCH 6/7] Added mtls certs generation Signed-off-by: nyagamunene --- docs/messaging.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/messaging.md b/docs/messaging.md index 14725f09..eb46158d 100644 --- a/docs/messaging.md +++ b/docs/messaging.md @@ -1,6 +1,7 @@ # Messaging Once a channel is provisioned and thing is connected to it, it can start to publish messages on the channel. The following sections will provide an example of message publishing for each of the supported protocols, with the examples being shown without TLS, with TLS, and with mTLS. +> While using MTLS the `thing.crt` and `thing.crt` can be genarated by running `make thing_cert` while in the `docker/ssl` folder ## HTTP @@ -76,7 +77,7 @@ mosquitto_pub --id-prefix magistrala -u -P -t channels ``` -> The `thing.crt` and `thing.crt` can be genarated by running `make thing_cert` + Here is how you would subscribe: From e2016ab1f5aae4ee1781327a9e9931ac05e313a3 Mon Sep 17 00:00:00 2001 From: nyagamunene Date: Tue, 28 May 2024 14:36:52 +0300 Subject: [PATCH 7/7] Update messaging with examples Signed-off-by: nyagamunene --- docs/authorization.md | 3 +- docs/messaging.md | 161 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 133 insertions(+), 31 deletions(-) diff --git a/docs/authorization.md b/docs/authorization.md index 39a90943..18f2fa9b 100644 --- a/docs/authorization.md +++ b/docs/authorization.md @@ -344,8 +344,7 @@ Users with viewer relations have access to view all entities (things, channels, ### Domain Member -Users with member relations could not view and no access to entities (things, channels, groups) created by others within the domain. Members are also allowed to create their own entities and can view and update the ones they have created. -Domain members will not have access by default to any of the entities in the Domain, access shall be granted for specific entities by the domain administrator or individual entity administrator. +Users with ```member``` relation in a domain do not have default access to view or interact with entities (such as things, channels, or groups) created by others in the same domain. However, these members are permitted to create their own entities and have full access to view and update those they have personally created. Despite this, ```members``` do not automatically gain access to all entities within the domain. Instead, access to specific entities must be explicitly granted by either the domain administrator or the individual administrator of the entity in question. **Example:** **user_4 , user_5, user_6, user_7, user_8, user_9** is **member** of **domain_1**. **These member relation users can able to create & manage new things, channels & groups in the domain. They can have access to the entities to which they have a relation in the domain. They could not view and manage other entities to which they don't have any relation in domain**. diff --git a/docs/messaging.md b/docs/messaging.md index eb46158d..e94cba1f 100644 --- a/docs/messaging.md +++ b/docs/messaging.md @@ -5,32 +5,67 @@ Once a channel is provisioned and thing is connected to it, it can start to publ ## HTTP -The following environmental variables are used to enable or disable HTTP with TLS and MTLS: `MG_HTTP_ADAPTER_CERT_FILE`,`MG_HTTP_ADAPTER_KEY_FILE`, `MG_HTTP_ADAPTER_SERVER_CA_FILE`, `MG_HTTP_ADAPTER_CLIENT_CA_FILE`. These can be located in the `docker/.env` file. +The following environmental variables are used to enable or disable HTTP with TLS and MTLS: `MG_HTTP_ADAPTER_CERT_FILE`,`MG_HTTP_ADAPTER_KEY_FILE`, `MG_HTTP_ADAPTER_SERVER_CA_FILE`, `MG_HTTP_ADAPTER_CLIENT_CA_FILE`. These can be located in the `docker/.env` file. By default magistrala is set to run without TLS or MTLS enabled. ### Without TLS -To use magistala HTTP without TLS, comment out all of the listed environment variables provided above. To publish message over channel, thing should send following request: +To publish message over channel, thing should send following request: ```bash curl -s -S -i -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " http://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' ``` +The response body should look something like: +```bash +HTTP/1.1 202 Accepted +Server: nginx/1.25.4 +Date: Wed, 22 May 2024 16:59:26 GMT +Content-Type: application/json +Content-Length: 0 +Connection: keep-alive +``` ### With TLS -To use magistala HTTP with TLS, uncomment the following environment variables`MG_HTTP_ADAPTER_CERT_FILE`,`MG_HTTP_ADAPTER_KEY_FILE` and comment out the rest.To publish message over channel, thing should send following request: +To use magistala HTTP with TLS, set the following environment variables as follows: +```bash +MG_HTTP_ADAPTER_CERT_FILE=./ssl/certs/magistrala-server.crt +MG_HTTP_ADAPTER_KEY_FILE=./ssl/certs/magistrala-server.key +``` +Then update the line `proxy_pass http://http-adapter:${MG_HTTP_ADAPTER_PORT}/;` to `proxy_pass https://http-adapter:${MG_HTTP_ADAPTER_PORT}/;` in `docker/nginx/nginx-key.conf`.Then restart magistrala. +To publish message over channel, thing should send following request: ```bash curl -s -S -i --cacert docker/ssl/certs/ca.crt -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " https://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' ``` +The response body should look something like: +```bash +HTTP/2 202 +server: nginx/1.25.4 +date: Tue, 28 May 2024 09:10:22 GMT +content-type: application/json +content-length: 0 +``` ### With MTLS -To use magistala HTTP with MTLS, uncomment all of the environment variables listed above. To publish message over channel, thing should send following request: +To use magistala HTTP with MTLS, set the following environment variables as follows and restart magistrala: +```bash +MG_HTTP_ADAPTER_CERT_FILE=./ssl/certs/magistrala-server.crt +MG_HTTP_ADAPTER_KEY_FILE=./ssl/certs/magistrala-server.key +MG_HTTP_ADAPTER_SERVER_CA_FILE=./ssl/certs/ca.crt +MG_HTTP_ADAPTER_CLIENT_CA_FILE=./ssl/certs/ca.crt +``` +To publish message over channel, thing should send following request: ```bash curl -s -S -i --cacert docker/ssl/certs/ca.crt --cert docker/ssl/certs/thing.crt --key docker/ssl/certs/thing.key -X POST -H "Content-Type: application/senml+json" -H "Authorization: Thing " https://localhost/http/channels//messages -d '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' ``` +The response body should look something like: +```bash + +``` + Note that if you're going to use senml message format, you should always send messages as an array. For more information about the HTTP messaging service API, please check out the [API documentation][http-api]. @@ -42,47 +77,99 @@ The following environmental variables are used to enable or disable MQTT with TL ### Without TLS -To use magistala mqtt without TLS, comment all of the listed environment variables provided above. To publish message over channel, thing should call following command: +To publish message over channel, thing should send following request: ```bash -mosquitto_pub --id-prefix magistrala -u -P -t channels//messages -h localhost -m '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' +mosquitto_pub -i magistrala -u -P -t channels//messages -h localhost -m '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' ``` -To subscribe to channel, thing should call following command: +This is the expected logs on magistrala-mqtt: +```bash +{"time":"2024-05-22T17:40:26.460507725Z","level":"INFO","msg":"Accepted new client"} +{"time":"2024-05-22T17:40:26.461947159Z","level":"INFO","msg":"connected with client_id magitrala100398"} +{"time":"2024-05-22T17:40:26.482658303Z","level":"INFO","msg":"published with client_id magitrala100398 to the topic channels/17c1bb45-7dc7-44eb-a2b4-57a16e4bc05b/messages"} +{"time":"2024-05-22T17:40:26.485183131Z","level":"ERROR","msg":"disconnected client_id magitrala100398 and username 91f6e004-9f9e-4f95-9b72-a04befbdf584"} +``` +To subscribe to channel, thing should send following request: + +```bash +mosquitto_sub -i magistrala -u -P -t channels//messages -h localhost +``` +This is the expected logs on magistrala-mqtt: +```bash +{"time":"2024-05-22T17:34:08.779743250Z","level":"INFO","msg":"Accepted new client"} +{"time":"2024-05-22T17:34:08.846790260Z","level":"INFO","msg":"connected with client_id magistrala93639"} +{"time":"2024-05-22T17:34:08.932790249Z","level":"INFO","msg":"subscribed with client_id magistrala93639 to topics channels/17c1bb45-7dc7-44eb-a2b4-57a16e4bc05b/messages"} +``` +When message is published the message is expected to be seen on the subscriber side like shown: ```bash -mosquitto_sub --id-prefix magistrala -u -P -t channels//messages -h localhost +[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}] ``` ### With TLS -To use magistala mqtt with TLS, uncomment the following environment variables: `MG_MQTT_ADAPTER_CERT_FILE`, `MG_MQTT_ADAPTER_KEY_FILE` and comment out the rest. To publish message over channel, thing should call following command: +To use magistala mqtt with TLS, set the following environment variables: +```bash +MG_MQTT_ADAPTER_CERT_FILE=./ssl/certs/magistrala-server.crt +MG_MQTT_ADAPTER_KEY_FILE=./ssl/certs/magistrala-server.key +``` +To publish message over channel, thing should send following request: ```bash -mosquitto_pub --id-prefix magistrala --cafile docker/ssl/certs/ca.crt -u -P -t channels//messages -h localhost -p 1883 -m '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' +mosquitto_pub -i magistrala --cafile docker/ssl/certs/ca.crt -u -P -t channels//messages -h localhost -p 1883 -m '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' ``` -To subscribe to channel, thing should call following command: - +This is the expected logs on magistrala-mqtt: ```bash -mosquitto_sub --id-prefix magistrala --cafile docker/ssl/certs/ca.crt -u -P -t channels//messages -h localhost -p 1883 +{"time":"2024-05-27T07:28:05.550261589Z","level":"INFO","msg":"Accepted new client"} +{"time":"2024-05-27T07:28:05.615021741Z","level":"INFO","msg":"connected with client_id magistrala32808"} +{"time":"2024-05-27T07:28:05.668840909Z","level":"INFO","msg":"published with client_id magistrala32808 to the topic channels/dd5426b2-3ec8-4259-9a07-c2bbb7127ce7/messages"} +{"time":"2024-05-27T07:28:05.669544477Z","level":"ERROR","msg":"disconnected client_id magistrala32808 and username 7abb9fa0-8700-4f9f-9e38-c93dd4bda017"} ``` -### With MTLS - -Uncomment out all of the above mentioned environment variables to enable MTLS certificates. Here is an example of how you would publish: +To subscribe to channel, thing should send following request: ```bash -mosquitto_pub --id-prefix magistrala -u -P -t channels//messages -h localhost -p 1883 -m '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' --cafile docker/ssl/certs/ca.crt --cert docker/ssl/certs/thing.crt --key docker/ssl/certs/thing.key - +mosquitto_sub -i magistrala --cafile docker/ssl/certs/ca.crt -u -P -t channels//messages -h localhost -p 1883 +``` +This is the expected logs on magistrala-mqtt: +```bash +{"time":"2024-05-27T07:33:36.517467526Z","level":"INFO","msg":"Accepted new client"} +{"time":"2024-05-27T07:33:36.578444287Z","level":"INFO","msg":"connected with client_id magistrala38318"} +{"time":"2024-05-27T07:33:36.590345981Z","level":"INFO","msg":"subscribed with client_id magistrala38318 to topics channels/dd5426b2-3ec8-4259-9a07-c2bbb7127ce7/messages"} ``` +### With MTLS - -Here is how you would subscribe: +To use magistala MQTT with MTLS, set the following environment variables as follows and restart magistrala: +```bash +MG_MQTT_ADAPTER_CERT_FILE=./ssl/certs/magistrala-server.crt +MG_MQTT_ADAPTER_KEY_FILE=./ssl/certs/magistrala-server.key +MG_MQTT_ADAPTER_SERVER_CA_FILE=./ssl/certs/ca.crt +MG_MQTT_ADAPTER_CLIENT_CA_FILE=./ssl/certs/ca.crt +``` +To publish message over channel, thing should send following request: +```bash +mosquitto_pub -i magistrala -u -P -t channels//messages -h localhost -p 1883 -m '[{"bn":"some-base-name:","bt":1.276020076001e+09, "bu":"A","bver":5, "n":"voltage","u":"V","v":120.1}, {"n":"current","t":-5,"v":1.2}, {"n":"current","t":-4,"v":1.3}]' --cafile docker/ssl/certs/ca.crt --cert docker/ssl/certs/thing.crt --key docker/ssl/certs/thing.key +``` +This is the expected logs on magistrala-mqtt: +```bash +{"time":"2024-05-27T07:43:25.03963452Z","level":"INFO","msg":"Accepted new client"} +{"time":"2024-05-27T07:43:25.072298607Z","level":"INFO","msg":"connected with client_id magistrala48391"} +{"time":"2024-05-27T07:43:25.092920495Z","level":"INFO","msg":"published with client_id magistrala48391 to the topic channels/dd5426b2-3ec8-4259-9a07-c2bbb7127ce7/messages"} +{"time":"2024-05-27T07:43:25.094117867Z","level":"ERROR","msg":"disconnected client_id magistrala48391 and username 7abb9fa0-8700-4f9f-9e38-c93dd4bda017"} +``` +To subscribe to channel, thing should send following request: ```bash -mosquitto_sub --id-prefix magistrala -u -P -t channels//messages -h localhost -p 1883 --cafile docker/ssl/certs/ca.crt --cert docker/ssl/certs/thing.crt --key docker/ssl/certs/thing.key +mosquitto_sub -i magistrala -u -P -t channels//messages -h localhost -p 1883 --cafile docker/ssl/certs/ca.crt --cert docker/ssl/certs/thing.crt --key docker/ssl/certs/thing.key +``` +This is the expected logs on magistrala-mqtt: +```bash +{"time":"2024-05-27T07:48:27.617045744Z","level":"INFO","msg":"Accepted new client"} +{"time":"2024-05-27T07:48:27.647008937Z","level":"INFO","msg":"connected with client_id magistrala53810"} +{"time":"2024-05-27T07:48:27.660881053Z","level":"INFO","msg":"subscribed with client_id magistrala53810 to topics channels/dd5426b2-3ec8-4259-9a07-c2bbb7127ce7/messages"} ``` If you want to use standard topic such as `channels//messages` with SenML content type (JSON or CBOR), you should use following topic `channels//messages`. @@ -240,7 +327,7 @@ i.e. connection URL should be `ws:///mqtt`. For quick testing you can use [HiveMQ UI tool][websocket-client]. -The following environmental variables are used to enable or disable MQTT-over-WS with TLS and MTLS: `MG_MQTT_ADAPTER_WS_CERT_FILE`,`MG_MQTT_ADAPTER_WS_KEY_FILE`, `MG_MQTT_ADAPTER_WS_SERVER_CA_FILE`, `MG_MQTT_ADAPTER_WS_CLIENT_CA_FILE`. +The following environment variables are used to enable or disable MQTT-over-WS with TLS and MTLS: `MG_MQTT_ADAPTER_WS_CERT_FILE`,`MG_MQTT_ADAPTER_WS_KEY_FILE`, `MG_MQTT_ADAPTER_WS_SERVER_CA_FILE`, `MG_MQTT_ADAPTER_WS_CLIENT_CA_FILE`. Here is an example of a browser application connecting to Magistrala server and sending and receiving messages over WebSocket using MQTT.js library: @@ -307,8 +394,7 @@ client.connect({ onSuccess: onConnect }); ### Without TLS -Comment out all of the above mentioned environment variables to disable TLS certificates. -Here is an example of how you would publish: +Here is an example of a Go program connecting to Magistrala server and sending messages over MQTT without TLS using paho mqtt library: ```go package main @@ -371,11 +457,22 @@ func publish(client mqtt.Client) { } ``` +This is the expected logs on magistrala-mqtt: +```bash +{"time":"2024-05-28T07:43:33.176947136Z","level":"INFO","msg":"connected with client_id da018f93-49fd-4409-9ede-70c718d336a0"} +{"time":"2024-05-28T07:43:33.259267711Z","level":"INFO","msg":"published with client_id da018f93-49fd-4409-9ede-70c718d336a0 to the topic channels/dd5426b2-3ec8-4259-9a07-c2bbb7127ce7/messages"} +{"time":"2024-05-28T07:43:33.26171184Z","level":"ERROR","msg":"disconnected client_id da018f93-49fd-4409-9ede-70c718d336a0 and username 7abb9fa0-8700-4f9f-9e38-c93dd4bda017"} +``` + ### With TLS -Uncomment out the following environment variables: `MG_MQTT_ADAPTER_WS_CERT_FILE`,`MG_MQTT_ADAPTER_WS_KEY_FILE` and comment out the rest to enable TLS certificates. -Here is an example of how you would publish: +To use magistrala MQTT-over-WS with TLS, set the following environment variables as follows and restart magistrala: +```bash +MG_MQTT_ADAPTER_WS_CERT_FILE=./ssl/certs/magistrala-server.crt +MG_MQTT_ADAPTER_WS_KEY_FILE=./ssl/certs/magistrala-server.key +``` +To publish message over channel, thing should send following request: ```go package main @@ -451,7 +548,7 @@ func publish(client mqtt.Client) { } } -// Load return a TLS configuration that can be used in TLS servers +// LoadTLS return a TLS configuration that can be used in TLS servers func LoadTLS(certFile, keyFile, serverCAFile, clientCAFile string) (*tls.Config, error) { tlsConfig := &tls.Config{} @@ -508,8 +605,14 @@ func loadCertFile(certFile string) ([]byte, error) { ### With MTLS -Uncomment out all of the above mentioned environment variables to enable MTLS certificates. -Here is an example of how you would publish: +To use magistrala MQTT-over-WS with MTLS, set the following environment variables as follows and restart magistrala: +```bash +MG_MQTT_ADAPTER_WS_CERT_FILE=./ssl/certs/magistrala-server.crt +MG_MQTT_ADAPTER_WS_KEY_FILE=./ssl/certs/magistrala-server.key +MG_MQTT_ADAPTER_WS_SERVER_CA_FILE=./ssl/certs/ca.crt +MG_MQTT_ADAPTER_WS_CLIENT_CA_FILE=./ssl/certs/ca.crt +``` +To publish message over channel, thing should send following request: ```go package main