apparmor="DENIED" on /etc/resolvconf/resolv.conf.d/head read causes DNS resolution to fail despite the use of the network interface

I have a non default dns setup on my host to make my dnscrypt-proxy dns
server setting stick across network interfaces, wifi access point
changes in network-manager, and reboots.

rm /etc/resolvconf/resolv.conf
cat <<EOF > sudo tee /etc/resolvconf/resolv.conf.d/head
nameserver <ip-of-my-local-dnscrypt-proxy-instance>
EOF

This causes the following when running my snap which uses the network interface

= AppArmor =
Time: Oct 30 08:48:34
Log: apparmor="DENIED" operation="open" profile="snap.btcd.daemon" name="/etc/resolvconf/resolv.conf.d/head" pid=27224 comm="btcd" requested_mask="r" denied_mask="r" fsuid=584788 ouid=0
File: /etc/resolvconf/resolv.conf.d/head (read)

Which (I think) in turn causes this

INF] CMGR: DNS discovery failed on seed seed.bitcoin.sipa.be: lookup seed.bitcoin.sipa.be on [::1]:53: read udp [::1]:34651->[::1]:53: read: connection refused

Are these events related? What is the correct fix?

My initial guess is that I need to add network-bind for the snap to be able to listen for incoming UDP packets. Is that correct?

I’ve tried to look at the apparmor profile configuration, but I don’t find any file for my snap in /etc/apparmor.d, only a profile listed in the aa-status output.

1 Like

Hmm from reading https://github.com/snapcore/snapd/blob/master/interfaces/builtin/network.go

resolved may need to be enabled. I switched it off to make my manual configuration change sticky in the past. I’ll re-enable it first to see if it helps.

It is surprising that the confined app is trying to access /etc/resolvconf/resolv.conf.d/head. I would expect that file to only be accessed by the resolvconf script, which would run outside of confinement on your system. The contents of that file should be copied to a location that the snap can access (probably /run/resolvconf/resolv.conf).

If you want to test whether DNS is functional within the snap’s sandbox, try running the following:

snap run --shell btcd.daemon

This will start a shell using the snap’s confinement. Inside that shell, try running:

getent hosts example.com

If this returns any IP addresses, then the problem is likely in the application rather than the sandbox.

1 Like

Right on point @jamesh , I forgot to mention that I set up a manual symlink like so in the past, so that it does not get replaced (ie sticks):

/etc$ ls -la resolv.conf
lrwxrwxrwx 1 root root 29 Apr 14  2019 resolv.conf -> resolvconf/resolv.conf.d/head

and from a look at <abstractions/nameservice> in apparmor, /etc/resolvconf/resolv.conf.d is not one of the readable locations.

/etc$ cat apparmor.d/abstractions/nameservice | grep -n -E "resolv.?conf" 
35:  /etc/resolv.conf        r,
36:  # on systems using resolvconf, /etc/resolv.conf is a symlink to
37:  # /{,var/}run/resolvconf/resolv.conf and a file sometimes referenced in
38:  # /etc/resolvconf/run/resolv.conf. Similarly, if NetworkManager is used
39:  # without resolvconf, /etc/resolv.conf is a symlink to its own resolv.conf.
40:  # Finally, on systems using systemd's networkd, /etc/resolv.conf is
41:  # a symlink to /run/systemd/resolve/resolv.conf
42:  /{,var/}run/{resolvconf,NetworkManager,systemd/resolve}/resolv.conf r,
43:  /etc/resolvconf/run/resolv.conf r,

So i need to do as you suggest and move my head to

/run/resolvconf/resolv.conf

However, since that file already exists and gets updated dynamically,

/etc/resolvconf/run/resolv.conf

is probably better (that file does not exist on my machine). Or, I could get rid of resolvconf altogether, another day.

More generally, is there any way to dump the current apparmor profile of a snap?
I can’t see a file in /etc, only systemd related files for my snap…

PS: Thanks for the debug hint, never heard of getent before.

According to the man page, the contents of that file should have been copied to /run/resolvconf/resolv.conf. If you are going to use resolveconf, I would suggest reading its instructions and determining why it isn’t generating the configuration you’re after rather than fighting against it.

Note also that newer versions of Ubuntu, the default resolver configuration will send requests to systemd-resolved. So another option would be to leave resolv.conf as is and edit the systemd-resolved configuration file at /etc/systemd/resolve.conf.

1 Like

snapd manages the profiles itself and stores them in /var/lib/snapd/apparmor/profiles. You can either inspect them manually there, or you can run them through a preprocess step to dump the file and all the included abstraction rules with: apparmor_parser -p /var/lib/snapd/apparmor/profiles/snap.name.cmd.

1 Like

Hmm, it seems the answer has been staring me in the face the whole time, and the man page is what confused the hell out of me (even back then), and led me towards the hairbrained head symlink idea.

All I needed to do is create a real (ie not a symlink) /etc/resolv.conf file with the one dns server setting of my dnscrypt-proxy, and everything works the way I want, without any dynamically appended servers from dhcp. Oh well, always be learning.

1 Like

That’s perfect, thank you