FS#61163 - [unbound] enable systemd hardening

Attached to Project: Community Packages
Opened by Remi Gacogne (rgacogne) - Sunday, 23 December 2018, 16:26 GMT
Last edited by Gaetan Bisson (vesath) - Thursday, 19 September 2019, 20:01 GMT
Task Type Feature Request
Category Packages
Status Closed
Assigned To Gaetan Bisson (vesath)
Architecture All
Severity Low
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 1
Private No

Details

Since we are currently providing the systemd service file for Unbound, it would be nice to add some hardening options to it. I have been running with these for a while without any issue, and unless someone sees something wrong with them I think it would make sense to add them to the service file:

PrivateDevices=true
PrivateTmp=true
ProtectControlGroups=true
ProtectHome=true
ProtectKernelModules=true
ProtectKernelTunables=true
# not full to allow auto-trust-anchor-file to work correctly
ProtectSystem=true

NoNewPrivileges=true

RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
RestrictNamespaces=true
SystemCallArchitectures=native

This task depends upon

Closed by  Gaetan Bisson (vesath)
Thursday, 19 September 2019, 20:01 GMT
Reason for closing:  Implemented
Additional comments about closing:  unbound-1.9.3-3 in [community]
Comment by Jake Kreiger (Magali75) - Monday, 24 December 2018, 12:03 GMT
We can even take those from upstream: https://github.com/NLnetLabs/unbound/blob/master/contrib/unbound.service.in

CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
PrivateTmp=true
ProtectHome=true
ProtectControlGroups=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectSystem=strict
ReadWritePaths=@UNBOUND_SYSCONF_DIR@ @UNBOUND_LOCALSTATE_DIR@ /run @UNBOUND_RUN_DIR@
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
RestrictRealtime=true
SystemCallArchitectures=native
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources

However we can't use upstream service directly because 'Type=notify' can work only for socket activation.
Comment by Remi Gacogne (rgacogne) - Monday, 24 December 2018, 12:10 GMT
Oh, I didn't realize they added these, thanks!

Note that Type=Notify should work as long as they call sd_notify(), which they do in daemon_fork(), so perhaps we could in fact use the upstream service directly?
Comment by Jake Kreiger (Magali75) - Monday, 24 December 2018, 12:36 GMT
If you can test that it works then sure but last time I tried it didn't.

You may need to pass '--enable-systemd' in configure and maybe 'use-systemd: yes' in unbound.conf.
Comment by Remi Gacogne (rgacogne) - Monday, 24 December 2018, 13:41 GMT
That indeed requires --enable-systemd during configure, but not 'use-systemd: yes' in the configuration which enabled socket activation.
Comment by Jake Kreiger (Magali75) - Monday, 24 December 2018, 14:19 GMT
Here are couple of things I found during testing:

--enable-systemd requires adding PKG_CONFIG="/usr/bin/pkg-config" in configure params otherwise it can't find libsystemd dependency.

'ReadWritePaths=@UNBOUND_SYSCONF_DIR@ @UNBOUND_LOCALSTATE_DIR@ /run @UNBOUND_RUN_DIR@' will result in
'ReadWritePaths=/etc /var /run /etc/unbound' which is definitely too broad and wrong. That would need patching as desired lines could be like this instead: 'ReadWritePaths=/etc/unbound /var/lib/unbound /run/unbound'.

With 'Type=Notify' executing 'systemctl start unbound' command hangs in terminal (although service is started correctly). Removing 'Type=Notify' fixes this issue.

That's all from me.
Comment by Eli Schwartz (eschwartz) - Monday, 24 December 2018, 15:45 GMT
It was suggested to use the upstream service with systemd enabled, in  FS#59162 

The maintainer tried, then reverted it with the comment "Oh, well, Type=notify fails for me too: unbound never notifies anything to systemd and `systemctl start` is left hanging. We'll just get rid of PIDFile=... Sorry for the noise."
Comment by Jake Kreiger (Magali75) - Monday, 24 December 2018, 18:47 GMT
Yes, this is the same what I reported above. However the upstream hardening part is good except the 'ReadWritePaths'.

We can use upstream service and patch some lines with 'sed' or copy just the hardening parts to our own service.
Comment by loqs (loqs) - Monday, 24 December 2018, 21:05 GMT
Is sd_notify not being used because --enable-systemd is not passed to configure and without PKG_CONFIG=/usr/bin/pkg-config confgure fails to find libsystemd seemingly due to failing to find pkg-config / pkgconf ?
https://github.com/NLnetLabs/unbound/blob/d29c1f06af38d71f0940531dddb90d9cf1b2f829/daemon/daemon.c#L663
Edit:
Missed https://bugs.archlinux.org/task/61163#comment175632 by Jake Kreiger which had already found all of this.
Sorry for the noise.
Comment by Remi Gacogne (rgacogne) - Sunday, 06 January 2019, 11:59 GMT
AFAICT, there are at least two issues to fix before Type=notify can work:
1/ we need to compile with '--enable-systemd' (with the right PKG_CONFIG env) ;
2/ we need to make sure that unbound doesn't chroot to "/etc/unbound" (the default) before calling sd_notify(), otherwise that fails because /run/systemd/notify does not exist inside the chroot. This can be done by setting chroot: "" in the configuration file.

