www.hj8828.com 2

www.hj8828.comLinux DHCP服务器的配置

DHCP概述

DHCP概述

一、选拔DHCP的要求性

在TCP/IP互联网上,每台职业站要能存取网络上的能源在此之前,都必须实行基本的互连网布置,一些首要参数诸如IP地址,子网掩码,缺省网关,DNS等必备,还大概须求部至极加的消息如IP管理战术之类。对于贰个稍稍大点的网络来讲,互连网的管制和护卫的职分是一对一劳碌的。1台Computer从3个子网转移到另一个子网,将在重新对系统进行配备。对于一般档期的顺序的专门的学业站用户是无法加之他们计划自个儿的工作站网络的权力,而且也尚无那些供给。假如二个尚无对应技术水平的用户由于好奇或想学习一下的目标错误地更换了工作站的互联网布局,变成网络故障,后果肯定。因而,须求有一种机制来让TCP/IP的布置和治本从用户端调换成互联网管理端,达成IP的集中式管理。消除方案便是用DHCP。

二、DHCP的要紧成效

DHCP的齐全都以动态主机配置协议(Dynamic Host Configuration
Protocol),由IETF(Internet
互连网程序猿任务小组)设计,详尽的情商内容在帕杰罗FC文书档案rfc213一和rfc1541里。目标正是为着缓和TCP/IP网络的规划、管理和掩护的承担,化解IP地址空间缺少难点。运转DHCP的服务器把TCP/IP网络设置聚集起来,动态管理专门的学业站IP地址的配备,用DHCP租约和预置的IP地址相挂钩,DHCP租约提供了自动在TCP/IP网络上有惊无险地分配和租用IP地址的体制,落成IP地址的聚集式管理,基本上无需互连网管理人士的人工干预。而且,DHCP自个儿被规划成BOOTP(自举重协会议)的扩展,协助须要网络布局音讯的无盘职业站,对急需一定IP的系统也提供了对应帮忙。

BOOTP协议 / BOOTP Protocol


目录

  1. 骨干理论
  2. BOOTP 与
    DHCP
  3. 通讯流程
  4. 数码报文格式 
  5. 报文加解码完毕

一. 着力理论 / Basic
西奥ry

BOOTP(Bootstrap
Protocol)是壹种指点协议,基于RAV四FC95一协商,基于UDP协议,也称之为自举重协会议,是DHCP协议的前身。BOOTP用于无盘工作站(类似网吧无盘结构)的局域网中,能够让无盘专门的学问站从一个着力服务器上获得IP地址。通过BOOTP协议可感觉局域网中的无盘工作站分配动态IP地址,那样就无需管理员去为各样用户去设置静态IP地址。

BOOTP使用UDP报文字传递输,并行使保留端口号6柒(BOOTP服务器,客户端应用此端口作为指标端口发送请求,平常是广播)和6八(BOOTP客户端,服务器使用此端口作为靶子端口发送应答)职业。使用BOOTP协议的时候,一般包蕴Bootstrap
Protocol Server(自举协议服务端)和Bootstrap Protocol
Client(自举协议客户端)两有的。

2. BOOTP 与 DHCP /
BOOTP and DHCP

BOOTP协议(BOOTstrap
Protocol):
指导程序协商,是一种C/S协议,制服了RARP协议的七个缺陷,具体表现为:(一)BOOTP协议是一个C/S程序,BOOTP服务器能够放在Internet的别的地方;(二)BOOT协议除了回到IP地址外,还提供任何布置音讯(如子网掩码等),那几个音讯能够记录在BOOTP报文的选项部分。可是BOOTP协议的瑕疵也很明朗:BOOTP协议是八个静态配置协议。也正是说当客户请求自身的IP地址时,BOOTP服务器就会探究一张(MAC–>IP)的映射表,这种映射关系必须是开始的一段时期设定好的。约等于说:BOOTP协议中,MAC地址和IP地址之间的绑定关系是静态的,是定点存放在一张表中,除非管理员改造那张表。所未来来就建议了现行反革命熟练的DHCP协议。

DHCP协议(Dynamic
Host Configuration
Protocal):动态主机配置协议。同BOOTP协议一样,DHCP协议也是依据C/S格局的,DHCP是BOOTP的后人,并且能够合营BOOTP。DHCP不仅仅能够管理静态配置(此时同样BOOTP协议),而且能够管理动态配置。也便是说,在客户在查找其和谐的IP地址时,DHCP服务器中(MAC–>IP)地址能够优先存在,也得以暂且分配。换句话说:当客户发送DHCP请求报文时,DHCP服务器服务器先在其数据库中找出该Computer的配置消息。若找到,则赶回找到的消息。若找不到,则从服务器的IP地址池中取3个地点分配给该Computer。

