Can someone look over my dhcpd.conf config and see if it looks okay? After fighting the provisioning software we just acquired, I've decided that since we have all the customer info in database form already, that I'm just going to write my own. When subscribers are added or removed, I'm just going to have it dynamically rebuild the dhcpd.conf file from the db and upload it to the dhcp server via ftp (then restart the service).
Anyway, I just put this file together and don't have time to test it now (will in the morning) so can anyone point out any glaring errors?
I do have a few questions about this method though...
1. I'm assuming the DHCP server is smart enough to figure out which scope the listed hosts belong to, so I can leave the hosts ungrouped?
2. Do I need to define a default, zero-service modem config file in the main scope declaration, or will the modems not being able to boot because the the tftp download fails be enough?
3. How can I handle customers needing static IP leases? I could tie their CPE mac addy to a static lease, but I'd rather be able to tie it to a CM mac, so no matter what CPE mac connects to that modem, it will get the proper IP.
##### CM Pool ######################################
subnet 172.16.16.0 netmask 255.255.248.0 {
range 172.16.16.11 172.16.20.0;
option domain-name-servers 12.127.16.68,12.127.16.67;
option routers 172.16.16.10;
option tftp-server-name "172.16.16.8";
server-name "172.16.16.8";
option broadcast-address 172.16.23.255;
default-lease-time 86400;
max-lease-time 86400;
option time-offset -25200;
option time-servers 172.16.16.8;
}
##### CPE Pool ######################################
subnet 172.20.16.0 netmask 255.255.248.0 {
range 172.20.16.11 172.20.20.0;
option domain-name-servers 12.127.16.68,12.127.16.67;
option routers 172.20.16.10;
option broadcast-address 172.20.23.255;
default-lease-time 86400;
max-lease-time 86400;
}
###### Subscribed Cable Modems #################################
host host0011E3DD550D {
hardware ethernet 00:11:E3:DD:55:0D;
filename "/cmconfig/gold.bin";
}
host host0014F866B1A4 {
hardware ethernet 00:14:F8:66:B1:A4;
filename "/cmconfig/gold.bin";
}
host host0011E3A9647B {
hardware ethernet 00:11:E3:A9:64:7B;
filename "/cmconfig/gold.bin";
}
host host000F666A7355 {
hardware ethernet 00:0F:66:6A:73:55;
filename "/cmconfig/gold.bin";
}
on another note, since I'm going to have to add facilities for monitoring and managing modems (via snmp), is it easier to just use the CMTS oids and have it manage the modems, or figure out the snmp community strings for the modems themselves and control them directly?
I figured out the DHCP stuff, although I'm still not sure if I want to use a default zero-service config file or not.
Everything seems to be working well except for my config files. I can't get the MIC to work out. I used the docsis config file generator and set the MIC shared secret per the documentation, but the file will not authenticate. What's the trick to it?
edit: I was being stupid. I had a linefeed at the end of the string that was screwing it up. Fixed that and everything is working fine now.
Hello, I saw your post about DHCP and wanted to ask a question. How do you guarantee the modem getting the same IP address without using a static host command with fixed IP address? We want to input all of our cable modems into an NMS (i.e. OpenNMS,Zenoss) and then put the modems on a map. This way when we have an outage, we can look at a screen to see which node the modems belong to. Or, do you not allow modems to have static IP addresses? Please let me know your thoughts.
Thanks,
Aaron
I don't issue static IP's to the modems, but it would be easy to implement.
I have a script that adds the modems mac address and their info into a mysql database. After inserting it, it issues the OMAPI command to authorize the MAC in the DHCP server. To do what you want, I would just need to add an 'ip' field to the modem database, and have it pair an IP to the mac address. Then when you make the OMAPI call, you specify an IP address, making that host definition static.
I didn't do this, as I'd much rather let DHCP do it's thing and assign dynamic addresses. Now I do use nagios to monitor my networks(similar to zenoss) and I have thoughts on how to integrate it.
1. (doing right now). I have a script that polls the CMTS for a list of IP's then queries each modem and retrieves it's reported Rx and Tx powers. Then it calculates the statistical moments of the distribution and reports those back. I can't see every modem individually, but if part of the plant goes crazy, I can see the shift in the distribution and know there is a problem. My properties are small apt complexes with at most 200 subs, so works fairly well.
2. (working on using nagios). Since all mac address - address relations are stored in a database, it isn't hard to generate a list of modem macs with some sort of physical relation. My thought is to poll the database every few hours to get a list of subscriber mac addresses, then poll the cmts to get the corresponding IP's. Use this information to generate a config file then reload the NMS. You can create a template 'modem' containing all the common info, so this dynamic config would be minimalistic.
If using Zenoss, I think it can perform dynamic host discovery, so you might be able to configure it to periodically scan the network for new hosts. Then write a plugin that checks the database or DHCP server to see if a MAC is authorized and add it as a service. That way you could monitor modems that aren't registered but attempting to get service.
Here is some thoughts on your set up,
1. Use classes to differentiate between modems and everything else
Here is a class for modems
class "CM" {
match if substring(option vendor-class-identifier,0,6) = "docsis";
spawn with option agent.remote-id;
}
For this to work properly you have to turn on option 82 on your CMTS this is the cisco command "ip dhcp relay information option" may be different for different brands of CMTS.
then in your subnet decls you can add the line
'allow members of CM' and 'deny unknown-clients;' to the CM subnet
and
'deny members of CM' to the CPE pool
This way unknown modems are denied dhcp.
2. instead of hardcoding the config file to each host use groups
i.e.
group Gold
{
filename "/cmconfig/gold.bin";
option bootfile-name "/cmconfig/gold.bin";
}
note the alternate bootfile option is for some funky modems so it gets right info.
then in your hosts decl you tell it what group and it adds the right stuff.
i.e.
host host000F666A7355 {
hardware ethernet 00:0F:66:6A:73:55;
group "Gold";
}
3. In addition to the 'option tftp-server-name "172.16.16.8";' you need a
next-sever 172.16.16.8;
line for some stupid modems or they will get hung up not able to tftp.
4. Rather than "dynamically rebuild the dhcpd.conf file from the db and upload it to the dhcp server via ftp (then restart the service)." While this solution does indeed work, there is definate possibility that if something goes wrong, i.e. typeo in your dhcpd.conf that you will be left with a non-working dhcpd server. You should look into omapi for dhcpd it allows you to add hosts dynamically without restarting the server. Since you are already storing the modem information in a database you could use omshell (cli omapi tool) to dynamically add the host decl to the server before it adds to the db ensuring the two are in sync. If you use PHP for doing this I can give you some sample code. There are also Perl and Python modules that you can use as well.
Thanks for the suggestions, I'll look into omapi. I do plan on writing most of it in php. Could you pass along some sample code?
Also, any thoughts on how to correlate CPE ip to a particular modem? I've been looking through the OIDS for both modems and the CMTS and can't seem to find anything.
Thanks
EDIT:
I made the changes you indicated and DHCPD does not like them. It's balking at everything I added. The only thing it would accept was the group statement after I stripped the name
scratch that
I switched over to DHCP3 and through a combo of the man page and trial and error have a working config with your added suggestions.
Now I just need to play with the omapi stuff
What version of dhcpd are you using? I use v3.0.5-7 and I am experimenting with 4.0.0, if you are still having trouble you can email the conf offlist at jasonp <@> cablemo <.> com and I can take a stab at it for you.
In my subnets I use a pool decl to separate out the indivdual ranges, perhaps that is the problem. i.e. I would have written your cm pool like this
subnet 172.16.16.0 netmask 255.255.248.0 {
pool {
range 172.16.16.11 172.16.20.0;
allow members of "CM";
deny unknown-clients;
option routers 172.16.16.10;
}
}
Then put the other options in the CM class definition..
You could probably use option 82 and classes to do specific ips to cpe behind a specific modem i.e. something like this
class CMCustomer-023456
{
spawn with option agent.remote-id;
lease limit 1;
}
then inside your subnet create a pool and only allow members of that class
i.e.
subnet 10.0.0.0 netmask 255.255.255.0
{
pool
{
range 10.0.0.2 10.0.0.2;
allow members of "CMCustomer-023456";
}
}
I think however that it would quickly get out of hand, and there would also be issues with leases not expiring. i.e. I have device A connected to modem decide to switch to device B when device B dhcps the only lease available is A's which has not expired and so it either gets another lease from main pool or is denied until Device A's lease is available. also only hosts and leases (and classes in newer versions of dhcpd) can be manipulated by omapi so you would have to make these changes in the dhcpd.conf itself.
here is some sample php5 code
<?php
error_reporting(E_ALL);
$clientIp = $_SERVER['REMOTE_ADDR'];
/*
Omapi/Omshell info
*/
$omapi_key = "your omapi key here";
$omapi_port = "9991";
$dhcpdServer = "your server ip";
$omshellPath = "/usr/bin/omshell";
function addOmapiModem($macAddress, $group)
{
global $omapi_key;
global $dhcpdServer;
global $omapi_port;
global $omshellPath;
$dspec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("file", "/tmp/eo.txt", "a"),);
$success = array();
$success[0] = false;
$success[1] = "";
$process = proc_open($omshellPath, $dspec, $pipes);
if (is_resource($process))
{
readit($pipes);
writeit($pipes, "port $omapi_port");
readit($pipes);
writeit ($pipes, "key omapi_key \"$omapi_key\"");
readit($pipes);
writeit($pipes, "server $dhcpdServer");
readit($pipes);
writeit($pipes, "connect");
$connected = readit($pipes);
if ($connected == "obj: \n> ")
{
writeit($pipes, "new host");
readit($pipes);
writeit($pipes, "set known=1");
readit($pipes);
writeit($pipes, "set hardware-type=1");
readit($pipes);
$formatted_mac = ereg_replace(":$", "", chunk_split($macAddress, 2, ":"));
writeit($pipes, "set hardware-address=$formatted_mac");
readit($pipes);
writeit($pipes, "set group=\"$group\"");
readit($pipes);
writeit($pipes, "create");
$added = readit($pipes);
if (ereg("^obj: host", $added) || ereg("open object: already exists", $added))
{
$success[0] = true;
} else {
$success[1] = $added;
}
}
fclose($pipes[0]);
fclose($pipes[1]);
$return_value = proc_close($process);
}
return $success;
}
function readit($pipes, $end = '> ', $length = 1024)
{
stream_set_blocking($pipes[1], FALSE);
while (!feof($pipes[1]))
{
$buffer = fgets($pipes[1], $length);
$returnValue .= $buffer;
if (substr_count($buffer, $end) > 0) {
$pipes[1] = "" ;
break;
}
}
return $returnValue;
}
function writeit ($pipes, $str)
{
fwrite($pipes[0], "$str\n");
return "$str\n";
}
?>
the way you ise it is like so
<?php
$result = addOmapiModem("001122334455", "Gold");
// if successful
if ($result[0] == true)
{
echo "successful";
} else {
// if not successful do something with error message
echo $result[1];
}
?>
thanks for the code.
I'm attempting to get omapi configured on my system, but I'm having issues finding documentation. I'm specifically trying to fine how/where you set the omapi key and port.
Also, since it appears that this transaction takes place over secured channels, would it be safe to route this traffic through the internet cloud? This provisioning server is going to sit behind a firewall at a remote location. Could I just key-hole nat the provisioning server to the cloud (and lock it down in the firewall) and manage hosts with that omapi connection? Also, are changes made through omapi permanently written to the dhcpd.conf file (or somewhere else) so that if the server went down, it could pop back up without having to resync with the head end?
check out this link for setting the omapi key
http://blog.nominet.org.uk/tech/2005/12/
You can reuse keys between servers too which makes interacting with omapi via omshell easier if you have more than one location.
with the omapi key it is secure we use it over the internet without trouble a firewall rule could not hurt though.
Hosts added via omapi are actually added to the dhcp.leases file so they are imported back in during a server restart just like leases.
thanks for your help. We installed the new unit today and so far things are looking good. I'm going to dig further into this omapi stuff and I'll probably have questions later.
I have a test server set up and have been experimenting with omapi to manage hosts. It works really well, except that when the dhcp service is restarted, all dynamic host declarations are wiped from the dhcpd.leases file. Since my dhcp.conf file restricts handing out IPs only to known hosts, a server reboot will kick everybody offline. Any ideas about how to deal with this?
make sure known is set to something other than 0, Also make sure that you let dhcpd name your hosts, I recall having a problem with hosts that i had custom named. i.e. don't specify a name via omshell/omapi.
It is also very important that you do not hand edit the dhcpd.leases file,
one stinking line....
I was naming the host. After I pulled that out of there, it worked fine. I've literally spent the entire day reading every document on omi and dhcp that google could find, and saw that mentioned nowhere.
Thanks a ton.
No problem,
Problem is very few people use omapi/omshell to work with dhcpd, which is a shame because it is far better than the alternative.
let me know if you still have problems.
Jason
are you setting known=1 in your omapi host declarations?
i.e.
omshell>new host
obj
omshell>set hardware-address=00:11:22:33:44:55
omshell>set hardware-type=1
omshell>set known=1
omshell>set group="Gold"
omshell>create
I hadn't been, but even without it modems were fully registering.
I just added that option, added a few hosts through omshell, let the modems come up, then reset the dhcp server. When I checked the dhcpd.leases file, the only thing in there are the leases (the host declarations have been cleared), and the modems (after a restart) are not being issued an IP.
Hi,
could you please post an example also for the delOmapiModem? Adding works great, but I would need some help with deleting via PHP.
TIA
Greetings to all users,
May I ask someone of you how you add the configurationfile to any host through omapi.
I managed to add a host by using omapi and even the group but I cannot add the specific filename to the cable modem.
for ex. filename "0012aabbcc34.cfg";.
As I want to have every customer with a specific config file like cmmac.cfg
Solved it by adding this to the dhcpd.conf file :)
-> filename =
concat(
suffix(concat("0",binary-to-ascii(16,8,"",substring(hardware,1,1))),2),
suffix(concat("0",binary-to-ascii(16,8,"",substring(hardware,2,1))),2),
suffix(concat("0",binary-to-ascii(16,8,"",substring(hardware,3,1))),2),
suffix(concat("0",binary-to-ascii(16,8,"",substring(hardware,4,1))),2),
suffix(concat("0",binary-to-ascii(16,8,"",substring(hardware,5,1))),2),
suffix(concat("0",binary-to-ascii(16,8,"",substring(hardware,6,1))),2),
".cfg");