Then if we want to use the provided unit file, we also need to disable the writing of the PID file, which is mostly useless once unbound is managed by systemd anyway. It needs to be disabled because unbound tries to write it before switching to the "unbound" user, while still running as root, but the file is owned by "unbound:unbound" and root doesn't have CAP_DAC_OVERRIDE anymore with the CapabilityBoundingSet applied, so it can't alter the file.
Comment by Jake Kreiger (Magali75) - Monday, 07 January 2019, 00:19 GMT
Are there security consequences of disabling chroot?
Comment by Gaetan Bisson (vesath) - Friday, 12 April 2019, 17:23 GMT
I'm happy to switch to upstream's service file and I don't see a problem with adding `--enable-systemd` and the right pkg-config incantation. However, adding `chroot: ""` to the default configuration file does not make me very happy.

What if we removed the `Type=notify` line from upstream's service file and used that? Can either of you confirm that it works and comment on whether it achieves the desired level of hardening?
Comment by Jensen McKenzie (your_doomsday) - Sunday, 08 September 2019, 10:10 GMT
@Gaetan Bisson (vesath)

In last release (1.9.3) upstream finally made some systemd fixes:
https://github.com/NLnetLabs/unbound/commit/a90f173875baf9a40ec2f2860439f571c2f3e280
https://github.com/NLnetLabs/unbound/commit/06847ff3be18afe77a0bd3ac69a862253c9506c0

You can try building with "--enable-systemd" and taking upstream service file.
Comment by Gaetan Bisson (vesath) - Monday, 09 September 2019, 08:35 GMT
Did you test that proposal? Does it work as intended? Could you send it to me as a patch to our PKGBUILD?
Comment by Jensen McKenzie (your_doomsday) - Monday, 16 September 2019, 21:39 GMT
@Gaetan Bisson (vesath) It works but you still need to disable chroot as mentioned before.

Wee can go back to your proposal from https://bugs.archlinux.org/task/61163#comment178585 and use upstream service file and remove Type=notify from it.

Here's simple PKGBUILD diff for that


Comment by Gaetan Bisson (vesath) - Monday, 16 September 2019, 23:41 GMT
Thanks!
Comment by Gene (GeneC) - Tuesday, 17 September 2019, 07:06 GMT
  • Field changed: Percent Complete (100% → 0%)
I'm seeing new errors in logs with this version:

Samples of new error mesasges that started with this release:
Using
ip-transparent: yes
leads to:
unbound[] warning: setsockopt(.. IP_TRANSPARENT ..) failed: Operation not permitted

Similarly there are now errors with other socket options which are new:

unbound[] warning: so-rcvbuf 1048576 was not granted. Got 425984. To fix: start with root permissions(linux) or sysctl bigger net.core.rmem_max(linux) or kern.ipc.maxsockbuf(bsd) values.

unbound[] warning: so-sndbuf 4194304 was not granted. Got 425984. To fix: start with root permissions(linux) or sysctl bigger net.core.wmem_max(linux) or kern.ipc.maxsockbuf(bsd) values.
Comment by Jensen McKenzie (your_doomsday) - Thursday, 19 September 2019, 14:40 GMT
  • Field changed: Percent Complete (100% → 0%)
@Gaetan Bisson (vesath)

I think there was misunderstanding. If you disable chroot then you don't need changing service type to simple.
In the diff I posted the assumption was to keep chroot intact while using upstream service file. Also as last comment shows ProtectKernelTunables is breaking some functionality and should be disabled.
Comment by Gene (GeneC) - Thursday, 19 September 2019, 15:36 GMT
Just an FYI

Warnings:
I changed ip-transparent to
ip-freebind: yes
Which works fine without root.
I also fixed my sockopts via sysctl (net.core.wmem_max and net.core.rmem_max).

Error:
I needed to add (as per the default config in package now requiring it)
chroot: ""
Without this, (my original config) the service fails to start at all.

Comment by Jensen McKenzie (your_doomsday) - Thursday, 19 September 2019, 16:15 GMT
@Gaetan Bisson (vesath) could you apply this patch[1], remove sed rule from PKGBUILD and chroot "" from config? This should fix the issues.

https://github.com/NLnetLabs/unbound/commit/ff8fd0be5c529e7a1b84e8c74426e9c531c0a8f8
Comment by Gaetan Bisson (vesath) - Thursday, 19 September 2019, 20:01 GMT
Thanks Jensen for the upstream patch and for clarifying my misunderstandings.

Loading...