@stgraber Ah, sorry, I misunderstood your proposal. You mean allowing only $SNAP_DATA and $SNAP_COMMON. Yeah, that sounds fine as a first step. The implementation I mentioned above is likely what we should aim for, as it enables other use cases, but we can do that as a follow up and it would remain compatible with what you suggest too.
Right, thatās what I had in mind. Lets limit it to something we know is safe for now, then extend it later for more complex use cases.
@niemeyer should we disallow abstract unix sockets (as theyāre not confined IIUC)?
Yes, sounds like a good idea for now. We also need to get a review from @jdstrand before the final PR goes in, so he has a chance to pick up any other issues around that sort of problem.
Actually, abstract sockets are mediated. Like so many other things, it is a matter of namespacing. Abstract sockets often look like this: @foo
, but they can have the form: @/path/foo
. Iām not saying the first iteration should support abstract sockets, but it could if the namespacing was right. Eg:
- @snap.$SNAP_NAME.whatever (eg, @snap.foo.whatever)
- @$SNAP_DATA/whatever (eg, @/var/snap/foo/x1/whatever)
Today, the default template does not allow creating abstract sockets, but this is only because we never decided on how to namespace them (it was discussed long ago, but never brought up again).
@jdstrand Not in this case, I suspect. Itās systemd that is opening up the socket. We have the same issue described above about writing of unix sockets.
Well, unless we do enforce it at the namespacing level rather than hoping for apparmor to catch it.
To be clear, I was not talking about Linux namespaces/containers. We can carve out abstract socket āpathsā that follow snappy conventions and enforce that with apparmor, in a similar fashion like we do now with the filesystem. We just have to decide how we want to carve that up (glossing over implementation details of making it work with systemd).
@niemeyer @jdstrand thanks for the clarification. Iāll reject abstract sockets for now in the listen-stream
validation.
Iām also wondering what should be allowed in terms of TCP addresses; can we just limit to a port (which would be the same as allowing [::]:<port>
) or should it be possible to specify addreses to (so that an app can, for example, bind only localhost)?
I donāt have an opinion on the actual question, but have a related question. You mention ābind only localhostā (emphasis mine); aiui systemd is merely going to listen on these itself, start the application then hand over the fd to the service, but the service is free to open and listen on any number of other ports (or named sockets or abstract sockets) as is desired. As such, the āonlyā here refers to the fact that the port will be open on the localhost, but not eth0. All of this is fine AFAIC. Fine-grained network mediation is on the roadmap, so at some point we will be able to enforce āyou may only this port on this interface and no othersā.
I ask because I want to make sure we donāt try to use āSocket Activated OS Containersā (see http://0pointer.de/blog/projects/socket-activated-containers.html) since those wonāt work right with snapd.
Reading https://www.freedesktop.org/software/systemd/man/systemd.socket.html I see no reason why we could not include abstract sockets at this time. Like with named sockets, we simply limit their naming so different snaps canāt clobber each other. Eg, like I said before (feel free to suggest other ideas):
- @snap.$SNAP_NAME.whatever (eg, @snap.foo.whatever)
- @$SNAP_DATA/whatever (eg, @/var/snap/foo/x1/whatever)
snapd ensures the abstract sockets match our naming convention when generating the systemd unit and we add a couple of apparmor glob rules to the default template that allow unconfined to access the socket and for anything in the snap to access it. Anything beyond that is out of scope for this PR (but other snap access is obviously implemented via interfaces).
If thatās the case, I think @$SNAP_COMMON/whatever
should be also supported (to match what would be allowed for filesystem-based unix sockets)