Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 181343 - pdns_recursor rec_control function is broken when chroot is enabled
Summary: pdns_recursor rec_control function is broken when chroot is enabled
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: New packages (show other bugs)
Hardware: All Linux
: High normal (vote)
Assignee: Sven Wegener
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-06-08 19:58 UTC by Jefferson Noxon
Modified: 2007-06-11 19:17 UTC (History)
0 users

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jefferson Noxon 2007-06-08 19:58:15 UTC
pdns_recursor uses unix domain sockets to communicate with the command-line utility rec_control.  When the chroot= configuration parameter is set (the default setting is /var/empty), the rec_control program no longer works.

The reason for the breakage is that a new unix domain socket is created for each rec_control request.  The powerdns recursor looks for these files in LOCALSTATEDIR (defined in config.h) unless --socket-dir is specified on the command line or socket-dir is changed in /etc/powerdns/recursor.conf.  When pdns_recursor is chrooted, it cannot access these files and therefore cannot respond to rec_control commands.

An unfortunate side-effect of the socket-dir option is that it also changes where pdns_recusor puts its PID file.  Therefore if the sysadmin changes it, the init.d script breaks and can no longer stop the daemon.

I advocate changing the default LOCALSTATEDIR in config.h to /var/run/powerdns .

This allows the following workaround to the chroot problem:

mkdir -p /var/empty/var/run
mv /var/run/powerdns /var/empty/var/run
ln -s /var/empty/var/run/powerdns /var/run

At this point, rec_control will create its sockets within the chroot-accessable portion of the filesystem.  pdns_recursor will be able to respond to rec_control commands.

Reproducible: Always

Steps to Reproduce:
1. Set "chroot=/var/empty" in /etc/powerdns/recursor.conf (this is the ebuild default!)
2. /etc/init.d/precursor start
3. rec_control ping

Actual Results:  
rec_control hangs

Expected Results:  
rec_control gives "pong" response

SuSE's solution is to use /var/run/pdns ... but conffiles on SuSE are also stored in /etc/pdns.  I suggest, since gentoo uses /etc/powerdns, that /var/run/powerdns is used for consistency.

It is also necessary to change the initscript to use the pid file in /var/run/powerdns.

Aside from the PID file problem associated with changing the socket-dir entry in the config file (as noted above), it is also worth mentioning that rec_control does not parse the config file, so if LOCALSTATEDIR is not changed in the code and the socket directory is changed in the config file, it's always necessary to pass --socket-dir= to rec_control... Which is somewhat cumbersome.

Is /var/empty really a good name for the chroot dir?  It's not very descriptive.
Comment 1 Sven Wegener gentoo-dev 2007-06-08 21:50:29 UTC
I know that rec_control is broken.

The main problem is that the recursor uses datagram sockets. When using stream sockets the recursor could pass the answer back the same way the request came in. I initially wrote the init script stop action with "rec_control quit" until I noticed that the chroot support breaks it. IMHO a chroot'ed daemon shouldn't need to open back a connection to the outside of the chroot.

In an ideal world the recursor would only need an empty directory for chroot, hence the current uhm "historic" default is /var/empty.
Comment 2 Sven Wegener gentoo-dev 2007-06-08 22:30:58 UTC
I updated the package. The chroot directory is now /var/lib/powerdns, statedir is /var/run/powerdns, being a symlink to /var/lib/powerdns/var/run/powerdns. Init script now uses rec_control quit to stop the recursor and also has a ping command. 

Thanks!
Comment 3 Sven Wegener gentoo-dev 2007-06-11 19:17:12 UTC
I updated it once more. Our bootmisc init script will remove the symlink in /var/run during boot. I now made the state and chroot directory /var/lib/powerdns and /var/lib/powerdns/var/lib/powerdns a symlink to ../..

Not really clean, but that's the way it is. :(