The ebuilds for net-dns/unbound create the "unbound" user with its home directory set to /etc/unbound: pkg_setup() { enewgroup unbound enewuser unbound -1 -1 /etc/unbound unbound use python && python-single-r1_pkg_setup } As a result, /etc/unbound is writable by the "unbound" user. However, that's where the sensitive unbound.conf gets installed (as root:root): $ /bin/ls -al /etc/unbound/ total 44 drwxr-xr-x 2 unbound root 4096 Dec 14 13:59 . drwxr-xr-x 79 root root 4096 Dec 14 13:59 .. -rw-r--r-- 1 root root 34276 Dec 14 13:59 unbound.conf That conf file must only be writable by root; at least... * the OpenRC service script uses the value of "pidfile" found in unbound.conf, so anyone who can edit that file can clobber things on the fileystem. * the daemon binds to its interface and port as root, so the "unbound" user could bind to e.g. port 80. * From daemon/unbound.c and daemon/remote.c, it looks like unbound will call "chown" on its pidfile/socket respectively, meaning that if the "unbound" user can alter the pidfile or local socket location, then he can take control of any file the next time the daemon is started. (I haven't tested this one, because the first two are bad enough.) I just noticed this on our DNS servers a few minutes ago, and have done chown root /etc/unbound as a quick workaround. Nothing bad seems to have happened so far, but it's only been a few minutes. I'll report back if the phones start ringing.
Thanks for spotting! I think the ebuild should 'chown root /etc/unbound' to fix this. But caution has to be taken when unbound is running chrooted into /etc/unbound (this is the default) because unbound then cannot update the DNSSEC trust anchor file anymore for example. Something like /etc/unbound/var that is owned by unbound will help then.
(In reply to Marc Schiffbauer from comment #1) > Thanks for spotting! I think the ebuild should 'chown root /etc/unbound' to > fix this. Yeah, regardless of any other changes to the ebuild, someone -- either us, in pkg_postinst, or the user himself -- will need to fix the existing ownership information. That's actually pretty hard to get right in general, but I think you're lucky. Since you only need to change ownership of one path (/etc/unbound) and it lives in a root-owned directory (/etc), the following should be safe: if [[ -d "${ROOT}/etc/unbound" ]]; then chown --no-dereference --from=unbound root "${ROOT}/etc/unbound" fi in pkg_postinst. > But caution has to be taken when unbound is running chrooted into > /etc/unbound (this is the default) because unbound then cannot update the > DNSSEC trust anchor file anymore for example. Something like > /etc/unbound/var that is owned by unbound will help then. I don't know enough about unbound to know what it needs in the chroot.. would something like the following work? 1. Change the "enewuser" to set $HOME to /dev/null (just delete all the args to enewuser) 2. Dosym a link /var/lib/unbound/etc/unbound -> /etc/unbound 3. Change the default chroot path from /etc/unbound to /var/lib/unbound That way, /etc/unbound is safe but a chrooted daemon can see it. If the chrooted daemon needs to be able to write to something, you can make /var/lib/unbound or one of its subdirectories writeable by the "unbound" user. The daemon is willing to start for me out-of-the-box with those modifications, but I don't know how to make it try to write stuff. Also, so I don't forget... if the above steps turn out to work, there is an ugly item "1.a." that we'll need to address; namely updating the home directory for any "unbound" users that already exist on the system.
@ Maintainer(s): Can we please get a status update?
I will have a look and then a fix very soon. Thanks for the reminder.
Fixed and revbunped in 6f3d0c2027034767f2acf1b52940c15ec137d6c0 Thanks Michael for spotting. FYI: I fix ownership in pkg_setup() as this is where the user and his $HOME is created. If we did this in pkg_postinst() that would have been racy
@ Marc: Please do not close security bugs. @ Michael: Can you please review the changes and ack/nack?
Is there a reason to keep enewuser unbound -1 -1 /etc/unbound unbound instead of enewuser unbound -1 -1 -1 unbound going forward? Its homedir will be unwritable either way, now. Regardless, the immediate problem looks fixed. Thank you!
This has broken unbound usage for trust-anchor fetching, and broke all of the Gentoo infra unbound instances! open("root-anchors.txt.3292-0", O_WRONLY|O_CREAT|O_TRUNC, 0666) = -1 EACCES (Permission denied) sendto(8, "<26>Feb 24 22:58:09 unbound: [3292:0] fatal error: could not open autotrust file for writing, root-anchors.txt.3292-0: Permission denied", 136, MSG_NOSIGNAL, NULL, 0) = 136 Per upstream unbound EXPECTS to be able to write this. Per the unbound.conf manpage: auto-trust-anchor-file: <filename> File with trust anchor for one zone, which is tracked with RFC5011 probes. The probes are several times per month, thus the machine must be online frequently. The initial file can be one with contents as described in trust-anchor-file. The file is written to when the anchor is updated, so the unbound user must have write permission. Write permission to the file, but also to the directory it is in (to create a temporary file, which is necessary to deal with filesystem full events), it must also be inside the chroot (if that is used).
While I agree with the intent of deploying this fix, the silent breakage on a revbump without any other notice of it is what caught me out. 1. let's ship the example unbound.conf that uses "var/" prefix in auto-trust-anchor-file 2. pre-create /etc/unbound/var/ that IS writable by the daemon, and is populated ready to go.
How about creating /var/lib/unbound writable by the unbound user and then setting --with-run-dir=/var/lib/unbound (i.e. comment #2)? I think /var is a better place for this data, but only if it doesn't cause other problems with the chroot.
(In reply to Robin Johnson from comment #9) > While I agree with the intent of deploying this fix, the silent breakage on > a revbump without any other notice of it is what caught me out. > > 1. let's ship the example unbound.conf that uses "var/" prefix in > auto-trust-anchor-file > 2. pre-create /etc/unbound/var/ that IS writable by the daemon, and is > populated ready to go. +1 I revbumped with a fix for auto-trust-anchor-file and add an additional var/ dir in /etc/unbound @Michael: Thanks for your suggestion. But using --with-run-dir would cause more things to be changed which I want to avoid. For example the config file would not be in the chroot anymore, so we'd have to install it in run-dir as well and then create a symlink in /etc/unbound... I would find this too invasive for what we'd like to achieve now. And I am still not completey happy with this whole trust anchor file handling: at some point in the past the dnssec-root package has been added to the tree and unbound depends on it. And we compile unbound with --with-rootkey-file="${EPREFIX}"/etc/dnssec/root-anchors.txt which makes unbound-anchor and unbound-host use this file as default. The man-page of unbound-anchor suggests to run unbound-anchor and then start unbound with a config that lets auto-trust-anchor-file point to /etc/dnssec/root-anchors.txt so its basedir would need to be writable by unbound to make updates work, which is bad. Additionally this breaks unbounds default chroot support because /etc/dnssec is outside the unbound chroot. So I will just patch the example config file to suggest /etc/unbound/var/root-anchors.txt as value for auto-trust-anchor-file.
(In reply to Marc Schiffbauer from comment #11) > (In reply to Robin Johnson from comment #9) > > While I agree with the intent of deploying this fix, the silent breakage on > > a revbump without any other notice of it is what caught me out. > > > > 1. let's ship the example unbound.conf that uses "var/" prefix in > > auto-trust-anchor-file > > 2. pre-create /etc/unbound/var/ that IS writable by the daemon, and is > > populated ready to go. > > +1 > > I revbumped with a fix for auto-trust-anchor-file and add an additional var/ > dir in /etc/unbound > > @Michael: Thanks for your suggestion. But using --with-run-dir would cause > more things to be changed which I want to avoid. For example the config file > would not be in the chroot anymore, so we'd have to install it in run-dir as > well and then create a symlink in /etc/unbound... I would find this too > invasive for what we'd like to achieve now. > > And I am still not completey happy with this whole trust anchor file > handling: at some point in the past the dnssec-root package has been added > to the tree and unbound depends on it. > And we compile unbound with > --with-rootkey-file="${EPREFIX}"/etc/dnssec/root-anchors.txt which makes > unbound-anchor and unbound-host use this file as default. > The man-page of unbound-anchor suggests to run unbound-anchor and then start > unbound with a config that lets auto-trust-anchor-file point to > /etc/dnssec/root-anchors.txt so its basedir would need to be writable by > unbound to make updates work, which is bad. > Additionally this breaks unbounds default chroot support because /etc/dnssec > is outside the unbound chroot. > So I will just patch the example config file to suggest > /etc/unbound/var/root-anchors.txt as value for auto-trust-anchor-file. Which version did you push with this fix?
(In reply to Aaron Bauman from comment #12) > (In reply to Marc Schiffbauer from comment #11) > > (In reply to Robin Johnson from comment #9) > > > While I agree with the intent of deploying this fix, the silent breakage on > > > a revbump without any other notice of it is what caught me out. > > > > > > 1. let's ship the example unbound.conf that uses "var/" prefix in > > > auto-trust-anchor-file > > > 2. pre-create /etc/unbound/var/ that IS writable by the daemon, and is > > > populated ready to go. > > > > +1 > > > > I revbumped with a fix for auto-trust-anchor-file and add an additional var/ > > dir in /etc/unbound > > > > @Michael: Thanks for your suggestion. But using --with-run-dir would cause > > more things to be changed which I want to avoid. For example the config file > > would not be in the chroot anymore, so we'd have to install it in run-dir as > > well and then create a symlink in /etc/unbound... I would find this too > > invasive for what we'd like to achieve now. > > > > And I am still not completey happy with this whole trust anchor file > > handling: at some point in the past the dnssec-root package has been added > > to the tree and unbound depends on it. > > And we compile unbound with > > --with-rootkey-file="${EPREFIX}"/etc/dnssec/root-anchors.txt which makes > > unbound-anchor and unbound-host use this file as default. > > The man-page of unbound-anchor suggests to run unbound-anchor and then start > > unbound with a config that lets auto-trust-anchor-file point to > > /etc/dnssec/root-anchors.txt so its basedir would need to be writable by > > unbound to make updates work, which is bad. > > Additionally this breaks unbounds default chroot support because /etc/dnssec > > is outside the unbound chroot. > > So I will just patch the example config file to suggest > > /etc/unbound/var/root-anchors.txt as value for auto-trust-anchor-file. > > Which version did you push with this fix? IIRC Robin pushed the fix that I suggested. Current state ist that both versions of unbound in the tree have the fix. And looking at git log all versions >=1.6.8-r2 had the fix -Marc PS: Sorry for the delay :-/
This issue was resolved and addressed in GLSA 201904-03 at https://security.gentoo.org/glsa/201904-03 by GLSA coordinator Aaron Bauman (b-man).