From 35541e6fdc907736a073d27106327a8c1864f0c0 Mon Sep 17 00:00:00 2001 From: Wolfgang Hottgenroth Date: Wed, 14 Sep 2022 14:19:01 +0200 Subject: [PATCH] documentation --- Dockerfile | 7 +++-- crontab | 2 +- mosquitto-start.sh | 3 +- readme.md | 69 ++++++++++++++++++++++++++++++++++++---------- 4 files changed, 60 insertions(+), 21 deletions(-) diff --git a/Dockerfile b/Dockerfile index cf9258d..c387b8d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ ARG MOSQ_GID="1883" RUN \ apt update && \ - apt install -y mariadb-client openssl libwebsockets-dev certbot bash cron supervisor vim-tiny && \ + apt install -y mariadb-client openssl libwebsockets-dev certbot bash cron supervisor vim-tiny procps net-tools && \ update-alternatives --set editor /usr/bin/vim.tiny && \ update-alternatives --set vi /usr/bin/vim.tiny && \ groupadd -r -g $MOSQ_GID $MOSQ_USER && \ @@ -23,7 +23,7 @@ COPY etc/ /opt/etc COPY supervisor-mosquitto.conf /etc/supervisor/conf.d/ COPY crontab /etc/ COPY mosquitto.conf-sample /opt/etc/mosquitto/ -COPY cert-deploy.sh /opt/sbin/ +COPY cert-deploy.sh /opt/bin/ VOLUME /opt/etc VOLUME /opt/data @@ -38,5 +38,6 @@ EXPOSE 9001/tcp WORKDIR /opt -CMD /usr/bin/openssl dhparam -out /opt/etc/mosquitto/dh.pem 2048 && /usr/bin/supervisord -c /etc/supervisor/supervisord.conf +CMD [ "/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf" ] + diff --git a/crontab b/crontab index c35bd55..6969122 100644 --- a/crontab +++ b/crontab @@ -1,3 +1,3 @@ SHELL=/bin/sh PATH=/usr/bin -*/2 * * * * root supervisorctl start certbot +1 1 * * 1 root supervisorctl start certbot diff --git a/mosquitto-start.sh b/mosquitto-start.sh index 59fdcd7..4bca1ca 100755 --- a/mosquitto-start.sh +++ b/mosquitto-start.sh @@ -1,6 +1,6 @@ #!/bin/bash -IMAGE=registry.gitlab.com/wolutator/mosquitto-with-auth:latest +IMAGE=wollud1969/mosquitto-with-auth:latest VOLUME_CONFIG=mosquitto-config VOLUME_DATA=mosquitto-data VOLUME_LOG=mosquitto-log @@ -25,7 +25,6 @@ docker run \ -v $VOLUME_DATA:/opt/data \ -v $VOLUME_LOG:/var/log/supervisor \ -v $VOLUME_LETSENCRYPT:/etc/letsencrypt \ - --link mariadb \ --name mosquitto \ $IMAGE diff --git a/readme.md b/readme.md index cde7e81..f90f70f 100644 --- a/readme.md +++ b/readme.md @@ -2,6 +2,8 @@ This project includes the mosquitto MQTT broker (https://github.com/eclipse/mosquitto, see also https://mosquitto.org/) and the mosquitto-go-auth (https://github.com/iegomez/mosquitto-go-auth forked into https://github.com/wollud1969/mosquitto-go-auth) as submodules. +It additionally includes the Let's Encrypt `certbot` and some mimic for automatic renewal of certificates using `supervisord` and `cron`. + Using Gitlab CI and a Dockerfile included in this project a Docker image based on Debian Linux is created. @@ -17,41 +19,53 @@ The mosquitto-go-auth supports a couple of backends and it seems that all backen ## Running the container +You can not run a container based on this image "out-of-the-box". You need to edit the configuration, and if desired, run all the Let's Encrypt stuff. For details see below. + The container exposed the ports 1883 (MQTT), 8883 (MQTT over SSL) and 9001 (MQTT over websockets). Only the configuration directory containing `mosquitto.conf` and friends is prepared as a volume. -All logging is send to `stdout`, so it can be inspected using `docker logs -f ` +Besides the mosquitto configuration volume, there are volume required for the Let's Encrypt configuration and state, the data directory of the broker and for the logfiles for `supervisord`. + +Due to the requirements of `certbot` it also exposed the port 80 and 443. So, be careful when trying to start this image as a container on the same host as a webserver. + +All logging is send into a dedicated logfile under control of `supervisord`. To start the container a script is provided, which might need to adjusted to the actual environment: #!/bin/bash - IMAGE=registry.gitlab.com/wolutator/mosquitto-with-auth:latest + IMAGE=wollud1969/mosquitto-with-auth:latest VOLUME_CONFIG=mosquitto-config VOLUME_DATA=mosquitto-data + VOLUME_LOG=mosquitto-log + VOLUME_LETSENCRYPT=mosquitto-letsencrypt docker volume inspect $VOLUME_CONFIG > /dev/null || docker volume create $VOLUME_CONFIG docker volume inspect $VOLUME_DATA > /dev/null || docker volume create $VOLUME_DATA + docker volume inspect $VOLUME_LOG > /dev/null || docker volume create $VOLUME_LOG + docker volume inspect $VOLUME_LETSENCRYPT > /dev/null || docker volume create $VOLUME_LETSENCRYPT docker pull $IMAGE docker run \ - -d \ - --rm \ - -p1883:1883 \ - -p8883:8883 \ - -p9001:9001 \ - -v $VOLUME_CONFIG:/opt/etc/mosquitto \ - -v $VOLUME_DATA:/opt/data \ - --link mariadb \ - --name mosquitto \ - $IMAGE + -d \ + --rm \ + -p80:80 \ + -p443:443 \ + -p1883:1883 \ + -p8883:8883 \ + -p9001:9001 \ + -v $VOLUME_CONFIG:/opt/etc/mosquitto \ + -v $VOLUME_DATA:/opt/data \ + -v $VOLUME_LOG:/var/log/supervisor \ + -v $VOLUME_LETSENCRYPT:/etc/letsencrypt \ + --name mosquitto \ + $IMAGE +The container expects the main configuration file in the root of the configuration volume named `mosquitto.conf`. -The container expects the main configuration file in the root of the volume named `mosquitto.conf`. - -A very simple configuration, only supporting MQTT on port 1883 is: +A very simple configuration, supporting MQTT on port 1883 and over TLS on port 8883 is: log_dest stdout @@ -64,6 +78,15 @@ A very simple configuration, only supporting MQTT on port 1883 is: #allow_anonymous true allow_anonymous false + listener 8883 + protocol mqtt + #allow_anonymous true + allow_anonymous false + certfile /opt/etc/mosquitto/server.crt + keyfile /opt/etc/mosquitto/server.key + dhparamfile /opt/etc/mosquitto/dh.pem + tls_version tlsv1.2 + auth_plugin /opt/lib/go-auth.so auth_opt_log_dest stdout auth_opt_log_level debug @@ -123,5 +146,21 @@ The password is generated using the `pw` tool provided by mosquitto-go-auth, whi For further information consult the readme and the examples in the mosquitto-go-auth project (https://github.com/iegomez/mosquitto-go-auth or https://github.com/wollud1969/mosquitto-go-auth). +## Preparing configuration and certificates + +* Start the container using the provided start script, follow the container log using `docker logs -f `, you will see that `supervisord` start `cron` and `mosquitto` and you will see that the start of `mosquitto` fails +* Go into the container using `docker exec -it bash` +* Go into the directory `/opt/etc/mosquitto`, copy `mosquitto.conf-sample` into `mosquitto.conf` and edit it if required + +If you want to register at Let's Encrypt and obtain a certificate follow the next steps: + +* Generate Diffie-Hellman parameters in the broker's configuration directory using `openssl dhparam -out /opt/etc/mosquitto/dh.pem 2048` +* Register at Let's Encrypt using `certbot register` +* Obtain a certificate using `certbot certonly -d --standalone`, make sure to add the domainname into DNS first +* Copy the deployment script into the deploy hooks directory of Let's Encrypt: `cp /opt/bin/cert-deploy.sh /etc/letsencrypt/renewal-hooks/deploy/`, edit it to fill in the right domainname +* Run the deployment script manually for the very first deployment of certificates: `env RENEWED_DOMAINS= RENEWED_LINEAGE=/etc/letsencrypt/live/ ./cert-deploy.sh` +* The certificate and private key is now copied from the Let's Encrypt state directory into the configuration directory of `mosquitto` and the broker is restarted, you can observe that in the container logging output +* Finally, test the broker using something like `mosquitto_sub -h -p 8883 --tls-version tlsv1.2 -v -t test` and `mosquitto_pub -h -p 8883 --tls-version tlsv1.2 -t test -m test123` +* Renewal of the certificate will be triggered once a week