Centos5.5 32位。
dhclient-3.0.5-18.el5
dhcp-3.0.5-18.el5
dhcp-devel-3.0.5-18.el5
1)下面配置的dhcp是A类网址,终端是某个地市的所有机顶盒。
2)本机配置了dns,地址为:10.1.0.17。如果没有配的话,dhcp配置文件中可删除。
3)由于是用来给机顶盒分配ip地址,因此配置了option60。
如果是终端是电脑的话,则可以删除相关选项。比如最后一步的测试,我们需要拿笔记本来测试,因此删除:class "STB" 以及option vendor-class-identifier和allow members of "STB"选项,以便允许给笔记本分配ip地址。
以下是配置文件:
vi /etc/dhcpd.conf
########################################
#
# DHCP Server Configuration file.
# see /usr/share/doc/dhcp*/dhcpd.conf.sample
#
#
# DHCP Server Configuration file.
# see /usr/share/doc/dhcp*/dhcpd.conf.sample
#
authoritative;
ddns-update-style none;
ignore client-updates;
option domain-name-servers 10.1.0.17;
authoriatative;
default-lease-time 25600;
max-lease-time 86400;
class "STB" {
match if substring (option vendor-class-identifier, 0, 14) ="DTV-CHINA";
}
subnet 10.140.128.0 netmask 255.255.224.0 {
pool {
range 10.140.128.6 10.140.159.250;
option routers 10.140.128.1;
option subnet-mask 255.255.224.0;
option vendor-class-identifier "DTV-CHINA";
allow members of "STB";
}
}
subnet 10.140.160.0 netmask 255.255.224.0 {
pool {
range 10.140.160.6 10.140.191.250;
option routers 10.140.160.1;
option subnet-mask 255.255.224.0;
option vendor-class-identifier "DTV-CHINA";
allow members of "STB";
}
}
#下面还有很多的subnet子网就不列举了。
subnet 10.140.192.0 netmask 255.255.224.0 {
pool {
... ...
}
}
vi/etc/sysconfig/network-scripts/ifcfg-eth1
########################################
# Intel Corporation 82574L Gigabit NetworkConnection
DEVICE=eth1
BOOTPROTO=dhcp
HWADDR=C8:60:00:EA:45:7C
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
IPV6INIT=no
PEERDNS=yes
########################################
如果需要实现以下的配置,则需要在交换机中配置vlan,与之对应。
如果是做最后一步测试的话,则可以简单化。比如我们要压力测试下10.140.128网段的,则在以上配置文件中仅留下subnet 10.140.128.0这一项,并且服务器网卡可以配置为10.140.128.5 进行测试。
另外,最后一行为在本脚本中启动dhcpd服务的命令,而不要将服务配置为自动启动。原因是服务器启动时,centos中的服务是优先于下面的脚本先启动。如果脚本上的那些ip没有配置上的话,dhcpd启动会失败。
vi/etc/rc.d/rc.local
#######################################
#!/bin/sh
#
# This scriptwill be executed *after* all the other init scripts.
# You can putyour own initialization stuff in here if you don't
# want to do thefull Sys V style init stuff.
touch/var/lock/subsys/local
vconfig add eth1301
vconfig add eth1311
ifconfig eth10.0.0.0 up
ifconfig eth1.301 10.1.0.17 netmask 255.255.255.0 up #dns安装在本机
ifconfig eth1.311 10.140.128.5 netmask 255.255.224.0 up
ifconfig eth1.312 10.140.160.5 netmask 255.255.224.0 up
route add -net0.0.0.0 netmask 0.0.0.0 gw 10.1.0.254
/etc/init.d/dhcpd start
在启动服务前,可以将删除/var/lib/dhcpd/dhcpd.leases*,以便能够准确的查看dhcpd.leases文件的变化。
有时候,地址分配会出现一些问题,可以使用删除arp的命令来清空缓存:
1,删除某一个ip地址缓存:
arp -d 10.140.128.254
2,删除某一段ip地址缓存;
for ((i=1;i<=255;i++));do arp -d 10.140.128."$i" &>/dev/null;done
3,删除所有的ip地址缓存:
ip n f dev eth1 或 ip neigh flush dev eth1
255.255.224.0 转换成二进制为 1111 1111.1111 1111.1110 0000.0000 0000 即19/0(19个1)
前面的1表示的是子网,后面的0表示的是每个子网可带的ip地址。
ip地址个数大概为:2的5次方×255 = 32×255。因此dhcp中的range,每一段都是32×255-1个ip地址
range 10.140.128.1 10.140.159.255;
range 10.140.160.1 10.140.191.255;
range 10.140.192.1 10.140.223.255;
range 10.140.224.1 10.140.255.255;
而如果地址不够用的话,则可以将上面的地址池进行扩大,可以将子网改成18/0,即:
1111 1111.11111111.1100 0000.0000 0000,即255.255.192.0。此时,range每一段为64×255-1个ip地址:
range 10.140.128.110.140.191.255;
range 10.140.192.110.140.255.255;
如果配置要扩大的话,可能还需要修改核心交换机的配置。
另外,A类地址的0和255居然也能被分配到,比如子网是255.255.224.0,可以在笔记本上配置 10.140.129.0或者是10.140.129.255,居然也能ping通dhcp服务器。这应该是跟c类地址不一样的地方吧。
参考资料:
http://www.nominum.com/support/measurement-tools/
http://www.doc88.com/p-330776746344.html
http://wenku.baidu.com/view/7420d04e767f5acfa1c7cd32.html
由于dhcpd服务器配置了option60,只能给机顶盒分配ip地址。因此,我们不能直接进行测试。
为了测试方便,我们对配置文件进行了修改(以下红色表示dhcp服务器,蓝色表示测试客户端),将服务器的ip地址改成 10.140.128.5 :
[root@adp-ds ~]# more /etc/dhcpd.conf
#
# DHCP Server Configuration file.
# see/usr/share/doc/dhcp*/dhcpd.conf.sample
#
authoritative;
ddns-update-style none;
ignore client-updates;
option domain-name-servers 10.1.0.17;
authoriatative;
default-lease-time 25600;
max-lease-time 86400;
subnet 10.140.128.0 netmask 255.255.224.0 {
pool{
range 10.140.128.6 10.140.156.250;
option routers 10.140.128.1;
option subnet-mask 255.255.224.0;
}
}
重启下dhcpd:
# service dhcpd restart
准备一台测试机器,操作系统可以是centos5.5 32bit。将测试机与dhcpd服务器通过网线连接起来,并确认能够进行通讯,这里我们将测试机器连接到dhcpd服务器的10.140.128网段,测试客户端的ip地址设置为10.140.128.4。下载dhcperf-1.0.1.0-1-rhel-4-i386.tar,解压出dhcperf-1.0.1.0-1.i386.rpm进行安装:
#tar -zxvf dhcperf-1.0.1.0-1-rhel-4-i386.tar
cd dhcperf-1.0.1.0-1-rhel-4-i386
rpm -ivh dhcperf-1.0.1.0-1-rhel-4-i386.rpm
cd/usr/local/nom/bin/
./dhcperf --help
在dhcpd服务器再开启3个tty,用来监测两个文件(地址分配文件、系统日志文件)和系统资源使用情况:
# tail -f /var/lib/dhcpd/dhcpd.leases
# tail -f /var/log/message
# top
开始测试(第一条命令是只获取一个ip地址,看看是否可以获取到):
# ./dhcperf --server 10.140.128.5 --one-discover
Sending DHCPDISCOVER.
Received DHCPOFFER of 10.140.155.255.
Sending DHCPREQUEST for 10.140.155.255.
Received DHCPACK of 10.140.155.255.
Acquired address: 10.140.155.255
一个ip地址获取ip地址正常,继续测试:
./dhcperf --server 10.140.128.5 --discover --clients 2
此时,ip地址获取也正常,但过一段时间后,dhcpd服务器上系统日志有大量的错误信息:
Sep 6 10:27:13 adp-ds kernel: Neighbour tableoverflow.
Sep 6 10:27:13 adp-ds kernel: printk: 364messages suppressed.
到google上搜索“dhcpd Neighbour table”,有个资料 http://www.serveradminblog.com/2011/02/neighbour-table-overflow-sysctl-conf-tunning/中说的比较详细。对系统参数进行修改:
#vi /etc/sysctl.conf
net.ipv4.neigh.default.gc_thresh1= 4096
net.ipv4.neigh.default.gc_thresh2 = 8192
net.ipv4.neigh.default.gc_thresh3 = 8192
net.ipv4.neigh.default.base_reachable_time = 86400
net.ipv4.neigh.default.gc_stale_time = 86400
#sysctl -p
重新启动dhcpd后再次在测试客户端执行:
./dhcperf --server 10.140.128.5 --discover --clients 2
就不再出现上面的问题了。
执行完毕后,使用perl的脚本对/var/lib/dhcpd/dhcpd.leases 进行排序。即根据分配的地址进行排序处理,然后查看排序后的文件的ip地址分配情况。
我将perl安装到我工作笔记的D:/Perl64/下,将/var/lib/dhcpd/dhcpd.leases拷贝到D:/Perl64/。然后执行下面的perl脚本。如果是在其他的目录,或者是linux环境下,可以修改下这个脚本的4个文件的路径即可,以下共享下perl脚本,写的不好,请多多指教:
#! /usr/bin/perl
use 5.010;
use Data::Dumper;
use strict;
use warnings;
if(open(MYFILE,"D:/Perl64/dhcpd.leases")==0)
{
die ("Can't open the file! \n");
}
my $key;
my $value;
my %content;
######################################################################################
### 本 while 循环从原始文件中读取数据,存入到hash结构中。对ip地址进行了处理,处理后的
### 格式为xxx.xxx.xxx.xxx,以方便字符排序。
### hash 结构的 key 为 ip 地址(最后面还有个回车符);value的格式为:
### starts 5 2013/09/06 03:18:52;
### ends 5 2013/09/06 10:25:32;
### binding state active;
### next binding state free;
### hardware ethernet 00:00:00:00:00:01;
### uid "dhcperf_1";
### }
######################################################################################
while(<MYFILE>)
{
if (/^lease /) {
$key = $_;
$value = undef;
}
else {
$value = $value.$_;
}
if (/^}/) {
### 对key进行处理将“lease 10.140.128.10 {”格式化成“010.140.128.010” ###
$key =~ s/lease //; # 去掉“lease”
$key =~ s/ {//; # 去掉“ {”
### 格式化成 xxx.xxx.xxx.xxx
$key=~/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
$key =sprintf("%03d",$1).".".sprintf("%03d",$2)."."
.sprintf("%03d",$3).".".sprintf("%03d",$4)."\n";
####################
### 存入到hash结构中;
$content{$key} = $value ;
}
}
close(MYFILE);
######################################################################################
######################################################################################
### 将排序后的信息先写入两个文件,并将ip地址存入另外一个hash表。
### 第一个文件dhcpd2.leases 为排序后的带有原始mac地址等的信息;
### 第二个文件dhcpd3.leases 为排序后的纯IP地址信息;每个ip地址为一行,从小到大排序
### 而另外存入的hash表%ipdata的信息,其key为ip地址的网段,如010.140.129;
### 而value为ip地址的数组,从最小到最大排序,如 010.140.129.000一直到010.140.129.255
######################################################################################
if(open(WriteFILE1," > D:/Perl64/dhcpd2.leases")==0) {
die ("Can't open the file! \n");
}
if(open(WriteFILE2," > D:/Perl64/dhcpd3.leases")==0) {
die ("Can't open the file! \n");
}
my %ipdata;
my$ipkey="";
my @ipvalue = ();
foreach $key(sortkeys %content) {
print WriteFILE1"$key$content{$key}";
print WriteFILE2 "$key";
#可以将这些ip地址存储到一个二维数组(8×256)中,然后写入文件比较好阅读
if (($ipkey ne substr $key, 0, 11) &&(scalar @ipvalue != 0))
{
#say Dumper \@ipvalue;
$ipdata{$ipkey} = [@ipvalue];
@ipvalue = ();
}
$ipkey = substr $key, 0, 11;
$ipvalue[(substr $key, 12, 3)] = substr $key,0, 15;
#say $ipvalue[$i];
}
$ipdata{$ipkey} =[@ipvalue];
close(WriteFILE1);
close(WriteFILE2);
######################################################################################
######################################################################################
### 将 %ipdata 这个hash表的key排序后存入到数组 @networksection
######################################################################################
my @networksection =();
foreach $key(sortkeys %ipdata) {
push @networksection, $key;
}
#say Dumper\@networksection;
######################################################################################
######################################################################################
### 开始写二维数组文件,以便更好的阅读
### 该文件共 8 列,每 256 行为一个块,然后空一行,再继续256行。每一列第一行有头部,表示某个
### 子网。类似于:
###-------------------------------------------------------
### 010.140.128. 010.140.129. 010.140.135.
###-------------------------------------------------------
### 010.140.128.000010.140.129.000 ... ... 010.140.135.000
### 010.140.128.001010.140.129.001 ... ... 010.140.135.001
### ... ... ... ...
### 010.140.128.255010.140.129.255 ... ... 010.140.135.255
### (空一行)
###-------------------------------------------------------
### 010.140.136. 010.140.137. 010.140.143.
###-------------------------------------------------------
### 010.140.136.000010.140.137.000 ... ... 010.140.143.000
### ... ... ... ...
### ... ... ... ...
### 010.140.136.255010.140.137.255 ... ... 010.140.143.255
### (空一行)
### ... ... ... ...
### ... ... ... ...
###
### 如果IP地址不存在,则以空格代替。这样,看起来就方便多了
######################################################################################
my $step =8; # 即 8 列
if(open(WriteFILE3," > D:/Perl64/dhcpd4.leases")==0)
{
die ("Can't open the file! \n");
}
for (my $j=0;$j<@networksection/$step; $j++)
{
## 一行满 8 列的处理(有可能最后一个块不满 8列,则在 else 中进行处理)
if (@networksection >= ($j+1) * $step)
{
for (my $x=-3; $x<256; $x++)
{
my $string = "";
#$string = $j. " ";
for (my $k=0; $k<$step; $k++)
{
my $temp = "";
if ($x > -1) {
$temp =${$ipdata{$networksection[$j*$step+$k]}}[$x] ;
}
elsif (($x == -3) || ($x == -1)) {
$temp = "---------------";
}
elsif ($x == -2){
$temp = $networksection[$j*$step+$k];
$temp = $temp . ". ";
}
if (! defined $temp)
{
# 如果ip地址不存在,则使用相同长度的空格代替
$temp=" ";
}
$string = $string . $temp . " "
}
$string =~ s/ +$//; # 截掉最后的空格
#say $string;
print WriteFILE3 "$string\n";
}
#say "";
print WriteFILE3 "\n";
}
else # 最后一块不满 8列情况的处理
{
for (my $x=-3; $x<256; $x++)
{
my $string = "";
#$string = $j. " ";
for (my $k=0; $k<(@networksection - $j* $step); $k++)
{
my $temp = "";
if ($x > -1) {
$temp = ${$ipdata{$networksection[$j*$step+$k]}}[$x];
}
elsif (($x == -3) || ($x == -1)) {
$temp = "---------------";
}
elsif ($x == -2){
$temp = $networksection[$j*$step+$k];
$temp = $temp . ". ";
}
if (! defined $temp)
{
$temp=" ";
}
$string = $string . $temp . " "
}
$string=~s/ +$//;
#say $string;
print WriteFILE3 "$string\n";
}
}
}
close(WriteFILE3);
使用以上perl脚本,对正式系统上的的dhcpd.leases进行处理效果很显著,对已经分配的ip地址查看非常方便。不过由于正式系统正在运营,因此,不好进行压力测试。
不过发现一个奇怪的现象,正式系统中,centos5.5下的dhcp服务,分配出去的ip地址是从最后开始分配的。而且呈现三角的形状。如,10.140.128.6 10.140.156.250 网段,分配出去的地址为:
搞不清楚系统为何怎么分配。按照这个规律,从132到159共有28层,第一层为2个ip地址,理论上共有ip地址为(1+28)×28=812个,如果是这样的话,生产环境ip地址肯定不够用。正式系统的系统日志也有说地址不够用的异常,待下次出现用户投诉我再研究。
不过,在以上的测试系统中,如果人为的搞几台客户端进行验证,ip地址确实是从后面进行分配了。网上查了下有关的资料,也证实了这一点。而在测试系统的压力测试时,发现所有的地址都已被分配出去。因此,我想地址分配应该是正常的。正式系统需要继续观察是否分配了以上现象中提到的ip地址之外的地址。
http://www.serveradminblog.com/2011/02/neighbour-table-overflow-sysctl-conf-tunning/
If you have a big network with the hundreds of hosts youcan expect “Neighbour table overflow” error which occurs in large networks whenthere are two many ARP requests which the server is not able to reply. Forexample you’re using server as a DHCP server, cable modems provisioning, etc.
Nov 10 03:18:17 myhost Neighbour table overflow. Nov 10 03:18:23 myhost printk: 12 messages suppressed. |
Of curse, this can be fixed. The solution is to increasethe threshhold values in /etc/sysctl.conf. Add following lines to/etc/sysctl.conf (RH based distros)
net.ipv4.neigh.default.gc_thresh1 = 4096
net.ipv4.neigh.default.gc_thresh2 = 8192
net.ipv4.neigh.default.gc_thresh3 = 8192
net.ipv4.neigh.default.base_reachable_time = 86400
net.ipv4.neigh.default.gc_stale_time = 86400
Save sysctl.conf and execsysctl -p. You can also reboot but it isn’t necessary.
The default sysctl.conf file
net.ipv4.ip_forward=0 kernel.shmmax=68719476736 kernel.msgmax=65536 kernel.msgmnb=65536 net.ipv4.conf.default.rp_filter=1 kernel.sysrq=0 net.ipv4.conf.default.accept_source_route=0 kernel.shmall=4294967296 kernel.core_uses_pid=1 net.ipv4.tcp_syncookies=1 |
“Tuned” systctl.conf
net.ipv4.ip_forward=0 kernel.shmmax=4294967295 kernel.msgmax=65536 kernel.msgmnb=65536 net.ipv4.conf.default.rp_filter=1 kernel.sysrq=0 net.ipv4.conf.default.accept_source_route=0 kernel.shmall=268435456 kernel.core_uses_pid=1 net.ipv4.tcp_syncookies=1 net.ipv4.neigh.default.gc_thresh1 = 4096 net.ipv4.neigh.default.gc_thresh2 = 8192 net.ipv4.neigh.default.gc_thresh3 = 8192 net.ipv4.neigh.default.base_reachable_time = 86400 net.ipv4.neigh.default.gc_stale_time = 86400 |
Explanation…
The neighbour table is generally known as ARP table andthe default value for gc_thresh1 is 128 (Adjust where the gc will leave arptable alone)
[root@myServer ~]# cat /proc/sys/net/ipv4/neigh/default/gc_thresh1 128 |
which is not enough for large networks (more than 128hosts). Thats why we need to tune this value. The gc_thresh2 is a soft limit(Tell the gc when to become aggressive with arp table cleaning.) and thegc_thresh3 is a hard limit (Don’t allow the arp table to become bigger thanthis).
To enlarge the ARP cache table on the live system run:
# sysctl -w net.ipv4.neigh.default.gc_thresh3=8192 # sysctl -w net.ipv4.neigh.default.gc_thresh2=8192 # sysctl -w net.ipv4.neigh.default.gc_thresh1=4096 |
It is possible that after distro update your systctl.confwill be replaced with the default values. Check this file periodically..