mirror of
https://github.com/aljazceru/addons.git
synced 2025-12-17 05:04:21 +01:00
mosquitto: 6.0.0 (#2007)
This commit is contained in:
@@ -1,5 +1,18 @@
|
||||
# Changelog
|
||||
|
||||
## 6.0.0
|
||||
|
||||
- Support for anonymous logins has been removed
|
||||
- Replaced Home Assistant authentication handling
|
||||
- Merged local account handling with authentication plugin
|
||||
- Add watchdog endpoint for health monitoring
|
||||
- Updated mosquitto to 1.6.12
|
||||
- Updated mosquitto auth plugin to 0.1.5
|
||||
- Migrate add-on layout to S6 Overlay
|
||||
- Migrate all script to use Bashio
|
||||
- Update base image to Alpine Linux 3.13
|
||||
- Add port descriptions
|
||||
|
||||
## 5.1.1
|
||||
|
||||
- Update options schema for passwords
|
||||
|
||||
@@ -36,7 +36,6 @@ Add-on configuration:
|
||||
|
||||
```yaml
|
||||
logins: []
|
||||
anonymous: false
|
||||
customize:
|
||||
active: false
|
||||
folder: mosquitto
|
||||
@@ -55,12 +54,6 @@ logins:
|
||||
password: passwd
|
||||
```
|
||||
|
||||
### Option: `anonymous`
|
||||
|
||||
Allow anonymous connections. If logins are set, the anonymous user can only read data. An explicit ACL definition is required for anonymous connections [see Access Control Lists (ACLs)](#access-control-lists-acls).
|
||||
|
||||
Default value: `false`
|
||||
|
||||
#### Option: `customize.active`
|
||||
|
||||
If set to `true` additional configuration files will be read, see the next option.
|
||||
@@ -91,7 +84,7 @@ If set to `true` encryption will be enabled using the cert- and keyfile options.
|
||||
|
||||
This add-on is attached to the Home Assistant user system, so MQTT clients can make use of these credentials. Local users may also still be set independently within the configuration options for the add-on. For the internal Home Assistant ecosystem, we register `homeassistant` and `addons`, so these may not be used as user names.
|
||||
|
||||
## Disable listening on insecure (1883) ports
|
||||
## Disable listening on insecure (1883/1884) ports
|
||||
|
||||
Remove the ports from the add-on page network card (set them as blank) to disable them.
|
||||
|
||||
@@ -126,18 +119,9 @@ Add the following configuration to enable **unrestricted** access to all topics.
|
||||
user [YOUR_MQTT_USER]
|
||||
topic readwrite #
|
||||
```
|
||||
For anonymous mode ( `"anonymous": true` ), you have to remove the `user [YOUR_MQTT_USER]` line like so:
|
||||
|
||||
```text
|
||||
topic readwrite #
|
||||
```
|
||||
|
||||
The `/share` folder can be accessed via SMB, or on the host filesystem under `/usr/share/hassio/share`.
|
||||
|
||||
## Known issues and limitations
|
||||
|
||||
- Since version 4.1 of the add-on, an explicit ACL definition is now required if you plan to use legacy logins and `"anonymous": true` [see these instructions](#access-control-lists-acls).
|
||||
|
||||
## Support
|
||||
|
||||
Got questions?
|
||||
|
||||
@@ -5,12 +5,9 @@ FROM $BUILD_FROM
|
||||
WORKDIR /usr/src
|
||||
ARG MOSQUITTO_AUTH_VERSION
|
||||
RUN apk add --no-cache \
|
||||
curl \
|
||||
mosquitto \
|
||||
musl \
|
||||
openssl \
|
||||
nginx \
|
||||
pwgen \
|
||||
socat \
|
||||
&& apk add --no-cache --virtual .build-dependencies \
|
||||
build-base \
|
||||
curl-dev \
|
||||
@@ -20,19 +17,25 @@ RUN apk add --no-cache \
|
||||
\
|
||||
&& git clone --depth 1 -b "${MOSQUITTO_AUTH_VERSION}" \
|
||||
https://github.com/pvizeli/mosquitto-auth-plug \
|
||||
\
|
||||
&& cd mosquitto-auth-plug \
|
||||
&& cp config.mk.in config.mk \
|
||||
&& make \
|
||||
&& mkdir -p /usr/share/mosquitto \
|
||||
&& cp -f auth-plug.so /usr/share/mosquitto \
|
||||
&& cp -f np /usr/local/bin \
|
||||
\
|
||||
&& apk del .build-dependencies \
|
||||
&& rm -fr /usr/src/mosquitto-auth-plug
|
||||
&& apk del --no-cache .build-dependencies \
|
||||
&& rm -fr \
|
||||
/etc/logrotate.d \
|
||||
/etc/mosquitto/* \
|
||||
/etc/nginx/* \
|
||||
/usr/share/nginx \
|
||||
/usr/src/mosquitto-auth-plug \
|
||||
/var/lib/nginx/html \
|
||||
/var/www
|
||||
|
||||
# Copy data
|
||||
COPY data/run.sh /
|
||||
COPY data/auth_srv.sh /bin/
|
||||
COPY data/mosquitto.conf /etc/
|
||||
# Copy rootfs
|
||||
COPY rootfs /
|
||||
|
||||
WORKDIR /
|
||||
CMD [ "/run.sh" ]
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"build_from": {
|
||||
"aarch64": "homeassistant/aarch64-base:3.10",
|
||||
"amd64": "homeassistant/amd64-base:3.10",
|
||||
"armhf": "homeassistant/armhf-base:3.10",
|
||||
"armv7": "homeassistant/armv7-base:3.10",
|
||||
"i386": "homeassistant/i386-base:3.10"
|
||||
"aarch64": "ghcr.io/home-assistant/aarch64-base:3.13",
|
||||
"amd64": "ghcr.io/home-assistant/amd64-base:3.13",
|
||||
"armhf": "ghcr.io/home-assistant/armhf-base:3.13",
|
||||
"armv7": "ghcr.io/home-assistant/armv7-base:3.13",
|
||||
"i386": "ghcr.io/home-assistant/i386-base:3.13"
|
||||
},
|
||||
"args": {
|
||||
"MOSQUITTO_AUTH_VERSION": "0.1.4"
|
||||
"MOSQUITTO_AUTH_VERSION": "0.1.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Mosquitto broker",
|
||||
"version": "5.1.1",
|
||||
"version": "6.0.0",
|
||||
"slug": "mosquitto",
|
||||
"description": "An Open Source MQTT broker",
|
||||
"url": "https://github.com/home-assistant/hassio-addons/tree/master/mosquitto",
|
||||
@@ -9,6 +9,7 @@
|
||||
"map": ["ssl", "share"],
|
||||
"discovery": ["mqtt"],
|
||||
"services": ["mqtt:provide"],
|
||||
"watchdog": "tcp://[HOST]:1883",
|
||||
"auth_api": true,
|
||||
"ports": {
|
||||
"1883/tcp": 1883,
|
||||
@@ -16,9 +17,14 @@
|
||||
"8883/tcp": 8883,
|
||||
"8884/tcp": 8884
|
||||
},
|
||||
"ports_description": {
|
||||
"1883/tcp": "Normal MQTT",
|
||||
"1884/tcp": "MQTT over WebSocket",
|
||||
"8883/tcp": "Normal MQTT with SSL",
|
||||
"8884/tcp": "MQTT over WebSocket with SSL"
|
||||
},
|
||||
"options": {
|
||||
"logins": [],
|
||||
"anonymous": false,
|
||||
"customize": {
|
||||
"active": false,
|
||||
"folder": "mosquitto"
|
||||
@@ -28,8 +34,12 @@
|
||||
"require_certificate": false
|
||||
},
|
||||
"schema": {
|
||||
"logins": [{ "username": "str", "password": "password" }],
|
||||
"anonymous": "bool",
|
||||
"logins": [
|
||||
{
|
||||
"username": "str",
|
||||
"password": "password"
|
||||
}
|
||||
],
|
||||
"customize": {
|
||||
"active": "bool",
|
||||
"folder": "str"
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
#!/usr/bin/env bashio
|
||||
# shellcheck disable=SC2244,SC1117
|
||||
set +u
|
||||
set -e
|
||||
|
||||
CONFIG_PATH=/data/options.json
|
||||
SYSTEM_USER=/data/system_user.json
|
||||
REQUEST=()
|
||||
REQUEST_BODY=""
|
||||
LOGGING=$(bashio::info.logging)
|
||||
|
||||
declare -A LOCAL_DB
|
||||
|
||||
## Functions
|
||||
|
||||
function http_ok() {
|
||||
echo -e "HTTP/1.1 200 OK\n"
|
||||
exit 0
|
||||
}
|
||||
|
||||
function http_error() {
|
||||
echo -e "HTTP/1.1 400 Bad Request\n"
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
||||
function create_userdb() {
|
||||
local logins=0
|
||||
local username=""
|
||||
local password=""
|
||||
local hass_pw=""
|
||||
local addons_pw=""
|
||||
|
||||
logins=$(jq --raw-output '.logins | length' $CONFIG_PATH)
|
||||
for (( i=0; i < "$logins"; i++ )); do
|
||||
username="$(jq --raw-output ".logins[$i].username" $CONFIG_PATH)"
|
||||
password="$(jq --raw-output ".logins[$i].password" $CONFIG_PATH)"
|
||||
|
||||
LOCAL_DB["${username}"]="${password}"
|
||||
done
|
||||
|
||||
# Add system user to DB
|
||||
hass_pw=$(jq --raw-output '.homeassistant.password' $SYSTEM_USER)
|
||||
addons_pw=$(jq --raw-output '.addons.password' $SYSTEM_USER)
|
||||
|
||||
LOCAL_DB['homeassistant']="${hass_pw}"
|
||||
LOCAL_DB['addons']="${addons_pw}"
|
||||
}
|
||||
|
||||
|
||||
function read_request() {
|
||||
local content_length=0
|
||||
|
||||
while read -r line; do
|
||||
line="${line%%[[:cntrl:]]}"
|
||||
|
||||
if [[ "${line}" =~ Content-Length ]]; then
|
||||
content_length="${line//[!0-9]/}"
|
||||
fi
|
||||
|
||||
if [ -z "$line" ]; then
|
||||
if [ "${content_length}" -gt 0 ]; then
|
||||
read -r -n "${content_length}" REQUEST_BODY
|
||||
fi
|
||||
break
|
||||
fi
|
||||
|
||||
REQUEST+=("$line")
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
function get_var() {
|
||||
local variable=$1
|
||||
local value=""
|
||||
urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
|
||||
|
||||
# shellcheck disable=SC2001
|
||||
value="$(echo "$REQUEST_BODY" | sed "s/.*$variable=\([^&]*\).*/\1/g")"
|
||||
urldecode "${value}"
|
||||
}
|
||||
|
||||
|
||||
## MAIN ##
|
||||
bashio::log.level "${LOGGING}"
|
||||
|
||||
read_request
|
||||
|
||||
# This feature currently not implemented, we response with 200
|
||||
if [[ "${REQUEST[0]}" =~ /superuser ]] || [[ "${REQUEST[0]}" =~ /acl ]]; then
|
||||
http_ok
|
||||
fi
|
||||
|
||||
# We read now the user data
|
||||
create_userdb
|
||||
|
||||
username="$(get_var username)"
|
||||
password="$(get_var password)"
|
||||
|
||||
# If local user
|
||||
if [ "${LOCAL_DB["${username}"]}" == "${password}" ]; then
|
||||
bashio::log.info "[INFO] found ${username} on local database"
|
||||
http_ok
|
||||
elif [ ${LOCAL_DB["${username}"]+_} ]; then
|
||||
bashio::log.warning "[WARN] Not found ${username} on local database"
|
||||
http_error
|
||||
fi
|
||||
|
||||
# Ask HomeAssistant Auth
|
||||
auth_header="X-Hassio-Key: ${HASSIO_TOKEN}"
|
||||
content_type="Content-Type: application/x-www-form-urlencoded"
|
||||
|
||||
if curl -s -f -X POST -d "${REQUEST_BODY}" -H "${content_type}" -H "${auth_header}" http://hassio/auth > /dev/null; then
|
||||
bashio::log.info "[INFO] found ${username} on Home Assistant"
|
||||
http_ok
|
||||
fi
|
||||
|
||||
bashio::log.error "[ERROR] Auth error with ${username}"
|
||||
http_error
|
||||
@@ -1,41 +0,0 @@
|
||||
##
|
||||
# defaults
|
||||
protocol mqtt
|
||||
user root
|
||||
|
||||
##
|
||||
# logging
|
||||
log_dest stdout
|
||||
log_type error
|
||||
log_type warning
|
||||
log_type notice
|
||||
log_type information
|
||||
|
||||
##
|
||||
# datastore
|
||||
persistence true
|
||||
persistence_location /data/
|
||||
|
||||
##
|
||||
# User settings
|
||||
auth_plugin /usr/share/mosquitto/auth-plug.so
|
||||
auth_opt_backends http
|
||||
auth_opt_http_ip 127.0.0.1
|
||||
auth_opt_http_port 8080
|
||||
auth_opt_http_getuser_uri /login
|
||||
auth_opt_http_superuser_uri /superuser
|
||||
auth_opt_http_aclcheck_uri /acl
|
||||
auth_opt_log_quiet %%AUTH_QUIET_LOGS%%
|
||||
auth_opt_auth_cacheseconds 300
|
||||
|
||||
allow_anonymous %%ANONYMOUS%%
|
||||
|
||||
#include_dir /share/mosquitto
|
||||
|
||||
listener 1883
|
||||
protocol mqtt
|
||||
|
||||
listener 1884
|
||||
protocol websockets
|
||||
|
||||
# Follow SSL listener if a certificate exists
|
||||
@@ -1,177 +0,0 @@
|
||||
#!/usr/bin/env bashio
|
||||
set +u
|
||||
|
||||
CONFIG_PATH=/data/options.json
|
||||
SYSTEM_USER=/data/system_user.json
|
||||
|
||||
LOGINS=$(jq --raw-output ".logins | length" $CONFIG_PATH)
|
||||
ANONYMOUS=$(jq --raw-output ".anonymous" $CONFIG_PATH)
|
||||
KEYFILE=$(jq --raw-output ".keyfile" $CONFIG_PATH)
|
||||
CERTFILE=$(jq --raw-output ".certfile" $CONFIG_PATH)
|
||||
CAFILE=$(jq --raw-output --exit-status ".cafile | select (.!=null)" $CONFIG_PATH || echo "$CERTFILE")
|
||||
REQUIRE_CERTIFICATE=$(jq --raw-output ".require_certificate" $CONFIG_PATH)
|
||||
CUSTOMIZE_ACTIVE=$(jq --raw-output ".customize.active" $CONFIG_PATH)
|
||||
LOGGING=$(bashio::info 'hassio.info.logging' '.logging')
|
||||
HOMEASSISTANT_PW=
|
||||
ADDONS_PW=
|
||||
WAIT_PIDS=()
|
||||
|
||||
SSL_CONFIG="
|
||||
listener 8883
|
||||
protocol mqtt
|
||||
cafile /ssl/$CAFILE
|
||||
certfile /ssl/$CERTFILE
|
||||
keyfile /ssl/$KEYFILE
|
||||
require_certificate $REQUIRE_CERTIFICATE
|
||||
|
||||
listener 8884
|
||||
protocol websockets
|
||||
cafile /ssl/$CAFILE
|
||||
certfile /ssl/$CERTFILE
|
||||
keyfile /ssl/$KEYFILE
|
||||
require_certificate $REQUIRE_CERTIFICATE
|
||||
"
|
||||
|
||||
function write_system_users() {
|
||||
(
|
||||
echo "{\"homeassistant\": {\"password\": \"$HOMEASSISTANT_PW\"}, \"addons\": {\"password\": \"$ADDONS_PW\"}}"
|
||||
) > "${SYSTEM_USER}"
|
||||
}
|
||||
|
||||
function call_hassio() {
|
||||
local method=$1
|
||||
local path=$2
|
||||
local data="${3}"
|
||||
local token=
|
||||
|
||||
token="X-Hassio-Key: ${HASSIO_TOKEN}"
|
||||
url="http://hassio/${path}"
|
||||
|
||||
# Call API
|
||||
if [ -n "${data}" ]; then
|
||||
curl -f -s -X "${method}" -d "${data}" -H "${token}" "${url}"
|
||||
else
|
||||
curl -f -s -X "${method}" -H "${token}" "${url}"
|
||||
fi
|
||||
|
||||
return $?
|
||||
}
|
||||
|
||||
function constrain_host_config() {
|
||||
local user=$1
|
||||
local password=$2
|
||||
|
||||
echo "{"
|
||||
echo " \"host\": \"$(hostname)\","
|
||||
echo " \"port\": 1883,"
|
||||
echo " \"ssl\": false,"
|
||||
echo " \"protocol\": \"3.1.1\","
|
||||
echo " \"username\": \"${user}\","
|
||||
echo " \"password\": \"${password}\""
|
||||
echo "}"
|
||||
}
|
||||
|
||||
function constrain_discovery() {
|
||||
local user=$1
|
||||
local password=$2
|
||||
local config=
|
||||
|
||||
config="$(constrain_host_config "${user}" "${password}")"
|
||||
echo "{"
|
||||
echo " \"service\": \"mqtt\","
|
||||
echo " \"config\": ${config}"
|
||||
echo "}"
|
||||
}
|
||||
|
||||
## Main ##
|
||||
bashio::log.level "${LOGGING}"
|
||||
|
||||
bashio::log.info "Setup mosquitto configuration"
|
||||
sed -i "s/%%ANONYMOUS%%/$ANONYMOUS/g" /etc/mosquitto.conf
|
||||
|
||||
if [ "${LOGGING}" == "debug" ]; then
|
||||
sed -i "s/%%AUTH_QUIET_LOGS%%/false/g" /etc/mosquitto.conf
|
||||
else
|
||||
sed -i "s/%%AUTH_QUIET_LOGS%%/true/g" /etc/mosquitto.conf
|
||||
if [ "${LOGGING}" == "critical" ] || [ "${LOGGING}" == "fatal" ] || [ "${LOGGING}" == "error" ]; then
|
||||
sed -i -e "s/^log_type warning//" -e "s/^log_type notice//" -e "s/^log_type information//" /etc/mosquitto.conf
|
||||
elif [ "${LOGGING}" == "warning" ] || [ "${LOGGING}" == "warn" ]; then
|
||||
sed -i -e "s/^log_type notice//" -e "s/^log_type information//" /etc/mosquitto.conf
|
||||
fi
|
||||
fi
|
||||
|
||||
# Enable SSL if exists configs
|
||||
if [ -e "/ssl/$CAFILE" ] && [ -e "/ssl/$CERTFILE" ] && [ -e "/ssl/$KEYFILE" ]; then
|
||||
echo "$SSL_CONFIG" >> /etc/mosquitto.conf
|
||||
else
|
||||
bashio::log.warning "SSL not enabled - No valid certs found!"
|
||||
fi
|
||||
|
||||
# Allow customize configs from share
|
||||
if [ "$CUSTOMIZE_ACTIVE" == "true" ]; then
|
||||
CUSTOMIZE_FOLDER=$(jq --raw-output ".customize.folder" $CONFIG_PATH)
|
||||
sed -i "s|#include_dir .*|include_dir /share/$CUSTOMIZE_FOLDER|g" /etc/mosquitto.conf
|
||||
fi
|
||||
|
||||
# Handle local users
|
||||
if [ "$LOGINS" -gt "0" ]; then
|
||||
bashio::log.info "Found local users inside config"
|
||||
else
|
||||
bashio::log.info "No local user available"
|
||||
fi
|
||||
|
||||
# Prepare System Accounts
|
||||
if [ ! -e "${SYSTEM_USER}" ]; then
|
||||
HOMEASSISTANT_PW="$(pwgen 64 1)"
|
||||
ADDONS_PW="$(pwgen 64 1)"
|
||||
|
||||
bashio::log.info "Initialize system configuration."
|
||||
write_system_users
|
||||
else
|
||||
HOMEASSISTANT_PW=$(jq --raw-output '.homeassistant.password' $SYSTEM_USER)
|
||||
ADDONS_PW=$(jq --raw-output '.addons.password' $SYSTEM_USER)
|
||||
fi
|
||||
|
||||
# Initial Service
|
||||
if call_hassio GET "services/mqtt" | jq --raw-output ".data.host" | grep -v "$(hostname)" > /dev/null; then
|
||||
bashio::log.warning "There is already an MQTT service running!"
|
||||
else
|
||||
bashio::log.info "Initialize Home Assistant Add-on services"
|
||||
if ! call_hassio POST "services/mqtt" "$(constrain_host_config addons "${ADDONS_PW}")" > /dev/null; then
|
||||
bashio::log.error "Can't setup Home Assistant service mqtt"
|
||||
fi
|
||||
|
||||
bashio::log.info "Initialize Home Assistant discovery"
|
||||
if ! call_hassio POST "discovery" "$(constrain_discovery homeassistant "${HOMEASSISTANT_PW}")" > /dev/null; then
|
||||
bashio::log.error "Can't setup Home Assistant discovery mqtt"
|
||||
fi
|
||||
fi
|
||||
|
||||
bashio::log.info "Start Mosquitto daemon"
|
||||
|
||||
# Start Auth Server
|
||||
socat TCP-LISTEN:8080,fork,reuseaddr SYSTEM:/bin/auth_srv.sh &
|
||||
WAIT_PIDS+=($!)
|
||||
|
||||
# Start Mosquitto Server
|
||||
mosquitto -c /etc/mosquitto.conf &
|
||||
WAIT_PIDS+=($!)
|
||||
|
||||
# Handling Closing
|
||||
function stop_mqtt() {
|
||||
bashio::log.info "Shutdown mqtt system"
|
||||
kill -15 "${WAIT_PIDS[@]}"
|
||||
|
||||
# Remove service
|
||||
if call_hassio GET "services/mqtt" | jq --raw-output ".data.host" | grep "$(hostname)" > /dev/null; then
|
||||
if ! call_hassio DELETE "services/mqtt"; then
|
||||
bashio::log.warning "Service unregister fails!"
|
||||
fi
|
||||
fi
|
||||
|
||||
wait "${WAIT_PIDS[@]}"
|
||||
}
|
||||
trap "stop_mqtt" SIGTERM SIGHUP
|
||||
|
||||
# Wait and hold Add-on running
|
||||
wait "${WAIT_PIDS[@]}"
|
||||
84
mosquitto/rootfs/etc/cont-init.d/mosquitto.sh
Normal file
84
mosquitto/rootfs/etc/cont-init.d/mosquitto.sh
Normal file
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/with-contenv bashio
|
||||
# ==============================================================================
|
||||
# Configures mosquitto
|
||||
# ==============================================================================
|
||||
readonly ACL="/etc/mosquitto/acl"
|
||||
readonly PW="/etc/mosquitto/pw"
|
||||
readonly SYSTEM_USER="/data/system_user.json"
|
||||
declare cafile
|
||||
declare certfile
|
||||
declare discovery_password
|
||||
declare keyfile
|
||||
declare password
|
||||
declare service_password
|
||||
declare ssl
|
||||
declare username
|
||||
|
||||
# Read or create system account data
|
||||
if ! bashio::fs.file_exists "${SYSTEM_USER}"; then
|
||||
discovery_password="$(pwgen 64 1)"
|
||||
service_password="$(pwgen 64 1)"
|
||||
|
||||
# Store it for future use
|
||||
bashio::var.json \
|
||||
homeassistant "^$(bashio::var.json password "${discovery_password}")" \
|
||||
addons "^$(bashio::var.json password "${service_password}")" \
|
||||
> "${SYSTEM_USER}"
|
||||
else
|
||||
# Read the existing values
|
||||
discovery_password=$(bashio::jq "${SYSTEM_USER}" ".homeassistant.password")
|
||||
service_password=$(bashio::jq "${SYSTEM_USER}" ".addons.password")
|
||||
fi
|
||||
|
||||
# Set up discovery user
|
||||
password=$(np -p "${discovery_password}")
|
||||
echo "homeassistant:${password}" >> "${PW}"
|
||||
echo "user homeassistant" >> "${ACL}"
|
||||
|
||||
# Set up service user
|
||||
password=$(np -p "${service_password}")
|
||||
echo "addons:${password}" >> "${PW}"
|
||||
echo "user addons" >> "${ACL}"
|
||||
|
||||
# Set username and password for the broker
|
||||
for login in $(bashio::config 'logins|keys'); do
|
||||
bashio::config.require.username "logins[${login}].username"
|
||||
bashio::config.require.password "logins[${login}].password"
|
||||
|
||||
username=$(bashio::config "logins[${login}].username")
|
||||
password=$(bashio::config "logins[${login}].password")
|
||||
|
||||
bashio::log.info "Setting up user ${username}"
|
||||
password=$(np -p "${password}")
|
||||
echo "${username}:${password}" >> "${PW}"
|
||||
echo "user ${username}" >> "${ACL}"
|
||||
done
|
||||
|
||||
keyfile="/ssl/$(bashio::config 'keyfile')"
|
||||
certfile="/ssl/$(bashio::config 'certfile')"
|
||||
cafile="/ssl/$(bashio::config 'cafile')"
|
||||
if bashio::fs.file_exists "${certfile}" \
|
||||
&& bashio::fs.file_exists "${keyfile}";
|
||||
then
|
||||
bashio::log.info "Certificates found: SSL is available"
|
||||
ssl="true"
|
||||
if ! bashio::fs.file_exists "${cafile}"; then
|
||||
cafile="${certfile}"
|
||||
fi
|
||||
else
|
||||
bashio::log.info "SSL is not enabled"
|
||||
ssl="false"
|
||||
fi
|
||||
|
||||
# Generate mosquitto configuration.
|
||||
bashio::var.json \
|
||||
cafile "${cafile}" \
|
||||
certfile "${certfile}" \
|
||||
cutomize "^$(bashio::config 'customize.active')" \
|
||||
cutomize_folder "$(bashio::config 'customize.folder')" \
|
||||
keyfile "${keyfile}" \
|
||||
require_certificate "^$(bashio::config 'require_certificate')" \
|
||||
ssl "^${ssl}" \
|
||||
| tempio \
|
||||
-template /usr/share/tempio/mosquitto.gtpl \
|
||||
-out /etc/mosquitto/mosquitto.conf
|
||||
9
mosquitto/rootfs/etc/cont-init.d/nginx.sh
Normal file
9
mosquitto/rootfs/etc/cont-init.d/nginx.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/with-contenv bashio
|
||||
# ==============================================================================
|
||||
# Configures NGINX
|
||||
# ==============================================================================
|
||||
# This template only uses environment vars, no input
|
||||
echo "{}" \
|
||||
| tempio \
|
||||
-template /usr/share/tempio/nginx.gtpl \
|
||||
-out /etc/nginx/nginx.conf
|
||||
50
mosquitto/rootfs/etc/services.d/mosquitto/discovery
Executable file
50
mosquitto/rootfs/etc/services.d/mosquitto/discovery
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/with-contenv bashio
|
||||
# ==============================================================================
|
||||
# Send MQTT discovery information to Home Assistant and service information
|
||||
# to the Supervisor (for other add-ons).
|
||||
# ==============================================================================
|
||||
readonly SYSTEM_USER="/data/system_user.json"
|
||||
declare config
|
||||
declare discovery_password
|
||||
declare service_password
|
||||
|
||||
# Wait for mosquitti to start before continuing
|
||||
bashio::net.wait_for 1883
|
||||
|
||||
# Read the existing values
|
||||
discovery_password=$(bashio::jq "${SYSTEM_USER}" ".homeassistant.password")
|
||||
service_password=$(bashio::jq "${SYSTEM_USER}" ".addons.password")
|
||||
|
||||
# Create discovery config payload for Home Assistant
|
||||
config=$(bashio::var.json \
|
||||
host "$(hostname)" \
|
||||
port "^1883" \
|
||||
ssl "^false" \
|
||||
protocol "3.1.1" \
|
||||
username "homeassistant" \
|
||||
password "${discovery_password}" \
|
||||
)
|
||||
|
||||
# Send discovery info
|
||||
if bashio::discovery "mqtt" "${config}" > /dev/null; then
|
||||
bashio::log.info "Successfully send discovery information to Home Assistant."
|
||||
else
|
||||
bashio::log.error "Discovery message to Home Assistant failed!"
|
||||
fi
|
||||
|
||||
# Create service config payload for other add-ons
|
||||
config=$(bashio::var.json \
|
||||
host "$(hostname)" \
|
||||
port "^1883" \
|
||||
ssl "^false" \
|
||||
protocol "3.1.1" \
|
||||
username "addons" \
|
||||
password "${service_password}" \
|
||||
)
|
||||
|
||||
# Send service info
|
||||
if bashio::services.publish "mqtt" "${config}" > /dev/null 2>&1; then
|
||||
bashio::log.info "Successfully send service information to the Supervisor."
|
||||
else
|
||||
bashio::log.error "Service message to Supervisor failed!"
|
||||
fi
|
||||
8
mosquitto/rootfs/etc/services.d/mosquitto/finish
Normal file
8
mosquitto/rootfs/etc/services.d/mosquitto/finish
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/execlineb -S0
|
||||
# ==============================================================================
|
||||
# Take down the S6 supervision tree when mosquitto crashes
|
||||
# ==============================================================================
|
||||
if -n { s6-test $# -ne 0 }
|
||||
if -n { s6-test ${1} -eq 256 }
|
||||
|
||||
s6-svscanctl -t /var/run/s6/services
|
||||
20
mosquitto/rootfs/etc/services.d/mosquitto/run
Normal file
20
mosquitto/rootfs/etc/services.d/mosquitto/run
Normal file
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/with-contenv bashio
|
||||
# ==============================================================================
|
||||
# Runs mosquitto
|
||||
# ==============================================================================
|
||||
declare -a options
|
||||
|
||||
# Wait for NGINX to start before continuing (for authentication handling)
|
||||
bashio::net.wait_for 80
|
||||
|
||||
options+=(-c /etc/mosquitto/mosquitto.conf)
|
||||
|
||||
if bashio::debug; then
|
||||
options+=(-v)
|
||||
fi
|
||||
|
||||
# Send out discovery & service information
|
||||
./discovery &
|
||||
|
||||
bashio::log.info "Starting mosquitto MQTT broker..."
|
||||
exec mosquitto "${options[@]}"
|
||||
8
mosquitto/rootfs/etc/services.d/nginx/finish
Normal file
8
mosquitto/rootfs/etc/services.d/nginx/finish
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/execlineb -S0
|
||||
# ==============================================================================
|
||||
# Take down the S6 supervision tree when nginx crashes
|
||||
# ==============================================================================
|
||||
if -n { s6-test $# -ne 0 }
|
||||
if -n { s6-test ${1} -eq 256 }
|
||||
|
||||
s6-svscanctl -t /var/run/s6/services
|
||||
6
mosquitto/rootfs/etc/services.d/nginx/run
Normal file
6
mosquitto/rootfs/etc/services.d/nginx/run
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/with-contenv bashio
|
||||
# ==============================================================================
|
||||
# Runs the NGINX daemon
|
||||
# ==============================================================================
|
||||
bashio::log.info "Starting NGINX for authentication handling..."
|
||||
exec nginx
|
||||
67
mosquitto/rootfs/usr/share/tempio/mosquitto.gtpl
Normal file
67
mosquitto/rootfs/usr/share/tempio/mosquitto.gtpl
Normal file
@@ -0,0 +1,67 @@
|
||||
protocol mqtt
|
||||
user root
|
||||
log_dest stdout
|
||||
log_type error
|
||||
log_type warning
|
||||
log_type notice
|
||||
log_type information
|
||||
persistence true
|
||||
persistence_location /data/
|
||||
|
||||
# Authentication plugin
|
||||
auth_plugin /usr/share/mosquitto/auth-plug.so
|
||||
auth_opt_backends files,http
|
||||
auth_opt_cache true
|
||||
auth_opt_auth_cacheseconds 300
|
||||
auth_opt_auth_cachejitter 30
|
||||
auth_opt_acl_cacheseconds 300
|
||||
auth_opt_acl_cachejitter 30
|
||||
auth_opt_log_quiet true
|
||||
|
||||
# HTTP backend for the authentication plugin
|
||||
auth_opt_password_file /etc/mosquitto/pw
|
||||
auth_opt_acl_file /etc/mosquitto/acl
|
||||
|
||||
# HTTP backend for the authentication plugin
|
||||
auth_opt_http_ip 127.0.0.1
|
||||
auth_opt_http_port 80
|
||||
auth_opt_http_getuser_uri /authentication
|
||||
auth_opt_http_superuser_uri /superuser
|
||||
auth_opt_http_aclcheck_uri /acl
|
||||
|
||||
{{ if .customize }}
|
||||
include_dir /share/{{ .customize_folder }}
|
||||
{{ end }}
|
||||
|
||||
listener 1883
|
||||
protocol mqtt
|
||||
|
||||
listener 1884
|
||||
protocol websockets
|
||||
|
||||
{{ if .ssl }}
|
||||
|
||||
# Follow SSL listener if a certificate exists
|
||||
listener 8883
|
||||
protocol mqtt
|
||||
{{ if .cafile }}
|
||||
cafile {{ .cafile }}
|
||||
{{ else }}
|
||||
cafile {{ .certfile }}
|
||||
{{ end }}
|
||||
certfile {{ .certfile }}
|
||||
keyfile {{ .keyfile }}
|
||||
require_certificate {{ .require_certificate }}
|
||||
|
||||
listener 8884
|
||||
protocol websockets
|
||||
{{ if .cafile }}
|
||||
cafile {{ .cafile }}
|
||||
{{ else }}
|
||||
cafile {{ .certfile }}
|
||||
{{ end }}
|
||||
certfile {{ .certfile }}
|
||||
keyfile {{ .keyfile }}
|
||||
require_certificate {{ .require_certificate }}
|
||||
|
||||
{{ end }}
|
||||
49
mosquitto/rootfs/usr/share/tempio/nginx.gtpl
Normal file
49
mosquitto/rootfs/usr/share/tempio/nginx.gtpl
Normal file
@@ -0,0 +1,49 @@
|
||||
# Run nginx in foreground.
|
||||
daemon off;
|
||||
|
||||
# This is run inside Docker.
|
||||
user root;
|
||||
|
||||
# Pid storage location.
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
# Set number of worker processes.
|
||||
worker_processes 1;
|
||||
|
||||
# Write error log to the add-on log.
|
||||
error_log /proc/1/fd/1 error;
|
||||
|
||||
# Max num of simultaneous connections by a worker process.
|
||||
events {
|
||||
worker_connections 64;
|
||||
}
|
||||
|
||||
http {
|
||||
access_log off;
|
||||
gzip off;
|
||||
keepalive_timeout 65;
|
||||
server_tokens off;
|
||||
tcp_nodelay on;
|
||||
tcp_nopush on;
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:80 default_server;
|
||||
server_name _;
|
||||
|
||||
keepalive_timeout 5;
|
||||
root /dev/null;
|
||||
|
||||
location /authentication {
|
||||
proxy_set_header X-Supervisor-Token "{{ env "SUPERVISOR_TOKEN" }}";
|
||||
proxy_pass http://supervisor/auth;
|
||||
}
|
||||
|
||||
location = /superuser {
|
||||
return 200;
|
||||
}
|
||||
|
||||
location = /acl {
|
||||
return 200;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user