关于DHCP协议和dhcpd配置文件的讲解

在了解了DHCP协议的基础内容后,我们来对它的dhcpd配置文件的相关内容进行一下了解。首先我们来了解一下这方面的基础概念。然后再对它的应用进行一下分析。

名称

dhcpd.conf - dhcpd配置文件

描述

dhcpd.conf 文件包括ISC DHCP的dhcpd的配置信息。

dhcpd.conf文件是一个普通格式的ASCII码文档, 它由内置的递归解析器解释。

dhcpd.文件可能会包含许多额外的tab和空格、空行,它们的目的是让文件更容易阅读。 其中的关键字对大小写不敏感。注释语句可以放在任何位置(除了引号中)注释语句用# 开头,这一行结束时注释语句自然结束。

文件包括一组语句,语句在一对大括号中,包含参数和声明。

参数语句说明如何做一件事(例如,租期是多长时间),或者是否做一件事情。 (例如, dhcpd 是否为未知客户提供地址),或者给客户提供哪种参数(例如,使用网关220.177.244.7)。

声明用来描述网络的拓扑结构、网络上的客户,提供可以为客户端分配的地址,或者对某个客户端组应用组(group)参数。在任何组参数中,所有的这些组参数必须比使用这些组参数的语句先出现。

网络声明包含多子网的网络(有些地方译为:超网,但超网太难理解了,这里叫“多子网网络”)和子网的拓扑声明。对于子网的客户端被动态分配地址,子网声明中必须有一个range声明语句。对于静态分配的地址,或者是已知客户的安装,每个客户端都必须使用一个host声明语句。如果一个参数应用到一组声明中,这些声明并不只与某个子网相关,可以定义一个“组参数”。

对每一个要服务的子网,每个dhcp协议的服务器连接的子网,都必须有一个子网声明,用来告诉dhcpd如何处理那个子网上的地址。即使一个子网不需要分配任何地址,也需要一个子网声明。

一些物理网络上不只有一个IP子网存在,例如,如果一个网络需要一个8位的子网,但是当业务发展使总的节点数超过了254台,就需要增加一个8位的子网。这时,就增加了一个新的物理网络,这种情况下,2个网络的子网声明必须包含在一个“多子网网络声明(超级作用域)”中。

有些网络的客户端不只有一个子网,可能会为同一子网中一些客户端分配的一些参数与其它的客户端不同。这样的用户可以使用host语句来定义,一些参数也可以定义在“组参数”语句中,它被这些客户端共同调用。对于需要根据不同情况获得不同地址的客户端,可能会使用“类声明(class declarations)”和“条件声明(conditional declarations)”语句,这样可以根据客户端发送的信息来决定分配给客户端的参数。

当一个客户端启动时,服务器先查看是否有匹配客户端的host语句,如果没有,再看是否有匹配的“类声明(class declarations)”语句,接着查看是否有“池pool”匹配,“子网subnet”匹配和“多子网网络(超级作用域)shared-net-work”匹配。(根据这些匹配,)将符合这个客户端的参数提供给它。每种参数都不会被分析第2次,如果它们出现了2次或2次以上,那么会使用那个最精确出现的地方。

dhcpd首先查找客户端是否有包含固定IP地址的host语句,这个地址要在客户端启动的那个子网中,或者“多子网网络”中,如果没有对应的host语句匹配,那就查找非固定地址的声明。

例如:

