Hello, I’m currently trying to package my own software which runs a system service (as root).
It doesn’t necessarly need to run as root but it’s kind of the default for all system services. At some point I should consider running it as a special system user with fewer privileges. It only needs to access specific data directory on the system and a single internet port.
The first configuration mechanism I used was environment variables set by the Nix Module and accessed by module options. This works but I would need to rebuild my config each time I want the config to change which is not flexible enough for my needs.
So I decided to do it with dbus. I implemented a dbus server with sdbusplus, here are the specifications.
The interface is very simple:
- Only one object: /org/scotthamilton/rpifanserver
- Only one interface: org.scotthamilton.RpiFanServe with only one property: CacheLifeExpectancy
- Only one connection name (bus name): org.scotthamilton.RpiFanServe
Last and not least, every user of the rpi-fan-serve
group should be able to write to CacheLifeExpectancy.
That’s it.
Here is my take on trying to make a system bus config that implements those requirements:
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy user="root">
<!-- Only root can own the service -->
<allow own="org.scotthamilton.RpiFanServe"/>
</policy>
<policy group="rpi-fan-serve">
<!-- Dbus defaults -->
<allow send_destination="org.scotthamilton.RpiFanServe"
send_interface="org.scotthamilton.RpiFanServe"/>
<allow send_destination="org.scotthamilton.RpiFanServe"
send_interface="org.freedesktop.DBus.Introspectable"/>
<allow send_destination="org.scotthamilton.RpiFanServe"
send_interface="org.freedesktop.DBus.Peer"/>
<allow send_destination="org.scotthamilton.RpiFanServe"
send_interface="org.freedesktop.DBus.Properties"/>
<allow send_destination="org.scotthamilton.RpiFanServe"
send_interface="org.freedesktop.DBus.ObjectManager"/>
</policy>
</busconfig>
I also added my package to services.dbus.packages
and verified that I could find it in /etc/dbus-1/system.conf
after rebuilding my config.
I took the assumption from reading the doc that this config would mean that every message coming from senders that belong to the rpi-fan-serve
group would be allowed to call methods from the org.freedesktop.DBus.Properties
interface on the org.scotthamilton.RpiFanServe
destination bus.
And this works fine. My dbus server can acquire the bus name, I can send messages to it and they get received perfectly. But I can only set CacheLifeExpectancy with root.
Or in other words,
this works:
sudo busctl set-property org.scotthamilton.RpiFanServe /org/scotthamilton/rpifanserver org.scotthamilton.RpiFanServe CacheLifeExpectancy x 3600
but this doesn’t work (same but without sudo)
busctl set-property org.scotthamilton.RpiFanServe /org/scotthamilton/rpifanserver org.scotthamilton.RpiFanServe CacheLifeExpectancy x 3600
Output: Failed to set property CacheLifeExpectancy on interface org.scotthamilton.RpiFanServe: Access denied
I ran a bus monitor to figure out what was going on:
sudo busctl monitor org.scotthamilton.RpiFanServe
Output on error
Monitoring bus message stream.
‣ Type=method_call Endian=l Flags=0 Version=1 Cookie=2
Sender=:1.87 Destination=org.scotthamilton.RpiFanServe Path=/org/scotthamilton/rpifanserver Interface=org.freedesktop.DBus.Properties Member=Set
UniqueName=:1.87
MESSAGE "ssv" {
STRING "org.scotthamilton.RpiFanServe";
STRING "CacheLifeExpectancy";
VARIANT "x" {
INT64 8080;
};
};
‣ Type=method_call Endian=l Flags=0 Version=1 Cookie=4
Sender=:1.85 Destination=org.freedesktop.DBus Path=/org/freedesktop/DBus Interface=org.freedesktop.DBus Member=GetConnectionUnixUser
UniqueName=:1.85
MESSAGE "s" {
STRING ":1.87";
};
‣ Type=method_return Endian=l Flags=1 Version=1 Cookie=5 ReplyCookie=4
Sender=org.freedesktop.DBus Destination=:1.85
MESSAGE "u" {
UINT32 1001;
};
‣ Type=error Endian=l Flags=1 Version=1 Cookie=5 ReplyCookie=2
Sender=:1.85 Destination=:1.87
ErrorName=org.freedesktop.DBus.Error.AccessDenied ErrorMessage="Access to org.scotthamilton.RpiFanServe.CacheLifeExpectancy() not permitted."
UniqueName=:1.85
MESSAGE "s" {
STRING "Access to org.scotthamilton.RpiFanServe.CacheLifeExpectancy() not permitted.";
};
So it seems like it’s not even the org.freedesktop.DBus.Properties.Set
method call that was denied but the org.scotthamilton.RpiFanServe.CacheLifeExpectancy()
. I don’t know what to do because I already allowed the rpi-fan-serve group to access to the org.scotthamilton.RpiFanServe
interface.
For clarity, here is the output of id command
to show that I’m indeed belonging to the rpi-fan-serve
group.
uid=1001(scott) gid=100(users) groupes=100(users),1(wheel),57(networkmanager),131(docker),995(rpi-fan-serve)
Maybe I would have better chance to find a solution on a dbus dedicated forum but such a thing doesn’t exist and I don’t exclude the possiblity of this being Nix’s fault.