三 通信流程 /
Communication Flow

      
芯片中的BOOTP运营代码运营客户端,此时客户端还尚未地址,因而客户端以0.0.0.0为本机地址,向25伍.25五.255.25伍:陆7广播1个呼吁报文,服务端接收到请求报文后张开验证,并将布置的offer_ip及索要下载运维的公文名插入重临报文,广播回客户端,客户端接收后依照音信运维TFTP下载运行文件。传输进程中富含了重传计谋,服务器接过核查倒车管理等(RFC951)。

      
此处包罗1个鸡和蛋的难点,即就算客户端不晓得本身IP地址,服务器怎么发送IP报文到客户端。

不论什么时候一条指导应答被发送,发送设备举办下列操作:    

1.一旦客户端知道本身的IP地址(’ciaddr’字段非零),因为客户端能够回答ARPs
(Address Resolution Protocol, 六.四.1.二),那么IP能够健康发送。

二.万一客户端还不清楚自身的IP地址(ciaddr是零),客户端就不可能回复指导应答发送程序回的ARPs。那时有二种选拔:   

a.倘使发送程序有不能缺少的主导或驱动钩子程序来人工创立ARP地址缓冲条目款项,就能够动用’chaddr’和’yiaddr’字段填入二个条条框框。当然,这些条款象平时ARP创建的别的条约同样有二本性命时光,指点应答的发送程序就可见轻易地发送引导应答到客户端的IP地址了。UNIX
(四.二BSD)有这种效益。

b.若是发送程序缺少那么些骨干钩子程序,就不得不大致发送引导应答到对迎接口的播音地址。那只是在前边情状外的额外的广播。

通讯流程大致如下,

                    
(0.0.0.0)  Client    –(<broadcast>, 67)–>   Server

              TFTP
<—- Ip and file    <–(<broadcast>, 68)–   (offer ip and
boot file name)

www.hj8828.com 1

Note:
ARP(Address Resolution
Protocol),是依据IP地址获取物理(mac)地址的3个TCP/IP协议。主机发送音信时将饱含目的IP地址的ARP请求播音到互连网上的享有主机,并接收再次来到新闻,以此规定指标的物理地址;收到再次来到音讯后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次央浼时直接查询ARP缓存以节约能源。地址分析协议是创建在互连网中逐一主机相互信任的根底上的,网络上的主机能够独立发送ARP应答音信,其余主机械收割到回复报文时不会检查实验该报文的实际就能够将其记入本机ARP缓存;因而攻击者就足以向某一主机发送伪ARP应答报文,使其发送的新闻不恐怕到达预期的主机或达到错误的主机,那就重组了2个ARP诈骗。ARP命令可用来查询本机ARP缓存中IP地址和MAC地址的附和关系、增多或删除静态对应关系等。相关磋商有RARP、代理ARP。NDP用于在IPv陆中代替地址深入分析协议。

四 数据报文格式 /
Data Message Format

www.hj8828.com 2

字段   字节数    
位号       描述

——   ——— 
 ——         ——

Op          1      
1            Packet op code / Message
type
.包操作码/新闻类型,

一 =
BOOTREQUEST(教导请求), 二 = BOOTREPLY(指导应答)

Htype     1      
2            Hardware address type, 硬件地址类型

‘1’ = 10mb ethernet
10M以太网

Hlen       1      
3            Hardware address length,硬件地址长度

(eg ‘6’ for 10mb
ethernet). 例如’6’是10M以太网

Hops     
1       四            client sets to zero, 客户端设置成0

optionally used by
gateways,在高出网关指引时网关可挑选使用

in cross-gateway
booting.

Xid         4      
5-8         Transaction ID, a random number, used to match this boot
request

with the responses it
generates. 

事情ID,三个随意数,用来合营引用请求和回应

Secs      
2      9-10       Seconds elapsed since client started trying to
boot,filled in by client

由客户端填写,客户端指点起始后的驾鹤归西的秒数

–(Flags)
2      11-12      unused未使用

Ciaddr   
4      13-16     Client IP address,filled in by client in
bootrequest if known.

客户端IP地址,假使客户端知道就在指点请求中填入