一个典型的dhcpd.conf 文件将会象下面这样:

 
  
  1. global parameters...  
  2. subnet 204.254.239.0 netmask 255.255.255.224 {  
  3. subnet-specific parameters...  
  4. range 204.254.239.10 204.254.239.30;  
  5. }  
  6. subnet 204.254.239.32 netmask 255.255.255.224 {  
  7. subnet-specific parameters...  
  8. range 204.254.239.42 204.254.239.62;  
  9. }  
  10. subnet 204.254.239.64 netmask 255.255.255.224 {  
  11. subnet-specific parameters...  
  12. range 204.254.239.74 204.254.239.94;  
  13. }  
  14. group {  
  15. group-specific parameters...  
  16. host zappo.test.isc.org {  
  17. host-specific parameters...  
  18. }  
  19. host beppo.test.isc.org {  
  20. host-specific parameters...  
  21. }  
  22. host harpo.test.isc.org {  
  23. host-specific parameters...  
  24. }  

图 1

注意文件的开始,它是全局参数放置的地方,可能会是:

组织的域名,DNS服务器的地址(如果这个服务器对整个网络都是一样的)和其它一些。比如:

 
  
  1. option domain-name "isc.org";  
  2. option domain-name-servers ns1.isc.org, ns2.isc.org; 

图 2

如图2中所示,可以使用DNS服务器的名称而不使用它的IP地址,如果指定不只一个DNS服务器地址,那么只要有可能,所有地址都会提供给客户端。

每个子网都要指明的最可能必须的参数是router,如图1所示。因此对于第一个子网,它就应该是这个样子的

 
  
  1. option routers 204.254.239.1; 

注意这里的地址是数字形式的,如果每个网关都有域名,这就不是必须的,使用域名也是合法的。然而,很多情况下,多个网关只有一个域名,这样就不能使用域名了。

在图1中,有一个group 语句,它为一组host语句zappo,beppo和harpo提供了通用的参数。如你所见,这些主机都在test.isc.org这个域里,这样它在“组参数”中指明就会覆盖全局设置的参数:

 
  
  1. option domain-name "test.isc.org"; 

而且,指明它们的域,可能用在测试机器中,如果我们要测试DHCP协议的租约机制,可以在这里设置比默认值更短的租约:

 
  
  1. max-lease-time 120;  
  2. default-lease-time 120; 

你可能注意到有些参数以option 关键字开头,有些不。以option 关键字开头的语句对应实际的DHCP选项,不以option关键字开头的选项控制服务端(例如,租期) 或客户端的选项不在DHCP协议中(例如,服务器名或文件名)

在图1中,每个host 都有指定的参数,它会包含象hostname选项,要上传的文件名(filename 参数),还有要上传的服务器的地址(next-server 参数)。通常,任何参数都可以在任何可以出现的地方出现,并且按照参数出现位置确定应用范围。

假设你的环境中有许多没有CD的X终端,这些终端有不同的型号,你想为每种型号确定一个启动文件,一种方法是给每个服务器和组都使用host语句:

 
  
  1. group {  
  2. filename "Xncd19r";  
  3. next-server ncd-booter;  
  4. host ncd1 { hardware ethernet 0:c0:c3:49:2b:57; }  
  5. host ncd4 { hardware ethernet 0:c0:c3:80:fc:32; }  
  6. host ncd8 { hardware ethernet 0:c0:c3:22:46:81; }  
  7. }  
  8. group {  
  9. filename "Xncd19c";  
  10. next-server ncd-booter;  
  11. host ncd2 { hardware ethernet 0:c0:c3:88:2d:81; }  
  12. host ncd3 { hardware ethernet 0:c0:c3:00:14:11; }  
  13. }  
  14. group {  
  15. filename "XncdHMX";  
  16. next-server ncd-booter;  
  17. host ncd1 { hardware ethernet 0:c0:c3:11:90:23; }  
  18. host ncd4 { hardware ethernet 0:c0:c3:91:a7:8; }  
  19. host ncd8 { hardware ethernet 0:c0:c3:cc:a:8f; }  

地址池

“池”语句(pool)用来定义一个地址池,即便是在同一个网段或者子网,也可以定义几个池,系统将通过“池”来区分它们。例如,你可能想提供一大段地址分配给DHCP客户端时同时提供很短的租约的一小段地址,用来给未知客户。如果有防火墙,你可能会安排一段地址池能上网,另一个地址池不能上网,这可以鼓励用户注册到DHCP协议的系统中来,也就需要建立两个地址池:

 
  
  1. subnet 10.0.0.0 netmask 255.255.255.0 {  
  2. option routers 10.0.0.254;  
  3. # Unknown clients get this pool.  
  4. pool {  
  5. option domain-name-servers bogus.example.com;  
  6. max-lease-time 300;  
  7. range 10.0.0.200 10.0.0.253;  
  8. allow unknown-clients;  
  9. }  
  10. # Known clients get this pool.  
  11. pool {  
  12. option domain-name-servers ns1.example.com, ns2.example.com;  
  13. max-lease-time 28800;  
  14. range 10.0.0.5 10.0.0.199;  
  15. deny unknown-clients;  
  16. }  

上面这个例子中,已知客户和未知客户在相同的子网中,也可能将已知和未知客户分配在不同的子网中,或者在“多子网层次(超级作用域)”,这样地址池的范围可能跨越不同的子网。正如前面的例子,地址池可以允许或拒绝一个控制用户存取的组,这个组名前面要有allow或 deny 关键字。

如果一个池有一个允许列表,只有匹配的客户端才可以获得地址池的地址,如果这个池有一个拒绝列表,只有不匹配的客户端才可以获得池中的地址,如果同时存在允许和拒绝列表,那么只有在允许列表并且不在拒绝列表中的客户端才可以获得池中的地址。

动态地址分配

地址分配实际只在客户端在初始状态并且发送一个 DHCPDISCOVER信息时完成。如果客户端认为它有一个有效的租约并且发送了一个DHCPREQUEST信息来初始化或者更新租约,服务器就只有3个选择:(1)它可以忽略DHCPREQUEST信息,并且返回一个DHCPNAK 信息来告诉客户端,要求客户端停止使用这个地址,(2)或者发送一个DHCPACK信息,告诉客户端继续再使用这个地址一段时间,如果服务器找到客户端要求的地址,并且这个地址对于这个客户也是可用的,服务器会发送一个DHCPACK信息,如果这个地址已经不能用了,客户端就不能使用它,此时服务器将会发送一个DHCPNAK信息,(3)如果服务器不知道这个地址,它会先保持沉默,除非这个地址对于客户端依附的地址段是不正确的,这种情况下服务器会发送一个DHCPNAK,即便它完全不知道这个地址。

如果有一个host语句定义了客户端,同时host语句中包含了固定地址(fixed-address),这个IP地址对于客户端实际连接的网段也是合法的,此时DHCP协议的服务器不动态分配地址,而是发送host语句指明的地址。如果此时用户发送了DHCPREQUEST信息来获得其它地址,服务器会回应一个DHCPNAK信息,来拒绝为用户分配其它地址。

当一个DHCP服务器为客户端分配一个新的地址时(记住,这只发生在客户端发送DHCPDISCOVER信息时),它首先查找lease文件,看客户机是否存在一个有效的地址租约,或者此客户机原来是否有一个地址(这个地址已经过期),如果有,服务器就会检查那个地址,看客户端是否被允许使用这个地址,如果客户端已经不被允许使用这个地址(通常是客户机从另外一个子网登录了,或者此地址被其它客户端占用),并且服务器lease文件中显示原来的租约还存在,服务器就释放这个租约,事实上,此时是客户端发送的DHCPDISCOVER信息,它已经证明客户端实际并没有使用这个租约。如果没有找到存在的租约,或者客户端被强迫接收一个已经存在的租约,那么服务器就会查找客户端所在网段的地址池,找一个允许客户端使用而又没有使用的地址,它会按顺序遍历每个地址池(所有地址池外的“范围”range定义语句都组成一个没有允许列表的单独的池)。如果地址池的允许列表允许客户端得到一个池中的地址,这个地址池会被检查是否有可用的地址,如果有,客户端将会得到这个地址;否则,会检查下一个地址池。如果一直都没有找到可用的地址,服务器就不发送回应。如果找到一个地址,这个地址以前从未被任何客户端使用过,这个地址将立即分配给这个客户,如果这个地址曾经分配给另一个客户端,服务器会尝试查找一个从未分配的地址给客户端。

DHCP服务器使用哈希表(hash table)来产生一组可用的IP地址,这意味着地址不以任何特定的顺序存放,这样也就不能预测DHCP服务器下一个要分配的地址。前一个版本的ISC DHCP服务器使用降序来分配地址,现在不是了,并且在这个版本里也没有办法配置服务器分发地址的顺序 (ISC DHCP 3)。

防止IP地址冲突

DHCP服务器在分配IP地址前检查它们是否被使用来防止冲突。它通过向准备分配的IP地址发送ICMP Echo请求信息来完成,如果1秒内没有接收到ICMP Echo reply信息,就假定这个地址是可用的。这只对在range语句中指明的租约,并且租约被DHCP服务器认为可用时有效。例如,DHCP服务器或者它的热备机没有列出这个租约在使用中。如果收到ICMP Echo回应,DHCP服务器会假定出现了配置错误――IP地址被网络上的主机使用了,然后它标记这个地址为“废弃地址”,不再把它分配给客户端。如果DHCP协议的客户端试图得到一个地址,但是却没有可用的地址,服务器会(随机)标记一个“废弃地址”为“可用”,然后向这个地址发送同样的ICMP Echo 请求,如果没有得到 ICMP Echo reply回应,这个地址就会分配给这个客户。

如果要收回的第一个IP地址是可用的,DHCP服务器不会去循环使用“废弃地址”。而且,当下一个客户的DHCPDISCOVER信息到达时,它会用相同的方法开始一个新的分配,并且尝试分配一个新的IP地址。

你可能感兴趣的:(网络协议)