mosquitto icon indicating copy to clipboard operation
mosquitto copied to clipboard

Ship systemd unit for users with UNIX domain sockets

Open alexpdp7 opened this issue 1 month ago • 5 comments

This could be useful for local IPC for user software. UNIX domain sockets enable easy security (permissions can be set up so that only processes from the same user can access the socket), eliminate the need for port management (so multiple Mosquitto daemons for different users would not collide as TCP listening would).

(My use case was hooking up mic mute/unmute to an MQTT server. A user-bound MQTT server would be an easy way to expose mic mute/unmute as an API, and potentially replicate to a centralized MQTT server... while enabling local/offline operation.)

alexpdp7 avatar Dec 08 '25 18:12 alexpdp7

This is a reasonable request - I think it's better dealt with at the packaging level though. I'd be happy to offer something like this for the project provided debian packages, but would ideally like some thoughts from the official debian package maintainers on what a good practice here would be.

Would you be able to make any comment @rzr ?

ralight avatar Dec 09 '25 23:12 ralight

Would you be able to make any comment @rzr ?

Thank you for considering packaging perspective, I will need to investigate a bit policies regard users services, I don't think there is any blocker, but AFAIK the distro will/can not manage them (but eventually document them).

The question I have in mind now, are this users unit supposed to replace the system one ?

If no just go ahead at worst case they will be ignored (unpackaged) If yes I am reluctant to bring that major behavior change (it may impact also other packages depending on mosquito) if we can preserve the existing behavior we will also preserve the automated testsuites etc

For the record:

apt-cache rdepends  mosquitto
mosquitto
Reverse Depends:
  mosquitto-dev
  notus-scanner
  mosquitto-dev
  python3-berrynet

Same remarks should probably apply to other distros too.

cc: @narc-Ontakac2

rzr avatar Dec 09 '25 23:12 rzr

On my Debian system /usr/lib/systemd/user/ contains quite a few user services shipped by Debian, many of them provide a similar functionality to what I see a Mosquitto package would provide (I think the closest one is dbus).

For me, the user service would be completely independent from the system service. The system service would be meant for a system meant to provide a public MQTT service to other hosts, while the user service would serve as a backend for IPC between a user's processes.

alexpdp7 avatar Dec 10 '25 18:12 alexpdp7

This should be doable. There might however be details we need to take care of. The first that comes to mind is: Do we give a reasonable error message if ~/.config/mosquitto/mosquitto.conf is not found? This immediately raises the second one: Where do we put this error message?

@alexpdp7 Could you please elaborate more on the use case.

narc-Ontakac2 avatar Dec 11 '25 05:12 narc-Ontakac2

Systemd services can just print their errors; systemctl status shows the last output of failed services.

My use case is the following:

I'm working with a Firefox extension that can control online conferencing tools (e.g. expose mute status).

A websockets-aware MQTT server seems like a great option to bridge this extension to other tools:

  • A Firefox extension can't do so much to communicate with other processes, so I can't use dbus, for example
  • The MQTT ecosystem has many useful things for this kind of thing, such as Homie. So I could use any Homie-aware tool to control mute.
  • I can also easily write a command-line tool to control mute that I can bind to a global hotkey.

A user service is cool because then I don't need root to manage the MQTT server.

(I'm also seeing alternatives- there's dbus websocket proxies, for example.)

alexpdp7 avatar Dec 11 '25 08:12 alexpdp7

I have a user service configuration that at least starts.

/usr/lib/systemd/user/mosquitto.service

[Unit]
Description=Mosquitto MQTT Broker for %u
Documentation=man:mosquitto.conf(5) man:mosquitto(8)

[Service]
Type=notify
NotifyAccess=main
ExecStart=/usr/sbin/mosquitto -c %E/mosquitto/mosquitto.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
ExecStartPre=/usr/share/mosquitto/user/bin/init "%E" "%t" "%S" "%L"

# Hardening
SystemCallArchitectures=native
MemoryDenyWriteExecute=true
NoNewPrivileges=true

[Install]
WantedBy=default.target

with /usr/share/mosquitto/user/bin/init

#!/bin/sh

export CONF=$1        # %E
export RUN=$2         # %t 
export STATE=$3       # %S
export LOG=$4         # %L

if [ -f ${CONF}/mosquitto/mosquitto.conf ]; then
	exit;
fi

mkdir -m 750 -p ${LOG}/mosquitto
mkdir -m 750 -p ${RUN}/mosquitto
mkdir -m 750 -p ${STATE}/mosquitto
envsubst < /usr/share/mosquitto/user/config/mosquitto.conf > ${CONF}/mosquitto/mosquitto.conf 

and the configuration template /usr/share/mosquitto/user/config/mosquitto.conf

# Configuration template for the mosquitto user configuration
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf

listener 0 ${RUN}/mosquitto/mosquitto.socket 

pid_file ${RUN}/mosquitto/mosquitto.pid

persistence true
persistence_location ${STATE}/mosquitto

log_dest file ${LOG}/mosquitto/mosquitto.log

This is neither tested nor checked against Debian policies. It should however be good enough to see if it fits the use case.

narc-Ontakac2 avatar Dec 13 '25 09:12 narc-Ontakac2

I have packaged the above and uploaded it to my dev repo.

narc-Ontakac2 avatar Dec 13 '25 13:12 narc-Ontakac2