Yiaddr    4      
17-20     ‘Your’ (client) IP address,’你的’(客户端)IP地址

filled by server if
client doesn’t know its own address (ciaddr was 0)

若是客户端不知情它的地点(ciaddr是0),服务器填入

Siaddr     4      
21-24    Server IP address,服务器IP地址

returned in bootreply
by server,由服务器在指点应答再次回到

Giaddr    4      
25-28     Gateway IP address,used in optional cross-gateway
booting

网关IP地址,在越过网关指点中得以选拔使用

Chaddr  
16     29-44     Client hardware address,客户端硬件地址

filled in by
client.由客户端填写,前伍个人mac_id,后10位填充0

Sname   
64    45-108    Optional server host name, null terminated
string.

可选的服务器主机名,空截止的字符串

File       
128   109-236  Boot file name, null terminated string;

带领文件名,空截止的字符串

‘generic’ name or null
in bootrequest,

fully qualified
directory-path name in bootreply

在指点请求中利用’通用’名称或空

是教导应答中央银行使十分的目录路线名称

Vend       64   
237-300  Optional vendor-specific
area
,可选的卖主钦赐的区域,

e.g. could be hardware
type/serial on request,

比方,能够是伸手硬件类型/连串,

or ‘capability’ /
remote file system handleon reply. 

或应对的质量/远端文件系统句柄。

This info may be set
aside for use by a third phase bootstrap or kernel.

那么些消息留给第二方剖判指导或骨干(程序)使用。

伍报文加码达成

各自对服务端和客户端的增加利用
Python 进行落实,解码部分就要客户端和服务器的贯彻代码中成功,

里头使用到了 binascii
模块,wmi
模块,struct
模块。

  1 import binascii
  2 import socket
  3 import struct
  4 import wmi
  5 import random
  6 w = wmi.WMI()
  7 
  8 class ServerCodeC:
  9 
 10     @staticmethod
 11     def offer(transaction_id, client_ip_offer, server_ip, client_mac_id, file_path):
 12         SERVER_NAME = 'bootpserver'
 13         VENDOR = ''
 14         client_mac_id = binascii.unhexlify(client_mac_id.replace(':', ''))
 15         transaction_id = binascii.unhexlify(transaction_id)
 16         packet = b''
 17         packet += b'\x02' # op
 18         packet += b'\x01' # htype
 19         packet += b'\x06' # hlen
 20         packet += b'\x00' # hops
 21         packet += transaction_id
 22         packet += b'\x00\x00' # secs
 23         packet += b'\x80\x00' # flags (broadcast)
 24         packet += b'\x00\x00\x00\x00' # current client ip
 25         packet += socket.inet_aton(client_ip_offer) # next current client ip offer
 26         packet += socket.inet_aton(server_ip) # server ip
 27         packet += b'\x00\x00\x00\x00' # gateway ip
 28         packet += client_mac_id # Client mac id #TODO: Change it
 29         packet += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # client mac id padding
 30         packet += SERVER_NAME.encode('utf-8')
 31         packet += b"\x00"*(64-len(SERVER_NAME))
 32         packet += file_path.encode('utf-8')
 33         packet += b"\x00"*(128-len(file_path))
 34         packet += VENDOR.encode('utf-8')
 35         packet += b"\x00"*(64-len(VENDOR))
 36         return packet
 37 
 38     @staticmethod
 39     def collect(msg):
 40         msgBody = {}
 41         m = list(struct.unpack('%dc' % len(msg), msg))
 42         msgBody['op'] = m[0]
 43         msgBody['htype'] = m[1]
 44         msgBody['hlen'] = m[2]
 45         msgBody['hops'] = m[3]
 46         msgBody['xid'] = ''.join(['%02x' % ord(x) for x in m[4:8]]) # transaction_id
 47         msgBody['secs'] = m[8:10]
 48         msgBody['flags'] = m[10:12]
 49         msgBody['ciaddr'] = ''.join(str(ord(i)) + '.' for i in list(struct.unpack('%dc' % len(msg[12:16]), msg[12:16]))).rstrip('.')
 50         msgBody['yiaddr'] = ''.join(str(ord(i)) + '.' for i in list(struct.unpack('%dc' % len(msg[16:20]), msg[16:20]))).rstrip('.')
 51         msgBody['siaddr'] = ''.join(str(ord(i)) + '.' for i in list(struct.unpack('%dc' % len(msg[20:24]), msg[20:24]))).rstrip('.')
 52         msgBody['giaddr'] = ''.join(str(ord(i)) + '.' for i in list(struct.unpack('%dc' % len(msg[24:28]), msg[24:28]))).rstrip('.')
 53         msgBody['chaddr'] = ''.join(['%02x:' % ord(x) for x in m[28:34]])[:-1]  # Client_mac_id (Delete last one ':')
 54         msgBody['sname'] = msg[44:108].decode('utf-8').strip('\x00')
 55         msgBody['file'] = msg[108:236].decode('utf-8').strip('\x00')
 56         msgBody['vend'] = msg[236:300]
 57         return msgBody
 58 
 59 class ClientCodeC():
 60     transaction_id = None
 61     client_mac_id = None
 62 
 63     @classmethod
 64     def get_xid_macid(cls):
 65         xid = ''
 66         for i in range(8):
 67             xid += hex(random.randint(0, 15))[-1]
 68         cls.transaction_id = xid
 69 
 70         mac_id = []
 71         for network in w.Win32_NetworkAdapterConfiguration(IPEnabled=1):
 72             mac_id.append(network.MACAddress)
 73         cls.client_mac_id = mac_id[0].lower()
 74 
 75     @staticmethod
 76     def request():
 77         SERVER_NAME = ''
 78         VENDER = ''
 79         transaction_id = binascii.unhexlify(ClientCodeC.transaction_id)
 80         client_mac_id = binascii.unhexlify(ClientCodeC.client_mac_id.replace(':', ''))
 81 
 82         packet = b''
 83         packet += b'\x01'  # request op    1   1
 84         packet += b'\x01'  # htype         2   1
 85         packet += b'\x06'  # hlen          3   1
 86         packet += b'\x00'  # hops          4   1
 87         packet += transaction_id # transaction_id  5-8     4
 88         packet += b'\x00\x00'  # secs              9-10    2
 89         # TODO: Add resend time count
 90         packet += b'\x80\x00'  # flags(broadcast)  11-12   2
 91         packet += b'\x00\x00\x00\x00'  # client ip 13-16   4
 92         packet += b'\x00\x00\x00\x00'  # your client ip 17-20   4
 93         packet += b'\x00\x00\x00\x00'  # server ip 21-24   4
 94         packet += b'\x00\x00\x00\x00'  # gateway ip 25-28  4
 95         packet += client_mac_id    # mac id 29-34  6
 96         packet += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # mac id placeholder 35-44   10
 97         packet += b'\x00' * 64     # server name   45-108  64
 98         packet += b'\x00' * 128    # file name 109-236 128
 99         packet += VENDER.encode('utf-8')   # vender info 237-300
