1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
Name: chrooting and other forms of paranoia
File: chroot.txt
Date: 25 July 2001
Auth: Russell Kroll <rkroll@exploits.org>
Yes, you can run the model drivers and upsd in a chrooted jail. You have
to create a miniature version of your system in a separate tree that has
everything that they need. This means things like your C library if you
dynamically linked the programs, configuration files, and so on.
This assumes you are already using the "security domains" setup as seen in
the FAQ with nutdev and nutsrv. If you aren't, go read about that, get it
working, then come back to this document. This is a lot easier to do if
you have the non-root startup already figured out.
Fair notice: this can be deep magic if you're not familiar with how
programs link to each other on your system. If you've never run ldconfig
by hand or installed something from source before, this may not be for
you.
In this case I'm using /chroot/nut as the new root.
Design
------
Remember that the drivers and upsd talk to each other initially through
state files - typically in /var/state/ups. Once they get hooked up
through that file, they used shared memory and SysV IPC to send things
around. So, they do need to both run in the same jail filesystem.
Prepare the jail
----------------
On my Slackware based guinea pig system, here are the things that had
to be moved over to make everything happy:
/bin/su
/bin/sh (symlink to /bin/bash, as it is in the real /bin)
/bin/bash
/usr/local/ups (obviously - copy what you need)
/lib/ld-2.2.2.so (change version numbers as needed)
/lib/libc-2.2.2.so
/lib/libcrypt-2.2.2.so
/lib/libnss_compat-2.2.2.so
/lib/libnsl-2.2.2.so
/lib/libtermcap.so.2.0.8 (bash needs this)
/lib/libdl-2.2.2.so
/etc/ld.so.conf (empty file, to make ldconfig be quiet)
/etc/login.defs (same as your normal one - keeps su happy)
/etc/passwd (just nutdev/nutsrv entries)
/etc/group (just the nut entry)
/var/state/ups (same permissions as the original one)
/dev/console (use cp -a for these to preserve details)
/dev/null
/dev/log
/dev/ttyS1 (or whatever port you may be using)
Once all the libraries are in place, you need to run ldconfig to generate
all the symlinks for those so files.
/sbin/ldconfig -r /chroot/nut
In the /etc/passwd and group files, just copy the entries you were using
for nutsrv and nutdev from the real system files. Nothing else is needed.
You'll have to restart syslogd and add a switch that will make it pick
up the log entries from the programs.
/usr/sbin/syslogd -a/chroot/nut/dev/log
Start the programs
------------------
Finally, you can start the driver:
/usr/sbin/chroot /chroot/nut /bin/su nutdev -c \
"/usr/local/ups/bin/newapc /dev/ttyS1"
Or, if you have switched to using the driver controller:
/usr/sbin/chroot /chroot/nut /bin/su nutdev -c \
"/usr/local/ups/bin/upsdrvctl start"
Then start the server:
/usr/sbin/chroot /chroot/nut /bin/su nutsrv -c \
"/usr/local/ups/sbin/upsd"
If everything has been setup correctly, they should start up as before,
and the client programs like upsmon will see no difference.
Obviously this is expected to be quite a bit different on other systems,
but the principle is the same. Clone what you need as far as libraries
and support files go, and leave the rest behind. I recommend using tools
like strace where available to figure out other things that may be
needed. su didn't work until all those glibc support files were copied
in, for example. It would just say "Sorry.", which is not a great help.
Be sure you change your startup scripts to use the new chroot-based
init methods once you're satisfied with the operation of the programs
in this environment.
If everything has been done correctly, you'll have a clean environment
where the programs never have root. So, if they happen to be compromised
somehow, the attacker is confined to the chroot jail.
upsmon
======
Note that upsmon must start with full root privileges since it has to
signal init to switch runlevels and shut down. Recent developments have
minimized the use of root, however. upsmon by default now drops root
powers in the main process shortly after reading the config file.
During normal operations, there are two upsmons running. One is a
privileged parent which does nothing but block in read() reading for a
signal from the unprivileged child which does all the monitoring work. If
the parent gets the proper result from the child, then it calls the
SHUTDOWNCMD. Any other character results in it shutting down with an
error.
This design of a split parent/child with a limited communications channel
was inspired by the authentication techniques in Solar Designer's popa3d.
chrooting upsmon has not yet been attempted, but it should work if you can
tell your init to start the shutdown from inside the jail.
|