diff --git a/.mosquitto/mosquitto.conf b/.mosquitto/mosquitto.conf index 7739132..08d998a 100644 --- a/.mosquitto/mosquitto.conf +++ b/.mosquitto/mosquitto.conf @@ -233,6 +233,9 @@ password_file /etc/mosquitto/passwd # listener port-number [ip address/host name/unix socket path] listener 1883 0.0.0.0 +# TLS Listener +listener 8883 0.0.0.0 + # By default, a listener will attempt to listen on all supported IP protocol # versions. If you do not have an IPv4 or IPv6 interface you may wish to # disable support for either of those protocol versions. In particular, note @@ -315,10 +318,10 @@ listener 1883 0.0.0.0 # TLS encryption. # Path to the PEM encoded server certificate. -#certfile +certfile /mosquitto/certs/server.crt # Path to the PEM encoded keyfile. -#keyfile +keyfile /mosquitto/certs/server.key # If you wish to control which encryption ciphers are used, use the ciphers # option. The list of available ciphers can be optained using the "openssl @@ -359,7 +362,7 @@ listener 1883 0.0.0.0 # containing the CA certificates. For capath to work correctly, the # certificate files must have ".crt" as the file ending and you must run # "openssl rehash " each time you add/remove a certificate. -#cafile +cafile /mosquitto/certs/ca.crt #capath diff --git a/DESIGN_CONCIDERATIONS.md b/DESIGN_CONCIDERATIONS.md index 764139b..db31982 100644 --- a/DESIGN_CONCIDERATIONS.md +++ b/DESIGN_CONCIDERATIONS.md @@ -6,3 +6,27 @@ - Events on device takes precedence when comparing remote events. This means tie's are broken by Dn(e) winning over C(e) event when events occur concurrently. - Example At time T1 a remote user creates an event in the controlling process to changes D1's temperature (Controller: [1,0], Device: [0,0]). A message is sent at T2 by the controller to a subscribing device (Controller: [2,0], Device: [0,0]). Before receipt of this message a second user changes D1's temperature at device time T'1 (Controller: [2,0], Device: [0,1]). The device creates a message at T'2 and sends this temperature update notification to the controller (Controller: [2,0], Device: [0,2]). On receipt of the message send by the controller we will detect an in comparable event where the message vector would be of the form T || T' because Message Vector [2,0] and local Device vector [0,2] where 2 > 0 but 0 !> 2 and the reverse also is in conflict. This means we have detected concurrent events. In this case the message command sent from the controller at T2 is discarded and D1's temp set event takes precedence. D1's time will be advanced to [2,3] and when the controller receives D1's event message it's clock will advance to [3,2]. - If the remote user sends the temperature command again. The time of message sent on C(T3) will be [4,2]. On receipt at D1 it's own clock will advance to [4,4], and the temperature will be set. + + +## Enabling TLS for Mosquitto + +It is recommended to expose Mosquitto using TLS on port 8883 and port 8084 for Secure websockets. This implementation will only enable TLS security over TCP 8883 port. To achieve this declare a new listener for port 8883. All configuration that appears after the new listener declaration applies specifically to that listener. + +So the following can be added to the end of the mosquitto.conf +``` +listener 8883 0.0.0.0 +cafile /mosquitto/certs/ca.crt +certfile /mosquitto/certs/server.crt +keyfile /mosquitto/certs/server.key + +# By default an TLS enabled listener will operate in a similar fashion to a +# https enabled web server, in that the server has a certificate signed by a CA +# and the client will verify that it is a trusted certificate. The overall aim +# is encryption of the network traffic. By setting require_certificate to true, +# the client must provide a valid certificate in order for the network +# connection to proceed. This allows access to the broker to be controlled +# outside of the mechanisms provided by MQTT. +#require_certificate false +``` + +Note at this point clients are not required to provide their own certificate since we have not set `require_certificate true`. This is what we want to start with, but eventually we will want to issue certs to clients that will server not only as their client id but also as their authentication. No passkey is required to use the servery.key in this setup. If there was you would need to provide it in `keyfile_password your_passphrase_here` and the mosquitto.conf file should be limited with `chmod 600`. \ No newline at end of file diff --git a/README.md b/README.md index 857516e..1053786 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,17 @@ make test-integration ## Usage -*Instructions TBD* +To run the application end to end first start the development server: + +``` +make start-dev +``` + +Next we can start our subscriber: + +``` +go run +``` ## Design Considerations @@ -75,4 +85,4 @@ See [DESIGN_CONCIDERATIONS.md](./DESIGN_CONCIDERATIONS.md) - [TLS refresher](http://www.steves-internet-guide.com/ssl-certificates-explained/) - [HA Mosquitto in K8s](https://sko.ai/blog/how-to-run-ha-mosquitto/) - [Lamport Timestamps Tutorial](https://towardsdatascience.com/understanding-lamport-timestamps-with-pythons-multiprocessing-library-12a6427881c6) --[Vector Clocks Lecture](https://www.youtube.com/watch?v=x-D8iFU1d-o) +- [Vector Clocks Lecture](https://www.youtube.com/watch?v=x-D8iFU1d-o) diff --git a/cmd/subscriber/main.go b/cmd/subscriber/main.go index 9842305..2277c48 100644 --- a/cmd/subscriber/main.go +++ b/cmd/subscriber/main.go @@ -37,6 +37,7 @@ func main() { var port = 1883 opts := mqtt.NewClientOptions() opts.AddBroker(fmt.Sprintf("tcp://%s:%d", broker, port)) + // Client ID's must be unique. opts.SetClientID("go_mqtt_sub_client") opts.SetUsername("dirp") opts.SetPassword("dirp") diff --git a/docker-compose.yaml b/docker-compose.yaml index caf1200..c78eb31 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -6,9 +6,10 @@ services: restart: unless-stopped ports: - "1883:1883" + - "8883:8883" - "9001:9001" volumes: - ./.mosquitto:/etc/mosquitto - ./.mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf - ./.mosquitto/certs:/mosquitto/certs - user: "1000:1000" \ No newline at end of file + user: "1000:1000" \ No newline at end of file