100         packet += b"\x00"*(64-len(VENDER))
101         return packet
102 
103     @staticmethod
104     def collect(msg):
105         msgBody = {}
106         m = list(struct.unpack('%dc' % len(msg), msg))
107         msgBody['op'] = m[0]
108         msgBody['htype'] = m[1]
109         msgBody['hlen'] = m[2]
110         msgBody['hops'] = m[3]
111         msgBody['xid'] = ''.join(['%02x' % ord(x) for x in m[4:8]]) # transaction_id
112         msgBody['secs'] = m[8:10]
113         msgBody['flags'] = m[10:12]
114         msgBody['ciaddr'] = ''.join(str(ord(i)) + '.' for i in list(struct.unpack('%dc' % len(msg[12:16]), msg[12:16]))).rstrip('.')
115         msgBody['yiaddr'] = ''.join(str(ord(i)) + '.' for i in list(struct.unpack('%dc' % len(msg[16:20]), msg[16:20]))).rstrip('.')
116         msgBody['siaddr'] = ''.join(str(ord(i)) + '.' for i in list(struct.unpack('%dc' % len(msg[20:24]), msg[20:24]))).rstrip('.')
117         msgBody['giaddr'] = ''.join(str(ord(i)) + '.' for i in list(struct.unpack('%dc' % len(msg[24:28]), msg[24:28]))).rstrip('.')
118         msgBody['chaddr'] = ''.join(['%02x:' % ord(x) for x in m[28:34]])[:-1]  # Client_mac_id (Delete last one ':')
119         msgBody['sname'] = msg[44:108].decode('utf-8').strip('\x00')
120         msgBody['file'] = msg[108:236].decode('utf-8').strip('\x00')
121         msgBody['vend'] = msg[236:300]
122         return msgBody

一 采纳DHCP的须求性

