Move DESIGN and README to root directory.

This commit is contained in:
Nicholas J. Kain
2010-11-12 09:39:33 -05:00
parent b2daf09c10
commit 15f6bb66ee
2 changed files with 35 additions and 54 deletions

View File

@@ -1,104 +0,0 @@
Goals:
1. Security
a. Divide into seperate processes that each have the minimal
system access necessary to complete their task.
b. Use a well defined IPC mechanism to facilitate cooperation
between processes. In this case, UNIX domain sockets are
used, since they allow for UNIX DAC (on Linux, at least).
c. Write each program to be secure; don't rely on the
privilege seperations for security.
d. Simple error handling is favored rather than complex error
handling that may possibly be caused to "recover" in an
exploitable way.
e. Don't make stupid assumptions. Implement only the minimal
functionality necessary to perform a task. Expect brain
damaged or malicious inputs.
f. Run inside a chroot, with minimal privileges via
capabilities or MAC.
2. Reliability
a. Don't try to handle severe errors.
b. Log errors if program state is still sane.
c. Recover from predictable problems if necessary. Make sure
that recovery behavior is well understood and defined.
d. Complicated or unsafe recoveries should not be performed;
instead the program should promptly exit. Dead programs
don't cause exploits.
5. Portability
a. Portability is good, but portability may not be as wide as
a less secure program. Capabilities or MAC are not well
standardized, but remain necessary features.
b. Aside from the previous caveat, try to be as portable as
possible. At the very least, the dhcp client daemon
should be easily portable (only broadcast and perhaps RAW
packets are necessary).
98. Speed
a. If we aren't required to sacrifice anything more
important, it's always good to be fast.
99. Size
a. If we aren't required to sacrifice anything more
important, it's always good to be frugal.
Specifics:
Implementation language will be C. C is universally available, very
predictable, and well accepted. dhcp clients don't have to deal with
complicated data structures or extensively with strings, so C's
largest weaknesses should not be highly apparent. On the other hand,
dhcp clients must extensively deal with the OS in a low-level fashion.
C's strongest points will therefore be used.
More practically, a program written in a compiled language other than
C will be poorly accepted by the average user. Since widespread use
is an eventual goal of ndhc, this point is very eloquent.
For now, I'm taking advantage of the existing udhcpc. With minor
modifications, it will serve quite well as the dhcp client daemon. It
is then only necessary for me to write a client request translator
and a interface change daemon. The result should be a highly modular
solution.
I'm developing on a Linux-based platform. ndhc will first be designed
to work properly on a Linux-based system. I will then make certain
that ndhc works well on a RSBAC-enabled Linux system. Afterwards, I
_may_ spend some effort porting ndhc to FreeBSD (but don't count on it). I
have no personal interest in other platforms.
Layout:
ndhc daemon (root -> chroot -> drop all !(CAP_NET_BROADCAST|CAP_NET_RAW)
-> nopriv)
* handles dhcp protocol issues
* keeps track of leases
* talks to ndhif to perform tasks that require
higher privileges than CAP_NET_BROADCAST or CAP_NET_RAW
ifchd daemon (root -> openfd -> chroot -> drop all !CAP_NET_ADMIN -> nopriv)
* listens for interface change requests via UNIX domain socket
* restricts valid IP ranges that will be accepted
* performs interface changes
* keeps rw fds for system files (such as /etc/resolv.conf) that must
be modified outside the chroot

View File

@@ -1,191 +0,0 @@
ifchd, copyright (c) 2004 Nicholas Kain. Licensed under GNU GPL.
Requirements:
Linux kernel (tested: 2.4, 2.6)
* libcap is required (available via ftp.kernel.org)
C99-compliant C compiler (for C99 struct subobject init)
* any modern GCC should be sufficient
Tested with glibc 2.2.x and 2.3.x. dietlibc is not compatible. I have not yet
tested uclibc.
I may bother to port to other operating systems, but don't count on it. Other
OSes lack the functionality of a [RSBAC|SELinux]+PaX enabled kernel, so I find
them to be less useful for a highly secured system.
INTRODUCTION
------------
ndhc consists of a set of daemons that cooperate in order to provide
privilege-seperated dhcp client services. Each daemon runs with the minimal
necessary privileges in order to perform its task. Currently, ndhc consists of
two daemons: the eponymous ndhc and ifchd.
ndhc communicates with dhcp servers and handles the vagaries of the dhcp
client protocol. It runs as a non-root user inside a chroot. ndhc retains
only the minimum necessary set of privileges required to perform its duties.
These powers include the ability to bind to a low port, the ability to open a
raw socket, and the ability to communicate on broadcast channels. ndhc holds
no other powers and is restricted to a chroot that contains nothing more than a
domain socket filesystem object and (at least on Linux) a urandom device node.
ifchd handles interface change requests. It listens on a UNIX domain socket
for such requests, and denies any client that does not match an authorized gid,
uid, or pid. ifchd runs as a non-root user inside a chroot, and retains only
the power to configure network interfaces. ifchd is designed so that it has
the ability to service multiple client requests simultaneously; a single ifchd
is sufficient for multiple ndhc clients. Only exotic setups should require
this functionality, but it does exist.
Note that ndhc does not support the entire DHCP client protocol. Only the
minimum necessary featureset is implemented. This behavior should be familiar
to anyone who has used software that purports to be be secure.
Many of the features that ndhc depends upon are not entirely standard and vary
between UNIX systems. It is likely that some effort will be required in order
to port ndhc to new systems. The ndhc daemon should be entirely portable aside
from its use of Linux-style POSIX capabilities.
ifchd is necessarily less portable, since it must use system-specific ioctls in
order to configure network interfaces. Additionally, ifchd uses extensions to
the UNIX domain socket family to limit connections to user defined subsets of
possible uids, gids, and pids. These extensions are present in Linux and BSD,
although both Linux and BSD have different interfaces for the functionality.
Patches that provide support for new systems are welcome.
USAGE
-----
1) Compile and install ifchd and ndhc.
a) Build ifchd with "make"
b) Enter ndhc directory and build ndhc with "make"
c) Install the ifchd and ndhc executables in a normal place. I would
suggest /usr/sbin or /usr/local/sbin.
2) Time to create the jail in which ifchd and ndhc will run.
a) Become root and create new group "ifchd".
$ su -
# umask 077
# groupadd ifchd
b) Create new users "ifchd" and "dhcp". The primary group of these
users should be "ifchd".
# useradd -d /var/lib/ndhc -g ifchd ifchd
# useradd -d /var/lib/ndhc -g ifchd dhcp
b) Create the jail directory and set its ownership properly.
# mkdir /var/lib/ndhc
# chown ifchd.ifchd /var/lib/ndhc
# chmod a+rx /var/lib/ndhc
c) Create a urandom device for ndhc to use within the jail.
# cd /var/lib/ndhc
# mkdir dev
# mknod dev/urandom c 1 9
# chown -R root.root dev
# chmod a+rx dev
# chmod a+r dev/urandom
d) (optional) If you wish for logging to properly work, you
will need to properly configure your logging daemon so that it
opens a domain socket in the proper location within the jail.
Since this varies per-daemon, I cannot provide a general
configuration.
3) At this point the jail is usable; ifchd and ndhc are ready to
be used. As an example of a sample configuration, here is my
rc.dhcp:
--START--
#!/bin/sh
case "$1" in
start)
ifchd -i eth0 -p /var/run/ifchd.pid -u ifchd -g ifchd -U dhcp -G ifchd \
-c /var/lib/ndhc &> /dev/null
ndhc -b -i eth0 -u dhcp -C /var/lib/ndhc &> /dev/null
;;
stop)
killall ndhc ifchd
;;
esac
--END--
This script works fine with my personal machines, which are set up
exactly as I have outlined above. If you have not entirely followed my
directions, the script will of course require modifications.
4o) If you encounter problems, I suggest running both ifchd and ndhc in the
foreground, and perhaps compiling ndhc with extra debugging output
(uncomment DEBUG=1 in the Makefile).
BEHAVIOR NOTES
--------------
ifchd does not enable updates of the local hostname and resolv.conf by default.
If you wish to enable these functions, use the --resolve (-r) and --hostname
(-o) flags. See ifchd --help.
ifchd can be set such that it only allows clients to configure particular
network interfaces. The --interface (-i) argument does the trick, and may
be used multiple times to allow multiple interfaces.
RSBAC NOTES
-----------
I was personally unable to get ifchd to properly function with RSBAC_NET_DEV
enabled. Browsing the rsbac source, I was unable to figure out what I was
doing incorrectly -- my RC definitions were as far as I could tell, correct.
Therefore, my directions assume that you have disabled RSBAC_NET_DEV in your
kernel configuration.
The normal usage directions may be followed, but an additional step for rsbac
is necessary. Change to your secoff account and invoke rsbac_fd_menu on the
ifchd and ndhc executables. The AUTH capability for your ifchd and dhcp groups
must be allowed on the corresponding executables, otherwise ifchd and ndhc will
be unable to change to a non-root user and will refuse to run.
GRSECURITY NOTES
----------------
Make sure that CONFIG_GRKERNSEC_CHROOT_CAPS is disabled. Otherwise, ifchd will
lose its capabilities (in particular, the ability to reconfigure interfaces)
when it chroots.
PORTING NOTES
-------------
Unportable functions are isolated to linux.c. Any attempts to port ifchd to
other platforms should isolate platform-dependent code to similarly named
compilation units (eg: for FreeBSD, freebsd.[ch]).
There are four major functions that ifchd depends upon that are not generally
portable. First, it uses the SO_PEERCRED flag of getsockopt() to discriminate
authorized connections by uid, gid, and pid. Similar functionality exists in
at least the BSDs; however, it has a different API. Second, ifchd takes
advantage of Linux capabilities so that it does not need full root privileges.
Capabilities are supposedly a POSIX feature, but in practice, they vary greatly
from system to system. Third and fourth, ifchd configures network interfaces
and routes. Interface and route configuration is entirely non-portable,
usually requiring calls to the catch-all ioctl(), and will almost certainly
require platform-dependent code.
Some standard C libraries include a native implementation of strlcpy() and
strlcat(). Such defines may conflict with my implementations in strl.c/strl.h.
It is up to the user whether the standard C library implementations should be
used. Note that some machines implement strlcpy() and strlcat() with
nonstandard semantics (notably Solaris). On these systems, using the
system-provided implementations may lead to security problems. Such problems
are the fault of the vendor. If you are unsure whether your system is correct
or not, I suggest using the implementation that I provide.