How can I configure a DHCP server to assign addresses based on the OS that is running Solved maybe!
Marc Chamberlin
marc at marcchamberlin.com
Wed Jun 2 02:28:11 UTC 2010
Thanks everyone for all your help, it gave me a lot to explore and was a
big help. I have spent quite a few days on this, and though I hate
throwing stones at a project, with as much invested in it as this one
apparently has, and been around as long as it has, I am quite surprised
at how difficult it is/was to work with and configure this server. I
think a redesign, with particular attention paid to the model and
configuration language should be seriously considered, but that is just
IMHO.... Also, a number of (ok maybe I should say possible) bugs have
surfaced during the course of my investigations, which made it far more
difficult to find a solution, than it should have been. I will go
through these and then present what I think is a solution and ask for
opinions, since much of the underlying model is undocumented, (as far as
I could find) in particular the precedence that is used by the server as
it builds it's database and decision tree for IP address assignments.
First the problems I have discovered -
1. The biggest difficulty I had was trying to instrument my dhcpd.conf
file with logging messages so as to determine what was happening when
things went wrong. And frustratingly I discovered that logging ONLY
works with the server successfully uses the configuration setup to
assign an IP address. But when something goes wrong, and the server
cannot assign an IP address to a client, it appears that the code simply
drops to a fall through error message (which is very misleading) and
none of the output from log statements is outputted! This is a very
serious bug for users who are trying to set up their dhcp server,
because when you most need help from instrumenting your configuration
code, i.e. when a problem is occurring, the logging mechanism itself is
broke also! I finally discovered that nasty problem by putting a simple
log statement at the very beginning of my dhcpd.conf file and
discovering no output from it occurred whenever the dhcp server failed
to find an IP address that it could assign to a client. But it always
put out the log messages when it was successful in assigning an IP
address! This failure forced me to work largely in the dark, with having
to second guess a lot of possible causes as to why things were failing...
The fall through error message that I referred to seems to say " no free
leases". I submit that this is wrong and misleading users, myself
included. In actual fact the problem is the dhcp server could not assign
a lease for an IP address due to the way the dhcpd.conf file is
configured/mis-configured.
2. The hardware "object" while it may be convenient in some cases, I
submit it is confusing and difficult to work with. The underlying data
structure for this object is actually two fields, a hardware type
identifier and a numeric encoded mac address. I don't understand the
need to bond the hardware type with the mac address so tightly, and not
provide any easier objects for users to work with and manipulate
instead. It took me quite awhile to figure out how to use this object
effectively, given my goal of using the mac address of the client's
interface in conditional expressions! See below..
3. The binary-to-ascii function does not match the format of mac
addresses that the dhcp server displays in its own informational log
statements. The main issue is that it does not put out leading zeros for
small hexadecimal numbers, while mac addresses are shown in the log
files with leading zeros. This prevents the user from doing a simple cut
and paste of mac addresses from the log file and using that format in
match statements within dhcpd.conf. This is a natural tendency on users
part, and if the user is not aware of this difference it will cause
confusion and a lot of time wasted in tracking down a problem caused by
this difference.
4. There is not enough examples or descriptions on how to declare and
use server variables within a dhcpd.conf file. I fooled around with all
sorts of variants of what the following example attempts and could not
find any solution to get this to work. It would have saved a lot of
typing and made things more readable if it had worked...
macAddress = binary-to-ascii(16, 8, ":", substring (hardware, 1, 6));
log (info, concat("Mac Address: ", macAddress));
BTW the following does work -
log (info, concat("Mac Address: ", binary-to-ascii(16, 8, ":", substring
(hardware, 1, 6))));
5. In order to handle clients with more than one interface, and allow
clients to dynamically switch between different interfaces, I included
the following two statements in my dhcpd.conf file -
deny duplicates;
ping-check on;
My goal was to force a static IP address assignment to a particular
client, by using the class and pool declarations shown below, in
conjunction with these declarations. I noted instead, that if a client
booted up and initialized one of two interfaces (wired or wireless) then
switched interfaces (disabling the first initialized interface in the
process) that the dhcp server was unable to transfer the IP address
assigned to the first interface to the second one based on a simple
DHCPREQUEST. Instead the transfer only occurred if the client
reinitialize his interface and forcing a DHCPDISCOVER instead.
Perhaps this is correct dhcp behavior, but I would think that doing a
ping check and discovering that the client is no longer responding to
it, would have been sufficient to prevent the user unfriendly
requirement of having to reinitialize an interface just because it was
hot-plugged and/or the user turned the other off. So I am confused!
---
That said, I set up a test network of a variety of clients, and after
lots of experimentation I arrived at the following configuration
segment, using classes and pools, to assign static IP addresses to
clients based on their operating system and interfaces. This has the
advantage of showing up in the logs, and if I am correct, gets around
the limitations of using host declarations to assign static IP
addresses. I won't show my entire dhcpd.conf file as most of it is
pretty standard stuff, except for the two declarations I mentioned
above. Sorry this is a bit long still, but I limited my test to just 5
systems on a small network.....
class "marcslaptop_Vista_Class" {
match if ((substring(option vendor-class-identifier, 0, 4) = "MSFT") and
((ucase(binary-to-ascii(16, 8, ":", substring (hardware, 1,
6))) = ucase("0:1a:73:55:7d:f")) or
(ucase(binary-to-ascii(16, 8, ":", substring (hardware, 1,
6))) = ucase("0:16:36:c2:65:a4"))));
log (info, "marcslaptop_Vista_Class matched");
}
class "marcslaptop_Linux_Class" {
# match if (option dhcp-client-identifier = "\000marcslaptop") and
match if ((substring(option dhcp-client-identifier,1,11) =
"marcslaptop") and
((ucase(binary-to-ascii(16, 8, ":", substring (hardware, 1,
6))) = ucase("0:1a:73:55:7d:f")) or
(ucase(binary-to-ascii(16, 8, ":", substring (hardware, 1,
6))) = ucase("0:16:36:c2:65:a4"))));
log (info, "marcslaptop_Linux_Class matched");
}
class "nova_XP_Class" {
match if (substring(option vendor-class-identifier, 0, 4) = "MSFT") and
(ucase(binary-to-ascii(16, 8, ":", substring (hardware, 1,
6))) = ucase("0:13:20:8e:59:41"));
log (info, "nova_XP_Class matched");
}
class "nova_Linux_Class" {
match if (option dhcp-client-identifier = "\000nova") and
(ucase(binary-to-ascii(16, 8, ":", substring (hardware, 1,
6))) = ucase("0:13:20:8e:59:41"));
log (info, "nova_Linux_Class matched");
}
class "darkstar_2000_Class" {
match if (substring(option vendor-class-identifier, 0, 4) = "MSFT") and
(ucase(binary-to-ascii(16, 8, ":", substring (hardware, 1,
6))) = ucase("0:e0:29:6d:fd:a3"));
log (info, "darkstar_2000_Class matched");
}
class "stephslaptop_Vista_Class" {
match if (substring(option vendor-class-identifier, 0, 4) = "MSFT") and
(ucase(binary-to-ascii(16, 8, ":", substring (hardware, 1,
6))) = ucase("0:1A:73:29:73:71"));
log (info, "stephslaptop_Vista_Class matched");
}
class "teraserver_Class" {
match if (ucase(binary-to-ascii(16, 8, ":", substring (hardware, 1,
6))) = ucase("0:D:B:F7:0:6"));
log (info, "teraserver_Class matched");
}
subnet 192.168.2.0 netmask 255.255.255.0 {
default-lease-time 14400;
max-lease-time 172800;
pool {allow members of "marcslaptop_Linux_Class"; range 192.168.2.10;}
pool {allow members of "marcslaptop_Vista_Class"; range 192.168.2.15;}
pool {allow members of "nova_Linux_Class"; range 192.168.2.20;}
pool {allow members of "nova_XP_Class"; range 192.168.2.25;}
pool {allow members of "darkstar_2000_Class"; range 192.168.2.35;}
pool {allow members of "stephslaptop_Vista_Class"; range 192.168.2.45;}
pool {allow members of "teraserver_Class"; range 192.168.2.50;}
pool {
deny members of "marcslaptop_Linux_Class";
deny members of "marcslaptop_Vista_Class";
deny members of "nova_Linux_Class";
deny members of "nova_XP_Class";
deny members of "darkstar_2000_Class";
deny members of "stephslaptop_Vista_Class";
deny members of "teraserver_Class";
deny known-clients;
allow all clients;
range 192.168.2.101 192.168.2.199;}
}
There are a few things of note in the pool declaration for the final
pool segment that assigns IP addresses to unknown clients.
1. I added the deny members of "class" statements to prevent an IP
address assignment to a client which activates a second interface. This
requirement surprised me, but it seems to work.
2. The deny known-clients statement allows me to continue to use host
declarations for systems which I will never have a problem identifying
and making a static IP address assignment to.
3. The allow all clients statement is a guess on my part, as nothing is
said about precedence of configuration statements in the documentation.
But my guess is that this will allow assignment of an IP address to all
unknown clients without my having to specify all clients on my network
with host statements. If this won't work, and I have to use the allow
unknown clients statement instead, then I would be right back to where I
started from, having to specify hosts declarations, which I am trying to
get around due to their inadequate capabilities. I have not yet fully
tested this to my satisfaction, but initial trials seem to indicate it
works....
I would welcome thoughts an feedback on whether this scheme will work or
not. It is a bit messy and will be cumbersome to set up for a large
network of users, but perhaps some scripts would ease the pain. At least
the necessary information should be discoverable now, from the log and
dhcpd.leases files, for me to manage the dhcp server without having to
physically interact with each client computer..
Marc..
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 6464 bytes
Desc: S/MIME Cryptographic Signature
URL: <https://lists.isc.org/pipermail/dhcp-users/attachments/20100601/38c1d117/attachment.bin>
More information about the dhcp-users
mailing list