Initial commit

This commit is contained in:
Saber Karmous 2018-10-24 21:18:46 +02:00
commit d28fb1f24f
10 changed files with 702 additions and 0 deletions

10
.gitignore vendored Executable file
View File

@ -0,0 +1,10 @@
# OS generated files #
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
.rnd

43
Dockerfile Executable file
View File

@ -0,0 +1,43 @@
FROM python:2.7-alpine
LABEL maintainer bitrox <proxy@bitrox.io>
# Set environment variables.
ENV TERM=xterm-color
ENV SHELL=/bin/bash
RUN \
mkdir /mosquitto && \
mkdir /mosquitto/log && \
mkdir /mosquitto/conf && \
apk update && \
apk upgrade && \
apk add \
bash \
coreutils \
nano \
py-crypto \
ca-certificates \
certbot \
mosquitto \
mosquitto-clients && \
rm -f /var/cache/apk/* && \
pip install --upgrade pip && \
pip install pyRFC3339 configobj ConfigArgParse
COPY run.sh /run.sh
COPY certbot.sh /certbot.sh
COPY restart.sh /restart.sh
COPY croncert.sh /etc/periodic/weekly/croncert.sh
RUN \
chmod +x /run.sh && \
chmod +x /certbot.sh && \
chmod +x /restart.sh && \
chmod +x /etc/periodic/weekly/croncert.sh
EXPOSE 1883
EXPOSE 8883
EXPOSE 80
# This will run any scripts found in /scripts/*.sh
# then start Apache
CMD ["/bin/bash","-c","/run.sh"]

201
LICENSE Executable file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2017 Bitrox.io
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

206
README.md Executable file
View File

@ -0,0 +1,206 @@
# alpine-mosquitto-certbot
An automated build that integrates the [Mosquitto MQTT server](https://mosquitto.org/) with [Certbot](https://certbot.eff.org/) on top of [Alpine linux](https://www.alpinelinux.org/).
As the Internet of Things (IoT) world rapidly grows and evolves, developers need a simple and secure way to implement peer-to-peer and peer-to-server (backend) communications. MQTT is a relatively simple message/queue-based protocol that provides exactly that.
Unfortunately, there are a ton of Docker images available for brokers, e.g. eclipse-mosquitto; but, nearly all of them leave it up to the user to figure out how to secure the platform. This results in many developers simply ignoring security altogether for the sake of simplicity. Even more dangerous, many semi-technical home owners are now dabbling in the home automation space and due to the complexity of securing system, they are hanging IoT/automation devices on the internet completely unsecurred.
This docker image attempts to make it easier to implement a secure MQTT broker, either in the cloud or on premise. The secured broker can be used with home automation platforms like [Home Assistant](https://home-assistant.io/) or simply as a means of enabling secure IoT device communications.
For those interested in some of the nuts and bolts related to the integration, reference [Brian Boucheron's](https://www.digitalocean.com/community/users/bboucheron) excellent article [How to Install and Secure the Mosquitto MQTT Messaging Broker on Ubuntu 16.04](https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-the-mosquitto-mqtt-messaging-broker-on-ubuntu-16-04) which servered as a reference in creating this image.
## Standing up a server
A straigtforward way of standing up a server is to use [docker-compose](https://docs.docker.com/compose/). Here is a sample [docker-compose.yml](https://docs.docker.com/compose/compose-file/) file:
```
version: '2'
services:
mqtt:
image: bitrox/alpine-mosquitto-certbot
networks:
- backend-net
ports:
- 1883:1883
- 8083:8083
- 8883:8883
- 80:80
environment:
- DOMAIN=mqtt.myserver.com
- EMAIL=myemail@myprovider.com
volumes:
- ./mosquitto/conf/:/mosquitto/conf
- ./mosquitto/log/:/mosquitto/log
- ./letsencrypt:/etc/letsencrypt
- ./scripts:/scripts
container_name: mqtt
restart: always
networks:
backend-net:
external:
name: backend-net
```
In this case, four ports are exposed, which we'll go over in more detail when describing how this configuration matches that of the mosquitto.conf file. The first three ports are associated with Mosquitto, the forth port mapping (80:80) allows Certbot/LetsEncrypt to verify the DOMAIN. Also shown in the yml file is a backend-net network, which you many or may not have implemented with your particular Docker environment (Docker networking is WAY beyond the scope of this discussion).
## Environment Variables
There are three environment variables useable with this image. DOMAIN and EMAIL are required for Certbot/[Letencrypt](https://letsencrypt.org/) to obtain certificates necessary for secure communications. The third, TESTCERT, is optional.
**DOMAIN** - This should be defined as your fully qualified domain name, i.e. mqtt.myserver.com. The domain needs to point to your server as LetsEncrypt will verify such when obtaining certificates.
**EMAIL** - This simply needs to be an email address. It's required by certbot/LetsEncrypt to obtain certificates.
**TESTCERT** - This variable can be set to any value (e.g. TRUE). When defined, the image will utilize certbot/LetsEncrypt --staging server and obtain non-valid test-certs. It will also use --dry-run when simulating certificate renewal. The variable's utility is in the fact that it enables the user to configure and test/debug the process of obtaining certificates without running into the fairly low hourly limits imposed by LetsEncrypt. Example: If the service is configured correctly, but the server isn't reachable on port 80 due to an incorrectly configured firewall, TESTCERT defined will reveal this fact without attempting to obtain a real certificate.
## Volumes (persistence)
The scripts associated with this image assume a standard directory structure for mosquitto configuration and certbot/LetsEncrypt. It is possible to deviate from the below defined standard, but doing so should be left to those more familiar with Docker and Mosquitto.
```
/mosquitto/conf/
mosquitto.conf
passwd
/mosquitto/log/
/letsencrypt/
```
The docker-compose.yml file shown above maps local (persistent) directories to the relevant container volumes:
**/mosquitto/conf/** - this directory is where Mosquitto will look for the mosquitto.conf file.
**/mosquitto/conf/mosquitto.conf** - this file is user supplied. The startup scripts will look for exactly this file in exactly this directory. If it isn't found, the container will exit with appropriate error messages.
**/mosquitto/conf/passwd** - this file is the standard location for Mosquitto users/passwords. An alternate file/location can be specified in mosquitto.conf, but it must be in a location persisted through docker volume mapping. It's presence/use is optional, but allowing anonymous access to MQTT somewhat defeats the purpose of this image.
**/mosquitto/log** - This directory is the location where mosquitto will place log file(s). Like passwd defined above, its use is optional and can be controlled based on the contents of mosquitto.conf.
**/letsencrypt** - This directory is where certbot/LetsEncrypt will place retrieved certificates. The certbot scripts specifically require/expect this directory to exist in the container, so it should be mapped.
**/scripts** - To enable customization of the container, the run.sh script looks for this directory. If it finds /scripts, it will look inside the directory for any file ending in .sh, e.g. myscript.sh. It will then attempt to execuite said script(s) during container startup, immediately after dealing with certbot/LetsEncrypt, but before starting Mosquitto. Scripts found will be executed in alpha order. A suggested naming convention for scripts include a number followed by a dash, then the script name, ending in .sh, e.g. 00-myfirstscript.sh, 01-mysecondscript.sh, etc. This will ensure your scripts are executed in the order intended. An example of this functionality would be if you want additional software/utilities in the container.
The sample docker-compose.yml file shows a local directory ./scripts mapped to the container volume /scripts where run.sh will look for the above discussed user scripts to run at startup.
## Certbot/LetsEncrypt Integration
At container startup, scripts will look to see if certificates for DOMAIN exist in /letsencrypt. If it doesn't find any certificates, it will attempt to obtain them (via certbot certonly --standalone --agree-tos --standalone-supported-challenges http-01 -n -d $DOMAIN -m $EMAIL).
If certificates do exist, then an attempt will be made to renew them (via certbot renew).
Once a week, scripts will be run to check to see if the certificates need renewal. If so, they will be renewed, then the mosquitto server will be restarted so that it picks up the new certificates. Unfortunately, this does mean that there will be a brief (few second) outage each time certificates are in fact renewed. Adjust use cases for this server accordingly.
## mosquitto.conf
Documentation for Mosquitto should be consulted for details on how to properly configure this file. However, below is a sample configuration file that matches the docker-compose.yml shown above.
In the below configuration, we make mosquitto available via three different ports. Port 1883 uses the standard mqtt protocol. It is accessible without TLS/SSL, but does require user id/password verification (defined in /mosquitto/conf/passwd). The use case for 1883 is that it is expose internally to other processes/servers on a private network. Port 8883 provides accessiblity via the mqtt protocol, but requires TLS/SSL. The use case is that port 8883 is exposed to the internet, accessible via DOMAIN. And lastly, port 8083 allows the server to be accessed via websockets. It also requires TLS/SSL. Again it's use case would be that port 8083 is exposed to the internet, accessible via DOMAIN.
Logging is enabled and the directory for storing log files is defined as /mosquitto/log. The highest level of detail for logging is enabled. Consult [Mosquitto documentation](https://mosquitto.org/documentation/) for the logging parameters if you want a lesser level of logging turned on once you have the server debugged and integrated with your other devices/software.
Anonymous access to the server is disabled, indicating all connections must be validated via user id/password.
```
# Config file for mosquitto
#
# See mosquitto.conf(5) for more information.
#
# =================================================================
# General configuration
# =================================================================
# When run as root, drop privileges to this user and its primary
# group.
# Leave blank to stay as root, but this is not recommended.
# If run as a non-root user, this setting has no effect.
# Note that on Windows this has no effect and so mosquitto should
# be started by the user you wish it to run as.
user mosquitto
# =================================================================
# Default listener
# =================================================================
port 1883
protocol mqtt
# =================================================================
# Extra listeners
# =================================================================
listener 8083
protocol websockets
cafile /etc/letsencrypt/live/mqtt.bitrox.io/chain.pem
certfile /etc/letsencrypt/live/mqtt.bitrox.io/fullchain.pem
keyfile /etc/letsencrypt/live/mqtt.bitrox.io/privkey.pem
listener 8883
protocol mqtt
cafile /etc/letsencrypt/live/mqtt.bitrox.io/chain.pem
certfile /etc/letsencrypt/live/mqtt.bitrox.io/fullchain.pem
keyfile /etc/letsencrypt/live/mqtt.bitrox.io/privkey.pem
# =================================================================
# Logging
# =================================================================
log_dest file /mosquitto/log/mosquitto.log
log_type all
websockets_log_level 255
connection_messages true
log_timestamp true
# =================================================================
# Security
# =================================================================
allow_anonymous false
# -----------------------------------------------------------------
# Default authentication and topic access control
# -----------------------------------------------------------------
# Control access to the broker using a password file. This file can be
# generated using the mosquitto_passwd utility.
password_file /mosquitto/conf/passwd
## Generating User ID/Password
Mosquitto provides a utility (mosquitto_passwd) for adding users to a password file with encrypted passwords. Assuming the passwd file is in the standard location as shown in the mosquitto.conf file above, you can add a user/password combination (e.g. booboy myPwd123) to the file once the docker container is up and running, using the following command:
docker exec -it mqtt mosquitto_passwd -b /mosquitto/conf/passwd booboy myPwd123
This command doesn't provide any feedback if successful, but does show errors if there are problems. You can verify success simply looking in the passwd file. You should see an entry similar to: booboy:$6$+NKkI0p3oZmSukn9$mOUEEHUizK2zqc8Hk2l0JlHHXTW8GPzSonP9Ujrjhs1tVNQqN3lGCAFcFKnpJefOjUPwjqE5mZ
qSjBl6BCKnPA==
```
## Testing Your Server
To test your server locally (i.e. within the container), you can pop into the container and use mosquitto_pub and mosquitto_sub. Note that you'll need to do this from two separate terminal sessions so see the effect. If you receive error messages, look in the mosquitto error log (/mosquitto/log) for diagnostic information. You should also make sure the container came up properly using a command like:
```
docker logs mqtt
```
For the MQTT subscriber:
```
docker exec -it mqtt /bin/bash
mosquitto_sub -h <yourserveraddr> -u "booboy" -P "myPwd123" -t "testQueue"
```
The mosquitto_sub command will block waiting for messages from ++testQueue++.
To publish a message to ++testQueue++, open another terminal and use the following:
```
docker exec -it mqtt /bin/bash
mosquitto_pub -h <yourserveraddr> -u "booboy" -P "myPwd123" -t "testQueue" -m "Hello subscribers to testQueue!"
```
In the first (subscriber) terminal window, you should immediately see the message "Hello subscribers to testQueue!".
To test remotely, [mqtt-admin](https://hobbyquaker.github.io/mqtt-admin/) by [Sebastian Raff](https://hobbyquaker.github.io) is an excellent resource. Note that you need to make sure any filewalls/routers between your container and the internet are properly configured to route requests on the ports specified before attempting to use mqtt-admin.

65
certbot.sh Executable file
View File

@ -0,0 +1,65 @@
#!/bin/bash
# Check to see if certs for the specified domain exist
# Attempt to retrieve certs if missing or
# if present attempt to renew them
#
# WARNING:
# This script is called weekly from /etc/periodic/weekly/croncert.sh
#
# Duing the weekly check, if certs are renewed,
# the mosquitto process is restarted, causing
# a brief (few second) unavoidable service disruption
#
# If the environment varialbe TESTCERT is defined, this script
# will use --staging --test-cert for obtaining a cert and --dry-run for renewal
# This allows the user to test out the configuration and connectivity for obtaining
# certs without running into LetsEncrypt limits. It's advisable to define TESTCERT
# when initially bringing up the container. Once the logs (docker logs <containername>)
# show that LetsEncrypt is working fine, then remove TESTCERT environment variable
# to let this script obtain and manage the real certificates
#
FOLDER="/etc/letsencrypt/live/$DOMAIN"
echo "Dealing with certificates..."
echo "Location: $FOLDER"
if [ -d "$FOLDER" ]; then
echo "Certificates exist, attempting to renew..."
if [ ! -z "$TESTCERT" ]; then
echo "Renew dry run ..."
certbot renew --dry-run --noninteractive --post-hook "/restart.sh"
else
echo "Renew certs ..."
certbot renew --noninteractive --post-hook "/restart.sh"
fi
else
if [ ! -z "$DOMAIN" ]; then
if [ ! -z "$EMAIL" ]; then
if [ ! -z "$TESTCERT" ]; then
echo "Obtaining TEST cert for $DOMAIN"
certbot certonly \
--staging \
--test-cert \
--standalone \
--agree-tos \
--standalone-supported-challenges http-01 \
-n \
-d $DOMAIN \
-m $EMAIL
else
echo "Obtaining cert for $DOMAIN"
certbot certonly \
--standalone \
--agree-tos \
--standalone-supported-challenges http-01 \
-n \
-d $DOMAIN \
-m $EMAIL
fi
else
echo 'ERROR: $EMAIL must be defined'
fi
else
echo 'ERROR: $DOMAIN must be defined'
fi
fi

4
croncert.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
echo "Checking on certificates..."
/certbot.sh

10
restart.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/bash
ps cax | grep mosquitto > /dev/null
if [ $? -eq 0 ]; then
echo "Mosquitto is running."
pkill -f "mosquitto"
sleep 1
/usr/sbin/mosquitto -c /mosquitto/conf/mosquitto.conf&
else
echo "Mosquitto is not running."
fi

74
run.sh Executable file
View File

@ -0,0 +1,74 @@
#!/bin/bash
# Check and if needed install/renew certs
# Note that this script (certbot.sh) is also
# run weekely from /etc/periodic/weekly/croncert.sh
#
# WARNING:
# Duing the weekly check, if certs are renewed,
# the mosquitto process is restarted, causing
# a brief (few second) unavoidable service disruption
#
/certbot.sh
# This script assumes a standard persistent directory and file layout of:
# /mosquitto/
# conf/
# mosquitto.conf - the main configuation file
# passwd - the password file
# log/
#
# The presense and location of mosquitto.conf isn't optional.
# (We could allow user definition via environment var, but honestly why bother)
#
# The location of the log directory and passwd file can be
# mapped differently in mosquitto.conf. If so, this script will
# simply generate warnings, but continue to function.
#
if [ ! -d "/mosquitto/log" ]; then
echo "WARNING: missing /mosquitto/log directory"
echo "WARNING: ignore if your mosquitto.conf has a non-standard configuration"
fi
# create blank passwd if it doesn't exist
if [ -d "/mosquitto/conf" ]; then
if [ ! -f "/mosquitto/conf/passwd" ]; then
echo "Creating blank passwd file at /mosquitto/conf/passwd"
touch /mosquitto/conf/passwd
fi
else
echo "WARNING: /mosquitto/conf should be mapped to persistent docker volume"
echo "WARNING: ignore if your mosquitto.conf has a non-standard configuration"
fi
# execute any pre-exec scripts, useful for customization of images
if [ -d "/scripts" ]; then
echo "Looking for user scripts to execute..."
for i in /scripts/*sh
do
if [ -e "${i}" ]; then
echo "Found user script - processing $i"
. "${i}"
fi
done
fi
echo "Starting mosquitto process (daemon)..."
if [ -f "/mosquitto/conf/mosquitto.conf" ]; then
# Note that this method of starting mosquitto results in the process
# not receiving the SIGTERM signal from Docker on shutdown. This is
# nessary because mosquitto must be restarted automatically when
# certificates are renewed. In other words, we need the container to
# continue running beyond the life of the mosquitto process.
#
# A possible enhancement would be to include an "is alive" check
# for mosquitto to restart it if required or exit the container.
/usr/sbin/mosquitto -c /mosquitto/conf/mosquitto.conf&
echo "Going to sleep..."
# sleep infinity not available, so 9999d should be an acceptable substitute :-)
sleep 9999d
else
echo "ERROR: missing /mosquitto/conf/mosquitto.conf"
echo "ERROR: check your Docker volume mappings"
echo "Exiting..."
fi

25
sample/docker-compose.yml Executable file
View File

@ -0,0 +1,25 @@
version: '2'
services:
mqtt:
image: bitrox/mqtt
networks:
- backend-net
ports:
- 1883:1883
- 8083:8083
- 8883:8883
- 8116:80
environment:
- DOMAIN=mqtt.bitrox.io
- EMAIL=proxy@bitrox.io
volumes:
- ./mosquitto/conf/:/mosquitto/conf
- ./mosquitto/log/:/mosquitto/log
- ./letsencrypt:/etc/letsencrypt
- ./scripts:/scripts
container_name: mqtt
restart: always
networks:
backend-net:
external:
name: backend-net

64
sample/mosquitto.conf Executable file
View File

@ -0,0 +1,64 @@
# Config file for mosquitto
#
# See mosquitto.conf(5) for more information.
#
# =================================================================
# General configuration
# =================================================================
# When run as root, drop privileges to this user and its primary
# group.
# Leave blank to stay as root, but this is not recommended.
# If run as a non-root user, this setting has no effect.
# Note that on Windows this has no effect and so mosquitto should
# be started by the user you wish it to run as.
user mosquitto
# =================================================================
# Default listener
# =================================================================
port 1883
protocol mqtt
# =================================================================
# Extra listeners
# =================================================================
listener 8083
protocol websockets
cafile /etc/letsencrypt/live/mqtt.bitrox.io/chain.pem
certfile /etc/letsencrypt/live/mqtt.bitrox.io/fullchain.pem
keyfile /etc/letsencrypt/live/mqtt.bitrox.io/privkey.pem
listener 8883
protocol mqtt
cafile /etc/letsencrypt/live/mqtt.bitrox.io/chain.pem
certfile /etc/letsencrypt/live/mqtt.bitrox.io/fullchain.pem
keyfile /etc/letsencrypt/live/mqtt.bitrox.io/privkey.pem
# =================================================================
# Logging
# =================================================================
log_dest file /mosquitto/log/mosquitto.log
log_type all
websockets_log_level 255
connection_messages true
log_timestamp true
# =================================================================
# Security
# =================================================================
allow_anonymous false
# -----------------------------------------------------------------
# Default authentication and topic access control
# -----------------------------------------------------------------
# Control access to the broker using a password file. This file can be
# generated using the mosquitto_passwd utility.
password_file /mosquitto/conf/passwd