daf42ccb29
ifchd if it is necessary to do so, just as is the case for other keywords. Make data sending in ifchange_*() collect all keywords into a buffer that is sent in a single sockwrite() rather than performing a sockwrite() for every keyword. Minor documentation updates.
180 lines
7.0 KiB
Plaintext
180 lines
7.0 KiB
Plaintext
ifchd, copyright (c) 2004-2011 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
|
|
|
|
CMake (tested: 2.8)
|
|
|
|
Tested with glibc. dietlibc is not compatible. I have not tested uclibc.
|
|
|
|
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 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. Notably, DHCP
|
|
options concatenation and IPv4 Link Local Addressing as defined in RFC3927 are
|
|
not and will not be supported.
|
|
|
|
On the other hand, ndhc fully implements RFC5227's address conflict detection
|
|
and defense. Great care is taken to ensure that address conflicts will be
|
|
detected, and ndhc also has extensive support for address defense. Care is
|
|
taken to prevent unintentional ARP flooding under any circumstance.
|
|
|
|
ndhc also monitors hardware link status via netlink events and reacts
|
|
appropriately when interface carrier status changes or an interface is
|
|
explicitly deconfigured.
|
|
|
|
USAGE
|
|
-----
|
|
|
|
1) Compile and install ifchd and ndhc.
|
|
a) Create a build directory:
|
|
mkdir build && cd build
|
|
b) Create the makefiles:
|
|
cmake ..
|
|
c) Build ifchd and ndhc:
|
|
make
|
|
d) Install the ifchd/ifchd and ndhc/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 -s /sbin/nologin -g ifchd ifchd
|
|
# useradd -d /var/lib/ndhc -s /sbin/nologin -g ifchd dhcp
|
|
|
|
b) Create the jail directory and set its ownership properly.
|
|
|
|
# mkdir /var/lib/ndhc
|
|
# chown root.root /var/lib/ndhc
|
|
# chmod a+rx /var/lib/ndhc
|
|
# cd /var/lib/ndhc
|
|
# mkdir var
|
|
# mkdir var/state
|
|
# mkdir var/run
|
|
# chown -R ifchd.ifchd var
|
|
# chmod -R a+rx var
|
|
# chmod g+w var/run
|
|
|
|
c) Create a urandom device for ndhc to use within the jail.
|
|
|
|
# mkdir dev
|
|
# mknod dev/urandom c 1 9
|
|
# mknod dev/null c 1 3
|
|
# chown -R root.root dev
|
|
# chmod a+rx dev
|
|
# chmod a+r dev/urandom
|
|
# chmod a+rw dev/null
|
|
|
|
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 wan0 -p /var/run/ifchd.pid -u ifchd -g ifchd -U dhcp \
|
|
-G ifchd -c /var/lib/ndhc &> /dev/null
|
|
ndhc -b -i wan0 -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.
|
|
|
|
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
|
|
-------------
|
|
|
|
There are seven 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 were a proposed POSIX feature that was not made part of the
|
|
official standard, so any implemention that may exist will be system-dependent.
|
|
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. Fifth and sixth, both ifchd and ndhc use epoll() and signalfd(), which
|
|
are Linux-specific. Seventh, ndhc uses netlink sockets extensively for
|
|
both fetching data and hardware link state change notification events.
|
|
|
|
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.
|