Running your own private bus isn’t currently supported, but I took a look to see what it would take to implement it. Essentially I found that with the following session.conf file saved in $SNAP_COMMON/session.conf:
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<type>session</type>
<keep_umask/>
<listen>unix:tmpdir=snap.SNAP_NAME.</listen>
<auth>EXTERNAL</auth>
<apparmor mode="disabled"/>
<policy context="default">
<!-- Allow everything to be sent -->
<allow send_destination="*" eavesdrop="true"/>
<!-- Allow everything to be received -->
<allow eavesdrop="true"/>
<!-- Allow anyone to own anything -->
<allow own="*"/>
</policy>
</busconfig>
(where SNAP_NAME is the hardcoded name of your snap; <policy>
should be able to be whatever makes sense for your snap) and the following apparmor policy added on top of the slot side policy:
/usr/bin/dbus-run-session ixr,
/usr/bin/dbus-daemon ixr,
/sys/module/apparmor/parameters/enabled r,
unix (bind,listen) addr="@snap.@{SNAP_NAME}./dbus-*",
and finally add bind
to the snap’s seccomp policy. Then I could use dbus-run-session within a snap. Eg:
$ snap run --shell test-snapd-policy-app-consumer-classic
bash$ dbus-run-session --config-file=$SNAP_COMMON/session.conf env|grep DBUS
DBUS_SESSION_BUS_ADDRESS=unix:abstract=snap.test-snapd-policy-app-provider-classic./dbus-3HdA9U1lxA,guid=3438b8dd2cb51db68cf446a45babfc54
There is an apparmor denial that is just noise:
audit(1537997046.626:5710): apparmor="DENIED" operation="open" profile="snap.test-snapd-policy-app-provider-classic.dbus-session" name="/proc/19256/mounts" pid=19256 comm="dbus-daemon" requested_mask="r" denied_mask="r" fsuid=1000 ouid=1000
What this does is allow the snap to run dbus-run-session, which calls dbus-daemon with the configuration from the snap-provided session.conf file, which allows setting up of a private dbus bus at ‘@snap.SNAP_NAME./dbus-*’ and the private bus is setup. We need other rules for communicating over it; this is what I expect we would want in reality (untested):
# allow us to manage our own abstract socket
unix (bind, listen) addr="@snap.@{SNAP_NAME}.**",
# allow processes from this snap to use abstract sockets from this snap
unix (accept, connect, receive, send) addr="@snap.@{SNAP_NAME}.**" peer=(label=snap.@{SNAP_NAME}.*),
There are a couple of interesting things about this:
- the session.conf disables apparmor in dbus-daemon. That’s fine-- it isn’t in a good position to mediate itself and other snaps can’t access the private bus anyway because the ‘unix’ rules make this snap specific. Unconfined processes would be able to access it once they found the bus
- you therefore shouldn’t need to use the dbus interface at all with registering well-known names-- this is really about giving your snap access to the abstract socket; the fact that the snap is using a private dbus session is an implementation detail that can stay within the snap. It does mean that your services can only be accessed by clients within the same snap (likely what you are trying to achieve with a private bus anyway)
- the abstract socket is snap-specific because we use snap.SNAP_NAME. (the ‘snap.’ prefix and trailing ‘.’ means that snaps can’t overlap here and makes it equivalent to what we already allow with named sockets (eg, that can live in SNAP_COMMON, etc)
I’m inclined to add the above to the default policy, but for your snap today, you can’t use the private bus. I’ll update this topic if/when those changes land.