DHCP的行事规律:

有关阅读


  1. binascii
    模块

  2. wmi
    模块

  3. struct
    模块

4.
DHCP

 

在TCP/IP互联网上,每台专门的学业站要能存取网络上的能源在此以前,都必须实行基本的网络安插,一些重要参数诸如IP地址,子网掩码,缺省网关,DNS等要求,还大概供给有的叠加的消息如IP管理计策之类。对于二个稍稍大点的互连网来讲,互联网的管制和敬服的职责是非凡辛劳的。1台计算机从3个子网转移到另一个子网,将要重新对系统进行安插。对于常见等级次序的职业站用户是不可能加之他们陈设本人的职业站互联网的权限,而且也尚未这几个供给。假使贰个并未有相应本事水平的用户由于好奇或想学学一下的目的错误地转移了职业站的互连网安插,产生网络故障,后果肯定。由此,须要有1种机制来让TCP/IP的配置和管制从用户端调换成互联网管理端,落成IP的聚焦式管理。消除方案正是用DHCP。

和谐结构

参照链接


  2 DHCP的显要效用

8 bits

DHCP的完备是动态主机配置协议(Dynamic Host Configuration
Protocol),由IETF(Internet
互联网程序猿职责小组)设计,详尽的构和内容在BMWX三FC文书档案rfc213一和rfc15四一里。指标正是为了缓慢化解TCP/IP互连网的宏图、管理和护卫的承受,化解IP地址空间缺乏难题。运营DHCP的服务器把TCP/IP互连网设置聚集起来,动态处理专门的工作站IP地址的配备,用DHCP租约和预置的IP地址相交换,DHCP租约提供了机关在TCP/IP网络上安全地分配和租用IP地址的建制,达成IP地址的聚集式管理,基本上无需互连网管理人士的人为干预。而且,DHCP自己被设计成BOOTP(自举重协会议)的扩充,支持须要互联网陈设音信的无盘职业站,对亟待稳固IP的种类也提供了对应扶助。

16 bits

DHCP的干活原理

24 bits

几个DHCP名词

32 bits

在介绍DHCP工作原理在此之前,先说明那多少个名词的含义:

OpHtypeHlenHopsXidSecsFlagsCiaddrYiaddrSiaddrGiaddrChaddr (16
bytes)Sname (64 bytes)File (128 bytes)Option (variable)

DHCP客户:DHCP客户是壹透过DHCP来获得网络安顿参数的Internet主机,平日正是普通用户的专业站。

  • Op –
    音讯操作代码,既能够是指导请求(BOOTREQUEST)也足以是指引答(BOOTREPLY)
  • Htype – 硬件地址类型
  • Hlen – 硬件地址长度
  • Xid –处理ID
  • Secs –从得到到IP地址大概续约进程最先到明天所消耗的时光
  • Flags –标记
  • Ciaddr –客户机 IP地址
  • Yiaddr –“你的”(客户机)IP 地址
  • Siaddr –在 bootstrap 中利用的下1台服务器的IP地址
  • Giaddr –用于导入的接手代理IP地址
  • Chaddr –客户机硬件
  • Sname –任意服务器主机名称,空终止符
  • File –DHCP
    发掘协议中的教导文件名、空终止符、属名大概空,DHCP供应协议中的受限目录路径名
  • Options –可选参数字段。仿效定义选拔列表中的选用文件

DHCP服务器:DHCP服务器是提供互连网设置参数给DHCP客户的Internet主机。

技巧细节:

DHCP/BOOTP 中继代理:在DHCP客户和服务器之间转载 DHCP
消息的主机或路由器。

  • DHCP统一运用七个IANA分配的端口作为BOOTP:服务器端使用67/udp,客户端应用68/udp。

DHCP是依照客户机/服务器模型设计的,DHCP客户和DHCP服务器之间通过收发DHCP音信进行电视发表。

DHCP 新闻的格式:

  • DHCP运营分为多个基本历程,分别为呼吁IP租约、提供IP租约、选取IP租约和确定IP租约。

www.hj8828.com 3

DHCP 音讯的格式与BOOTP音信超越八分之四平等,
那样设计能够拉长BOOTP服务器工具,相同的时候为BOOTP和DHCP三种客户服务。其余,BOOTP的连片代理可用来转载跨子网的DHCP请求。

  • 客户在赢得了1个IP地址然后,就能够发送一个ARP请求来制止由于DHCP服务器地址池重叠而吸引的IP争论。