Bugzilla – Bug 199
chroot/setown vs syslog and pidfile
Last modified: 2008-09-29 16:23:39 CEST
By default unbound will chroot and setown to the unprivileged user before opening logging or the pidfiles. This means that it can't follow normal (NetBSD) practise of having a pidfile in /var/run nor can it use syslog from the default configuration.
A side effect of not logging being able to syslog is that querying becomes a lot slower when IPv6 error messages are to be written and the process doesn't respond to SIGTERM in timely manners.
I think it would be preferable if the pidfile is opened for writting while still being root (and ftruncated on exit) and at least the openlog call is done before chrooting.
Created attachment 75 [details]
a working, tested fix, to correct pidfile handling to be compatible with *BSD
note that the pidfile _MUST_ be owned by root on *BSD -- this is a security requirement inherent in the design of the rc.d system and its normal usage
(In reply to comment #1)
> Created an attachment (id=75) [details]
> a working, tested fix, to correct pidfile handling to be compatible with *BSD
I don't think the chroot handling is entirely, which is why I didn't just propose this patch. E.g. various places remove chrootdir as prefix from config options as they were originally be called after the chroot.
Indeed -- I realized later that I've just turned off chroot entirely. I don't worry so much about local exploits on machines that are trimmed down to run just one or two applications.
Is the problem so simple that the openlog() call isn't being done before chroot? Grrr.... I see there isn't any openlog() call at all -- there's your problem!
(all that unrelated stuff in the do_chroot() function shouldn't be in there -- it should be in the main line code, which pretty much makes the do_chroot() function itself pointless too -- there's no need to factor such simple code out into a sub-function like that)
I would like to help you. So far I understand, that you want:
* The pidfile written as root (that should be possible).
* Pidfile truncated or removed on (orderly) exit.
* openlog as root.
Notice that this is different from opening a logfile, which is done as the unprivileged user, so that it can be closed and reopened later to facilitate logrotate daemons.
* you do not appreciate the chroot() by default. This was done to ship with the maximum security settings. If you decide that you can do without this was your conscious decision, not forgetting to turn it on. I think it provides an extra layer of defense against intrusions.
Maybe all these problems can go away, if you take a look at the FreeBSD ports dir init script. It does all the chroot jail setup with devfs commands, does that work on NetBSD too?
(In reply to comment #4)
> I would like to help you. So far I understand, that you want:
> * The pidfile written as root (that should be possible).
Yes. Also pidfile should be able to be outside the chroot (e.g. /var/run).
> * Pidfile truncated or removed on (orderly) exit.
If possible as it avoids false positives for status checks.
> * openlog as root.
openlog before chroot actually, the root part is just a side effect.
> Notice that this is different from opening a logfile, which is done as the
> unprivileged user, so that it can be closed and reopened later to facilitate
> logrotate daemons.
> * you do not appreciate the chroot() by default
chroot() by default is fine, it just created problems due to the missing/misplaced openlog.
> Maybe all these problems can go away, if you take a look at the FreeBSD ports
> dir init script. It does all the chroot jail setup with devfs commands, does
> that work on NetBSD too?
On NetBSD /dev/log is a symlink to /var/run/log by default and thus would require changing the syslogd call. By default the daemon only has access to the config file and maybe log directories added by the user.
Created attachment 78 [details]
the latest version of my hack to get things working without rewriting it all
This patch essentially adds some comments about other related issues in the code involved.
OK so now the setup procedure is:
o read UID from /etc/passwd
o open syslog as root OR open logfile temporarily as root
o check on old pidfile
o deamonize, detach from terminal
o write new pidfile
o if pidfile inside chroot, chown it to delete it later
o chdir to working dir
o drop permissions to UID
o (if not using syslog) reopen logfile with new permissions (provides early failure for logrotate).
The syntax of the config file is unchanged, pidfile and logfile can be given relative to the working directory or as absolute paths. The pidfile as an absolute path can now be outside of the chroot.
On exit, it tries to truncate the pidfile, and also the pidfile is unlink(2)ed. But, if due to dropped permissions, chroot, etc, that does not work, the error is ignored.
That means you can have the pidfile in /var/run, but then it does not get truncated or unlinked on exit. If I try to work around this (e.g. by keeping a filedescriptor to it and truncate on exit), then your security model is broken and the server can change the pidfile from within the chroot.
Additionally I have tried to address the comments from the patch (e.g function naming, and so on). The libc call daemon(3) turns out to give trouble for some users (error, won't work), so I do not use it.
Can you try the svn trunk perhaps and tell me if I got it right? I can send you a tarball as well if you need.
The issue has been addressed at length, no more feedback from participants. Closing bugs (new issues can get a new entry).
Best regards, Wouter