Desc: chrooting and other forms of paranoia File: chroot.txt Date: 24 August 2003 Auth: Russell Kroll It has been possible to run the drivers and upsd in a chrooted jail for some time, but it involved a number of evil hacks. The 1.3 series adds much saner chroot behavior, using BIND 9 as an inspiration. The old way involved creating an entire tree, complete with libraries, a shell (!), and many auxiliary files. This was hard to maintain and could have become an interesting playground for an intruder. The new way is minimal, and leaves little in the way of usable materials within the jail. This document assumes that you already have created at least one user account for the software to use. If you're still letting it fall back on "nobody", stop right here and go figure that out first. It also assumes that you have everything else configured and running happily all by itself. Essentially, you need to create your configuration directory and state path in their own little world, plus a special device or two. For the purposes of this example, the chroot jail is /chroot/nut. The programs have been built with the default prefix, so they are using /usr/local/ups. First, create the confpath and bring over a few files. mkdir -p /chroot/nut/usr/local/ups/etc cd /chroot/nut/usr/local/ups/etc cp -a /usr/local/ups/etc/upsd.users . cp -a /usr/local/ups/etc/upsd.conf . cp -a /usr/local/ups/etc/ups.conf . I'm using 'cp -a' to maintain the permissions on those files. Now bring over your state path, maintaining the same permissions as before. mkdir -p /chroot/nut/var/state cp -a /var/state/ups /chroot/nut/var/state Next we must put /etc/localtime inside the jail, or you may get very strange readings in your syslog. You'll know you have this problem if upsd shows up as UTC in the syslog while the rest of the system doesn't. mkdir -p /chroot/nut/etc cp /etc/localtime /chroot/nut/etc Note that this is not "cp -a", since we want to copy the *content*, not the symlink that it may be on some systems. Finally, create a tiny bit of /dev so the programs can enter the background properly - they redirect fds into the bit bucket to make sure nothing else grabs 0-2. mkdir -p /chroot/nut/dev cp -a /dev/null /chroot/nut/dev Try to start your driver(s) and make sure everything fires up as before. upsdrvctl -r /chroot/nut -u nutdev start Once your drivers are running properly, try starting upsd. upsd -r /chroot/nut -u nutsrv Check your syslog. If nothing is complaining, try running clients like upsc and upsmon. If they seem happy, then you're done. symlinks -------- After you do this, you will have two copies of many things, like the confpath and the state path. I recommend deleting the 'real' /var/state/ups, replacing it with a symlink to /chroot/nut/var/state/ups. That will let other programs reference the .pid files without a lot of hassle. You can also do this with your confpath and point /usr/local/ups/etc at /chroot/nut/usr/local/ups/etc unless you're worried about something hurting the files inside that directory. In that case, you should maintain a 'master' copy and push it into the chroot path after making changes. upsdrvctl itself does not chroot, so the ups.conf still needs to be in the usual confpath. upsmon ------ This has not yet been applied to upsmon, since it can be quite complicated when there are notifiers that need to be run. One possibility would be for upsmon to have three instances: - privileged root parent that listens for a shutdown command - unprivileged child that listens for notify events - unprivileged chrooted child that does network I/O This one is messy, and may not happen for some time, if ever. Config files ------------ You may now set chroot= and user= in the global section of ups.conf. upsd chroots before opening any config files, so there is no way to add support for that in upsd.conf at the present time.