We have strictly confined snaps that need to do networking. This seems very straight-forward in the snap world, but we’re running into trouble with custom certificate authorities. The snap isn’t able to read the CAs on the host system and as a result, doesn’t trust things signed by the CA. This seems a fairly common thing to desire to just work in a snap, but I can’t find any interface related to this or a way to accomplish this without moving to classic confinement. Classic confinement is something we would like to avoid.
Has anyone solved this in a way that is clean and allows strict confinement?
Thank you for posting this topic. I believe currently the SSL certificates are loaded from the base snap (if it provides them), meaning that you cannot add your own from the outside world. As a workaround, if you know when building your snap which CAs you desire to trust, you could try adding them to your snap and mounting them into the SSL certificates store with layout support:
Where are the certificates on the host system? The network interface allows various access to /etc/ssl via the abstractions/ssl_certs apparmor abstraction.
You later said that “In my case, the CAs are user-provided at run-time. Does that leave me with any options?”. This is getting into the area of: Extending system certificates for which there is no current support right now. You should be able to make something work by:
using stage-packages ‘ca-certificates’ in your snapcraft.yaml
use @lucyllewy’s layout technique to use ‘bind’ instead of ‘bind-file’ like so:
layout:
/etc/ssl/certs:
bind: $SNAP_COMMON/certs
on install copy $SNAP/etc/ssl/certs to $SNAP_COMMON/certs
update $SNAP_COMMON/certs as desired
This is untested and there might be other ways you want to do it.
So this doesn’t appear to be working for us. I’m not sure what is going on, but we have the network interface and it only reads the system CA’s if you run the executable with the full path into the snap. So it is trying to read them and will successfully do it, just not when it is run via the snap. Any ideas on how to track this down?
Yes, the program will read system certs, but it also accepts a path to a specific CA cert, client cert, and client key to use. These are just full file paths to some random location on the machine.
The goal isn’t to replace the /etc/ssl/certs dir as much as read specific files. I think we’ll have to do something like add the home interface and just try to document that the user has to store the files there.
The most important part for us it the system cert reading.
Can you be more specific than “doesn’t appear to be working for us”? Are there any security policy denials in the journal? If so can you paste them?
OTOH, is this a java application? Perhaps you need to stage-packages ca-certificates-java.
Another thing to try is to install your snap in --devmode then strace it (snap run --strace your.cmd) then install your snap in strict mode, strace it and compare the traces.
It will take some time to setup the environment again, but the gist of it is that when running the executable it would fail due to an unknown x509 certificate. When I would run the binary from that snap directly, it would work fine. I will check for policy denials and check strace output when I get this setup again and then I will report back.
Unfortunately no, this is written in go. Further, the ca isn’t known at snap build time, so my assumption here is that a stage package won’t help. Is that correct? Here is a link to the snapcraft.yaml.
I ran it with strace in 3 different configurations.
I didn’t have it in my path as root, which is why I added the /snap/bin. When I run the snap as root or a normal user I get an x509 cert issue. If I run it via the /snap/client-keystone-auth/current/bin/client-keystone-auth method I get access to the server and either a token or, as in this case, an auth error because I don’t have valid credentials. The journal shows no apparmor errors or denials. In fact, nothing is output at all during the run.