Skip to content
This repository was archived by the owner on May 2, 2025. It is now read-only.

Commit 85c4e5d

Browse files
sisciabrocaar
authored andcommitted
Add CA cert option for MQTT TLS connection (#103)
1 parent fd8b0a8 commit 85c4e5d

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

cmd/lora-app-server/main.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ func mustGetContext(c *cli.Context) common.Context {
175175
rp := storage.NewRedisPool(c.String("redis-url"))
176176

177177
// setup mqtt handler
178-
h, err := handler.NewMQTTHandler(rp, c.String("mqtt-server"), c.String("mqtt-username"), c.String("mqtt-password"))
178+
h, err := handler.NewMQTTHandler(rp, c.String("mqtt-server"), c.String("mqtt-username"), c.String("mqtt-password"), c.String("mqtt-ca-cert"))
179179
if err != nil {
180180
log.Fatalf("setup mqtt handler error: %s", err)
181181
}
@@ -400,6 +400,11 @@ func main() {
400400
Usage: "mqtt server password (optional)",
401401
EnvVar: "MQTT_PASSWORD",
402402
},
403+
cli.StringFlag{
404+
Name: "mqtt-ca-cert",
405+
Usage: "mqtt CA certificate file used by the gateway backend (optional)",
406+
EnvVar: "MQTT_CA_CERT",
407+
},
403408
cli.StringFlag{
404409
Name: "ca-cert",
405410
Usage: "ca certificate used by the api server (optional)",

docs/content/install/config.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ GLOBAL OPTIONS:
1919
--mqtt-server value mqtt server (e.g. scheme://host:port where scheme is tcp, ssl or ws) (default: "tcp://localhost:1883") [$MQTT_SERVER]
2020
--mqtt-username value mqtt server username (optional) [$MQTT_USERNAME]
2121
--mqtt-password value mqtt server password (optional) [$MQTT_PASSWORD]
22+
--mqtt-ca-cert mqtt CA certificate file used by the gateway backend (optional) [$MQTT_CA_CERT]
2223
--ca-cert value ca certificate used by the api server (optional) [$CA_CERT]
2324
--tls-cert value tls certificate used by the api server (optional) [$TLS_CERT]
2425
--tls-key value tls key used by the api server (optional) [$TLS_KEY]

internal/handler/mqtt_handler.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ package handler
22

33
import (
44
"bytes"
5+
"crypto/tls"
6+
"crypto/x509"
57
"encoding/base64"
68
"encoding/json"
79
"fmt"
10+
"io/ioutil"
811
"regexp"
912
"strconv"
1013
"sync"
@@ -53,7 +56,7 @@ type ErrorNotification struct {
5356
}
5457

5558
// NewMQTTHandler creates a new MQTTHandler.
56-
func NewMQTTHandler(p *redis.Pool, server, username, password string) (Handler, error) {
59+
func NewMQTTHandler(p *redis.Pool, server, username, password, cafile string) (Handler, error) {
5760
h := MQTTHandler{
5861
dataDownChan: make(chan DataDownPayload),
5962
redisPool: p,
@@ -66,6 +69,15 @@ func NewMQTTHandler(p *redis.Pool, server, username, password string) (Handler,
6669
opts.SetOnConnectHandler(h.onConnected)
6770
opts.SetConnectionLostHandler(h.onConnectionLost)
6871

72+
if cafile != "" {
73+
tlsconfig, err := newTLSConfig(cafile)
74+
if err != nil {
75+
log.Fatalf("Error with the mqtt CA certificate: %s", err)
76+
} else {
77+
opts.SetTLSConfig(tlsconfig)
78+
}
79+
}
80+
6981
log.WithField("server", server).Info("handler/mqtt: connecting to mqtt broker")
7082
h.conn = mqtt.NewClient(opts)
7183
for {
@@ -79,6 +91,25 @@ func NewMQTTHandler(p *redis.Pool, server, username, password string) (Handler,
7991
return &h, nil
8092
}
8193

94+
func newTLSConfig(cafile string) (*tls.Config, error) {
95+
// Import trusted certificates from CAfile.pem.
96+
97+
cert, err := ioutil.ReadFile(cafile)
98+
if err != nil {
99+
log.Errorf("backend: couldn't load cafile: %s", err)
100+
return nil, err
101+
}
102+
103+
certpool := x509.NewCertPool()
104+
certpool.AppendCertsFromPEM(cert)
105+
106+
// Create tls.Config with desired tls properties
107+
return &tls.Config{
108+
// RootCAs = certs used to verify server cert.
109+
RootCAs: certpool,
110+
}, nil
111+
}
112+
82113
// Close stops the handler.
83114
func (h *MQTTHandler) Close() error {
84115
log.Info("handler/mqtt: closing handler")

internal/handler/mqtt_handler_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func TestMQTTHandler(t *testing.T) {
2626
test.MustFlushRedis(p)
2727

2828
Convey("Given a new MQTTHandler", func() {
29-
handler, err := NewMQTTHandler(p, conf.MQTTServer, conf.MQTTUsername, conf.MQTTPassword)
29+
handler, err := NewMQTTHandler(p, conf.MQTTServer, conf.MQTTUsername, conf.MQTTPassword, "")
3030
So(err, ShouldBeNil)
3131
defer handler.Close()
3232
time.Sleep(time.Millisecond * 100) // give the backend some time to connect

0 commit comments

Comments
 (0)