Browse Source

add tls support

nico 7 years ago
parent
commit
28cc530340

+ 26 - 22
kalliope/brain.yml

@@ -32,31 +32,35 @@
     signals:
       - mqtt_subscriber:
           broker_ip: "127.0.0.1"
+          broker_port: 8883
           topic: "topic1"
-      - mqtt_subscriber:
-          broker_ip: "192.168.0.1"
-          topic: "topic2"
-    neurons:
-      - say:
-          message:
-            - "Bonjour monsieur"
-
-  - name: "test-mqtt-2"
-    signals:
-      - mqtt_subscriber:
-          broker_ip: "127.0.0.1"
-          topic: "topic3"
+          username: "guest"
+          password: "guest"
+          ca_cert: "/home/nico/Desktop/PKI_rabbit/ca.cert"
+          certfile: "/home/nico/Desktop/PKI_rabbit/client.crt"
+          keyfile: "/home/nico/Desktop/PKI_rabbit/client.key"
+          tls_insecure: True
     neurons:
       - say:
           message:
             - "Bonjour monsieur"
 
-  - name: "test-mqtt-3"
-    signals:
-      - mqtt_subscriber:
-          broker_ip: "127.0.0.1"
-          topic: "topic1"
-    neurons:
-      - say:
-          message:
-            - "Bonjour monsieur"
+#  - name: "test-mqtt-2"
+#    signals:
+#      - mqtt_subscriber:
+#          broker_ip: "127.0.0.1"
+#          topic: "topic3"
+#    neurons:
+#      - say:
+#          message:
+#            - "Bonjour monsieur"
+#
+#  - name: "test-mqtt-3"
+#    signals:
+#      - mqtt_subscriber:
+#          broker_ip: "127.0.0.1"
+#          topic: "topic1"
+#    neurons:
+#      - say:
+#          message:
+#            - "Bonjour monsieur"

+ 9 - 0
kalliope/signals/mqtt_subscriber/MqttClient.py

@@ -31,6 +31,15 @@ class MqttClient(Thread):
             logger.debug("[MqttClient] Username and password are set")
             self.client.username_pw_set(self.broker.username, self.broker.password)
 
+        if self.broker.ca_cert is not None and self.broker.certfile is not None and self.broker.keyfile is not None:
+            logger.debug("[MqttClient] Active TLS")
+            self.client.tls_set(ca_certs=self.broker.ca_cert,
+                                certfile=self.broker.certfile,
+                                keyfile=self.broker.keyfile)
+            self.client.tls_insecure_set(self.broker.tls_insecure)
+        else:
+            print("miss")
+
     def run(self):
         logger.debug("[MqttClient] Try to connect to broker: %s, port: %s, "
                      "keepalive: %s, protocol: %s" % (self.broker.broker_ip,

+ 76 - 3
kalliope/signals/mqtt_subscriber/README.md

@@ -1,6 +1,9 @@
 # MQTT Subscriber
 
-## Install rabbitmq
+
+## Test with rabbitmq-server broker
+
+### Install rabbitmq
 
 ```
 sudo apt-get install rabbitmq-server amqp-tools
@@ -31,16 +34,86 @@ sudo rabbitmqctl set_user_tags admin administrator
 sudo rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
 ```
 
+### Test publish
 Publish a message with amqp-tools in the default rabbitmq exchange with the topic key "test.light"
 ```
 amqp-publish -e "amq.topic" -r "test.light" -b "your message"
 ```
 
-
 Test publish json
 ```
 amqp-publish -e "amq.topic" -r "test.light" -b '{"test" : "message"}'
 ```
 
+### Add TLS to rabbitmq
+
+#### Create root CA
+
+Install openssl
+```bash
+apt-get install openssl
+```
+
+Create PKI structure
+```bash
+mkdir testca
+cd testca
+echo 01 > serial
+```
+
+Create private key and CA certificate
+```bash
+openssl req -out ca.key -new -x509 
+```
+
+Generate server/key pair
+```bash
+openssl genrsa -out server.key 2048 
+openssl req -key server.key -new -out server.req 
+openssl x509 -req -in server.req -CA ca.crt -CAkey privkey.pem -CAserial serial -out server.crt
+```
+
+#### Create client certificate/key pair
+
+Create private key
+```bash
+openssl genrsa -out client.key 2048
+```
+
+Create a certificate request
+```bash
+openssl req -key client.key -new -out client.req 
+```
+
+Sign the client request with the CA
+```bash
+openssl x509 -req -in client.req -CA ca.cert -CAkey privkey.pem -CAserial serial -out client.crt 
+```
+
+#### Update rabbitmq configuration
+
+Edit (or create if the file is not present) a config file `/etc/rabbitmq/rabbitmq.config`
+```
+[
+  {rabbit, [
+     {ssl_listeners, [5671]},
+     {ssl_options, [{cacertfile,"/path/to/ca.cert"},
+                    {certfile,"/path/to/server.crt"},
+                    {keyfile,"/path/to/server.key"},
+                    {verify,verify_peer},
+                    {fail_if_no_peer_cert,false}]}
+   ]},
+  {rabbitmq_mqtt, [
+                  {ssl_listeners,    [8883]},
+                  {tcp_listeners,    [1883]}
+                ]}
+
+].
+```
+
+Restart rabbitmq server to take care of changes
+```bash
+sudo systemctl restart rabbitmq-server
+```
+
 
-amqp-publish -e "amq.topic" -r "topic1" -b "your message"

+ 20 - 1
kalliope/signals/mqtt_subscriber/models.py

@@ -20,7 +20,8 @@ class Topic(object):
 
 class Broker(object):
     def __init__(self, broker_ip=None, topics=None, port=None, client_id=None, keepalive=None,
-                 username=None, password=None, protocol=None):
+                 username=None, password=None, protocol=None, ca_cert=None, certfile=None, keyfile=None,
+                 tls_insecure=None):
         self.broker_ip = broker_ip
         self.topics = topics
         if self.topics is None:
@@ -33,6 +34,10 @@ class Broker(object):
         self.username = username
         self.password = password
         self.protocol = protocol
+        self.ca_cert = ca_cert
+        self.certfile = certfile
+        self.keyfile = keyfile
+        self.tls_insecure = tls_insecure
 
     def build_from_signal_dict(self, dict_parameters):
         """
@@ -84,6 +89,20 @@ class Broker(object):
         else:
             self.protocol = "MQTTv311"
 
+        if "ca_cert" in dict_parameters:
+            self.ca_cert = dict_parameters["ca_cert"]
+
+        if "certfile" in dict_parameters:
+            self.certfile = dict_parameters["certfile"]
+
+        if "keyfile" in dict_parameters:
+            self.keyfile = dict_parameters["keyfile"]
+
+        if "tls_insecure" in dict_parameters:
+            self.tls_insecure = dict_parameters["tls_insecure"]
+            self.tls_insecure = bool(self.tls_insecure)
+        else:
+            self.tls_insecure = False
 
     def __eq__(self, other):
         """