I can think of two ways to do this:
One is by making the service a user service rather than a system service.
Instead of creating a system unit, the systemd unit will be placed under the service user's home directory, at $HOME/.config/systemd/user/daemon-name.service
. The same user can then manage the service with systemctl --user <action> daemon-name.service
.
To allow the user unit to start at boot, root must enable linger for the account, i.e. sudo loginctl enable-linger username
. The unit must also be WantedBy=default.target
.
The other way is by allowing the user access to manage the system unit via PolicyKit. This requires systemd 226 or higher (and PolicyKit >= 0.106 for the JavaScript rules.d files – check with pkaction --version
). Note that Debian has deliberately held back PolicyKit to a nearly decade old version 0.105 which does not support this functionality, apparently because of one person's personal opinion, and neither it nor distributions derived from it (like Ubuntu) can use this method.
You would create a new PolicyKit configuration file, e.g. /etc/polkit-1/rules.d/57-manage-daemon-name.rules
which checks for the attributes you want to permit. For example:
// Allow alice to manage example.service;
// fall back to implicit authorization otherwise.
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" &&
action.lookup("unit") == "example.service" &&
subject.user == "alice") {
return polkit.Result.YES;
}
});
The named user can then manage the named service with systemctl
and without using sudo
.