Update README. Mention the ncmlib requirement and make it more succinct.
This commit is contained in:
parent
759b6bd831
commit
b6dda8f4f8
132
README
132
README
@ -1,4 +1,4 @@
|
|||||||
ndhc, Copyright (C) 2004-2015 Nicholas J. Kain.
|
ndhc, Copyright (C) 2004-2017 Nicholas J. Kain.
|
||||||
See LICENSE for licensing information. In short: Two-clause / New BSD.
|
See LICENSE for licensing information. In short: Two-clause / New BSD.
|
||||||
|
|
||||||
Requirements:
|
Requirements:
|
||||||
@ -6,6 +6,7 @@ Requirements:
|
|||||||
Linux kernel
|
Linux kernel
|
||||||
GNU Make or CMake
|
GNU Make or CMake
|
||||||
Ragel
|
Ragel
|
||||||
|
ncmlib
|
||||||
|
|
||||||
INTRODUCTION
|
INTRODUCTION
|
||||||
------------
|
------------
|
||||||
@ -88,6 +89,10 @@ different, it will forget about the old lease and request a new one.
|
|||||||
USAGE
|
USAGE
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
0) Make sure that ncmlib is present in the ndhc source directory:
|
||||||
|
$ ls
|
||||||
|
CMakeLists.txt LICENSE Makefile ncmlib README src
|
||||||
|
|
||||||
1) Compile and install ndhc.
|
1) Compile and install ndhc.
|
||||||
a) make
|
a) make
|
||||||
b) Install the build/ndhc executable in a normal place. I would suggest
|
b) Install the build/ndhc executable in a normal place. I would suggest
|
||||||
@ -188,16 +193,12 @@ subprocesses.
|
|||||||
If the host system lacks volatile storage, then a clientid should manually
|
If the host system lacks volatile storage, then a clientid should manually
|
||||||
be specified using the -I or --clientid command arguments.
|
be specified using the -I or --clientid command arguments.
|
||||||
|
|
||||||
RANDOMNESS NOTES
|
GRSECURITY NOTES
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
Each ndhc subprocess maintains a PCG PRNG that is uniquely seeded from the
|
Make sure that CONFIG_GRKERNSEC_CHROOT_CAPS is disabled. Otherwise, ndhc will
|
||||||
kernel random device at startup. Each PRNG consumes 128 bits of entropy for
|
lose its capabilities (in particular, the ability to reconfigure interfaces)
|
||||||
its initial state.
|
when it chroots.
|
||||||
|
|
||||||
DHCP does not require cryptographic randomness, so this arrangement should
|
|
||||||
be more than sufficient to ensure proper UUIDs, assuming only that the
|
|
||||||
kernel random device is even minimally seeded with real entropy.
|
|
||||||
|
|
||||||
PORTING NOTES
|
PORTING NOTES
|
||||||
-------------
|
-------------
|
||||||
@ -229,116 +230,3 @@ for raw sockets and ARP. These are largely Linux-specific, too.
|
|||||||
|
|
||||||
7) ndhc can optionally use seccomp-filter to allow only a set of whitelisted
|
7) ndhc can optionally use seccomp-filter to allow only a set of whitelisted
|
||||||
syscalls. This functionality is Linux-specific.
|
syscalls. This functionality is Linux-specific.
|
||||||
|
|
||||||
HISTORY
|
|
||||||
-------
|
|
||||||
|
|
||||||
I started writing ndhc back in 2004. My ISP at the time required a DHCP
|
|
||||||
client for connection authentication, and I was not comfortable with any
|
|
||||||
of the existing clients, which all ran as root and had colorful security
|
|
||||||
histories. DHCP is generally not a routed protocol, and lacks real
|
|
||||||
authentication mechanisms in real world deployments (some largely
|
|
||||||
abandoned RFCs for such behavior do exist), so no program existed to
|
|
||||||
fill the niche of a truly secure DHCP client.
|
|
||||||
|
|
||||||
My router/server at the time ran a custom Linux distro that was designed
|
|
||||||
for extreme security. A root privileged DHCP client would be nearly the
|
|
||||||
only root-owned process running on the machine, so I was highly motivated
|
|
||||||
to develop an alternative.
|
|
||||||
|
|
||||||
A separate ifchd was first written entirely from scratch. It did not take long
|
|
||||||
to write, since it was by design rather simple, and I was already familiar with
|
|
||||||
the quirks of Linux capabilities. That left me with the choice of adapting an
|
|
||||||
existing DHCP client or writing my own from scratch.
|
|
||||||
|
|
||||||
At the time, I just wanted something that would work, so my choice was to
|
|
||||||
adapt udhcpc to work with ifchd. udhcpc was chosen since it was intended to
|
|
||||||
be used with resource-constrained or embedded systems, and was thus very
|
|
||||||
small. ISC dhclient was another alternative, but it is an extremely large
|
|
||||||
program, and it would have been very hard to audit it for correctness.
|
|
||||||
|
|
||||||
udhcpc was not did not really fit my requirements well, since it was designed
|
|
||||||
to be small at all costs, sacrificing correctness when necessary. The code was
|
|
||||||
hard to follow, and had many quirks. Bounds-checking was rare, type aliasing
|
|
||||||
common, and state transitions were convoluted. Not all of the client was
|
|
||||||
asynchronous, and no precautions were taken against conflicting peers. ARP was
|
|
||||||
not used at all.
|
|
||||||
|
|
||||||
However, it was small. With a lot of work, I ripped out the script-calling
|
|
||||||
mechanisms and replaced them with ifchd requests. Bounds-checking was
|
|
||||||
aggressively (and somewhat hamfistedly) retrofitted into the code. It was
|
|
||||||
cleaned to a degree, and importantly it worked for connecting to my ISP.
|
|
||||||
|
|
||||||
Then I changed ISPs. My new ISP used PPPoE, not DHCP. Around the same time, I
|
|
||||||
also switched to using Gentoo rather than a hand-built distribution. I didn't
|
|
||||||
have time to maintain the old custom setup, and it was very hard keeping up
|
|
||||||
with library vulnerabilties in eg, zlib or openssl, and ensuring that all
|
|
||||||
installed binaries, dynamic and static, were updated. ndhc was abandoned for
|
|
||||||
many years. It wasn't needed on my server, and it was "too much effort" to
|
|
||||||
deviate from the stock distro DHCP clients on other machines.
|
|
||||||
|
|
||||||
Then, around 2008, I changed ISPs again. This time my new ISP used DHCP and
|
|
||||||
not PPPoE. So, after a few months, I decided to dust off the old ndhc/ifchd
|
|
||||||
project and adapt it to my modern standards and machines.
|
|
||||||
|
|
||||||
ifchd was in good shape and required little work. I ended up rewriting
|
|
||||||
ndhc. The only parts that remained from the original were the parts that
|
|
||||||
I had already rewritten before, and some of those were rewritten, too.
|
|
||||||
|
|
||||||
Eventually ifchd was rewritten to use a Ragel-generated DFA-based parser to
|
|
||||||
make it easier to verify correct behavior for all possible inputs.
|
|
||||||
|
|
||||||
Quite a while later, I eventually merged ifchd into the same binary as ndhc
|
|
||||||
and instead rely on forking subprocesses and using socketpairs for IPC. This
|
|
||||||
brought a lot of simplifications, particularly for user configuration.
|
|
||||||
|
|
||||||
Afterwards, privilege separation was applied to the remaining capabilities,
|
|
||||||
creating the ndhc-sockd subprocess. After this change, the main ndhc
|
|
||||||
process runs completely unprivileged.
|
|
||||||
|
|
||||||
The end result is a modern DHCP client is largely RFC-compliant, except where
|
|
||||||
the RFCs dictate behavior that would be buggy, overly complex, useless,
|
|
||||||
or exploitable. DHCP is poorly specified, and real-world servers and clients
|
|
||||||
vary a lot from the RFCs, so these conditions are necessary for a useful
|
|
||||||
program.
|
|
||||||
|
|
||||||
Although ndhc's implementation and behavior are different, I have to credit
|
|
||||||
the idea of using netlink events to discover hardware link status transitions
|
|
||||||
to Stefan Rompf and his 'dhcpclient' program. The Linux netlink events that
|
|
||||||
are used are otherwise rather obscure and poorly documented, and I wouldn't
|
|
||||||
have known about them otherwise.
|
|
||||||
|
|
||||||
GRSECURITY NOTES
|
|
||||||
----------------
|
|
||||||
|
|
||||||
Make sure that CONFIG_GRKERNSEC_CHROOT_CAPS is disabled. Otherwise, ndhc will
|
|
||||||
lose its capabilities (in particular, the ability to reconfigure interfaces)
|
|
||||||
when it chroots.
|
|
||||||
|
|
||||||
DHCP PROTOCOL QUIRKS
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Send a packet that has an options field set to:
|
|
||||||
'DHCP-OPTION-OVERLOAD:3'
|
|
||||||
Then in the file and sname fields:
|
|
||||||
'DHCP-OPTION-OVERLOAD:3'
|
|
||||||
I suspect some bad DHCP programs will hang given this input.
|
|
||||||
|
|
||||||
DHCP explicitly specifies that there is no minimum lease time and also
|
|
||||||
specifies that the minimum default rebinding time is leasetime*0.875 and
|
|
||||||
the minimum default renewing time is leasetime*0.500. All times are relative
|
|
||||||
to the instant when the lease is bound and are specified in seconds. Taken
|
|
||||||
together, this means that a client strictly implementing the RFC should
|
|
||||||
accept a lease that either is perpetually rebinding (lease == 1s) or instantly
|
|
||||||
expires (lease == 0s). ndhc ignores the RFC and specifies a minimum lease
|
|
||||||
time of one minute.
|
|
||||||
|
|
||||||
Renew and rebind times are optionally specified and may take on any value.
|
|
||||||
This means that a malicious server could demand a rebind time before a renew
|
|
||||||
time, or make these times ridiculously short, or specify both times past
|
|
||||||
that of the lease duration. ndhc avoids all of this nonsense by simply
|
|
||||||
ignoring these options and using the default values specified by the RFC.
|
|
||||||
|
|
||||||
There are other quirks, but these are just several interesting ones that
|
|
||||||
immediately occur to me while I'm writing this document.
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user