diff --git a/README.md b/README.md index 1cb53f48c425d69b732e6cc0b4f050074872f17d..765140b5a928a12ca86532382a3c343374fccbce 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ digital_outputs: off_payload: "OFF" initial: low # This optional value controls the initial state of the pin before receipt of any messages from MQTT. Valid options are 'low' and 'high'. retain: yes # This option value controls if the message is retained. Default is no. - + - name: fan module: raspberrypi pin: 22 @@ -82,6 +82,41 @@ digital_inputs: pulldown: no ``` +#### SSL/TLS + +You may want to connect to a remote server, in which case it's a good idea to use an encrypted connection. If the server supports this, then you can supply the relevant config values for the [tls_set()](https://github.com/eclipse/paho.mqtt.python#tls_set) command. + +```yaml +mqtt: + host: test.mosquitto.org + port: 8883 + tls: + enabled: yes +``` + +You may need to supply a trusted CA certificate, as instructed on https://test.mosquitto.org/. + +```yaml +mqtt: + host: test.mosquitto.org + port: 8883 + tls: + enabled: yes + ca_certs: mosquitto.org.crt +``` + +Or you might want to use SSL/TLS but not verify the server's certificate (not recommended). + +```yaml +mqtt: + host: test.mosquitto.org + port: 8883 + tls: + enabled: yes + cert_reqs: CERT_NONE + insecure: yes +``` + #### Temporary Set You may want to set the output to a given value for a certain amount of time. This can be done using the `/set_on_ms` and `/set_off_ms` topics. If an output is already set to that value, it will stay that value for the given amount of milliseconds and then switch to the opposite. diff --git a/config.schema.yml b/config.schema.yml index 970e884e7f8d448f892606549736c50c04a6418c..9f5ff233b2571f7da29eefe21db69bc25bd00497 100644 --- a/config.schema.yml +++ b/config.schema.yml @@ -55,6 +55,40 @@ mqtt: type: string required: no default: dead + tls: + type: dict + required: no + schema: + enabled: + type: boolean + required: yes + ca_certs: + type: string + required: no + certfile: + type: string + required: no + keyfile: + type: string + required: no + cert_reqs: + type: string + required: no + allowed: + - CERT_NONE + - CERT_OPTIONAL + - CERT_REQUIRED + default: CERT_REQUIRED + tls_version: + type: string + required: no + ciphers: + type: string + required: no + insecure: + type: boolean + required: no + default: false gpio_modules: type: list @@ -155,4 +189,3 @@ digital_outputs: type: boolean required: no default: no - diff --git a/pi_mqtt_gpio/__init__.py b/pi_mqtt_gpio/__init__.py index f3d999a73501eb3440da5c45419d937deb7ba5a0..9d26b90f776d1554630dcf76c7b8070884de1f03 100644 --- a/pi_mqtt_gpio/__init__.py +++ b/pi_mqtt_gpio/__init__.py @@ -58,6 +58,40 @@ mqtt: type: string required: no default: dead + tls: + type: dict + required: no + schema: + enabled: + type: boolean + required: yes + ca_certs: + type: string + required: no + certfile: + type: string + required: no + keyfile: + type: string + required: no + cert_reqs: + type: string + required: no + allowed: + - CERT_NONE + - CERT_OPTIONAL + - CERT_REQUIRED + default: CERT_REQUIRED + tls_version: + type: string + required: no + ciphers: + type: string + required: no + insecure: + type: boolean + required: no + default: false gpio_modules: type: list @@ -159,5 +193,4 @@ digital_outputs: required: no default: no - """) diff --git a/pi_mqtt_gpio/server.py b/pi_mqtt_gpio/server.py index 7070501125b16b7bc142131caf48d0fd817749de..bf8fa4df230c424824a17b30be3f1e56bcecb904 100644 --- a/pi_mqtt_gpio/server.py +++ b/pi_mqtt_gpio/server.py @@ -3,6 +3,7 @@ import logging import yaml import sys import socket +import ssl from time import sleep, time from importlib import import_module from hashlib import sha1 @@ -282,6 +283,28 @@ def init_mqtt(config, digital_outputs): status_topic, config["status_payload_dead"]) + # Set TLS options + tls_enabled = config.get("tls", {}).get("enabled") + if tls_enabled: + tls_config = config["tls"] + tls_kwargs = dict( + ca_certs=tls_config.get("ca_certs"), + certfile=tls_config.get("certfile"), + keyfile=tls_config.get("keyfile"), + ciphers=tls_config.get("ciphers") + ) + try: + tls_kwargs["cert_reqs"] = getattr(ssl, tls_config["cert_reqs"]) + except KeyError: + pass + try: + tls_kwargs["tls_version"] = getattr(ssl, tls_config["tls_version"]) + except KeyError: + pass + + client.tls_set(**tls_kwargs) + client.tls_insecure_set(tls_config["insecure"]) + def on_conn(client, userdata, flags, rc): """ On connection to MQTT, subscribe to the relevant topics.