场景描述
在使用DHCP服务器的时候,经常会有操作是把某个客户机的MAC地址与某个IP地址进行静态绑定,这是一个常规操作。 无论是你是使用Windows Server的DHCP, 运行在交换机上的DHCP或者一台LINUX DHCP服务器,都是个常规操作。
最近我们的一个客户提出了一个需求,他们想让静态地址绑定在交接机接口上,而不是通过MAC地址绑定。 场景是他们有一个144个机位的测试生产线(12组每组12台), 需要不停的测试新生产的台式机,每72小时完成一台的测试再测试另外一台。 每个机位上有一个网口(网线), 但是测试过程要求每个机位上的台式机的IP地址是固定的。
DHCP Option82可以在客户机发出的广播包中夹带的客户端位置信息。我们在在接入交换上启用Option 82功能,配合DHCP服务器的分发策略来解决这个问题。总体分三步:
- 开启接入交换机的Option82功能(有的设备有可能需要同时打开DHCP中继)2
- 在DHCP服务器上取得Remote-Id/Circuit-Id的默认值格式(也可以配置自定义的Remote-Id和Circuit-Id的值)
- 配置DHCP地址分发策略
客户使用TPLINK TL-SG2024D作为接入交换机, TL-SG5428作为核心交换机, 网络拓扑如下:
Option 82
定义
DHCP option 82是为了增强DHCP服务器的安全性,改善IP地址配置策略而提出的一种DHCP选项。通过在网络接入设备上配置DHCP中继代理功能,中继代理把从客户端接收到的DHCP请求报文添加进option 82选项(其中包含了客户端的接入物理端口和接入设备标识等信息),然后再把该报文转发给DHCP服务器,支持option 82功能的DHCP服务器接收到报文后,根据预先配置策略和报文中option 82信息分配IP地址和其它配置信息给客户端。
具体来的来说, Option 82是在客户机发起的DHCP广播包中插入一段信息,这段信息包含Remote-Id和Circuit-Id两部分。
Remote-Id(远程代理ID)
对于TPLINK的设备来说,默认的Remote-ID就是交换机的MAC地址, 用AA:BB:CC:DD的格式表示。这个ID也可以配置成自定义的名称。
Remote-Id的中文翻译是“远程代理ID", 而ID的值是交换机的MAC地址,交换机就是这个过程中的那个”代理“。 对应上面定义中的黑字”通过在网络接入设备上配置DHCP中继代理功能“,它的意思就是需要在DHCP广播包到达DHCP服务器中间的链路上有一个”代理“, 通常是某一层的交换机设备来充当这个代理。
在我们的案例中, 接入层的TL-SG2024D交换机就充当了这个代理。 需要这个设备支持代这种”代理功能“。 而在其WEB管理界面下,我们也的确找到了开启Option 82的相关功能。
Circuit-Id(电路ID)
指交换机上的物理接口名称,对于TPLINK设备,它是类似于0:1:1, 0:1:2 ... 0:1:24格式的名称, 分别对应交换机上的1号接口,2号接口直到24号接口。 电路ID也可以自定义。
如何确定Remote-Id和Circuit-Id的格式
不能通过Wireshark/Tcpdum抓包的信息中获得, 格式是不对的。最初调试的时候,我们用Wireshark在DHCP服务器上抓包得到的Remote-Id是aabbccddee这样格式的MAC地址, Circuit-Id是00101, 00102这样的格式。 然后配合Linux下的isc-dhcp-server来配置策略时,发现是无效的。
在正常配置isc-dhcp-server服务器的/var/lib/dhcp/dhcpd.releases中,找到一条已经分配的地址记录中,可以找到正确格式的ID值。但这必须在正确配置了接入交换机的Option 82功能之后才会出现这样的值。
在交换机上启用Option 82
TPLINK 2024交换机的Option 82功能在 二层交换/DHCP侦听功能下,必须打开DHCP侦听功能,然后选择全部接口,配置:
Option 82:启用
模式:保留
信任: 启用
在DHCP服务器来源的那个接口上还需要配置“信任”, 这样别的接口上接入DHCP服务器是不会生效的,在本例中,我选择全部接口,配置全部启用了“信任”
电路ID和远程ID子项你可以配置自定义的值,也可以保留默认的,这只影响你以后写DHCP策略时如何去写。 比如说,我可以手动的把12台接入交换机的每一个接口的电路ID都给一个唯一的值,比如SW001 - SW144, 这样我只要用电路ID(Circuit-Id)一个值就可以区分所有的接口了。 在本例中,我禁用了自定义两个Id,使用默认值,并且选择全部接口,配置全部启用了“信任”。
配置DHCP策略(isc-dhcp-server)
Linux的isc-dhcp-server
你首先要有个能正常工作的Linux DHCP Server, 配置文件如下,
#/etc/dhcp/dhcp.conf
option domain-name "owl.local";
option domain-name-servers 223.5.5.5,223.6.6.6;
default-lease-time 600;
max-lease-time 7200;
ddns-update-style none;#这个配置会让DHCP请求在Review和Select阶段时也带着Option 82的信息
stash-agent-options true;#此处定义144个分类器,用来分辨12台交换机上的144个接口, 我们的案例中每台交换机上只有1-12号接口接有需要固定IP地址的设备
#.... S01P01是分类器的自定义名称,表示Switch 1号上的1号接口, 此分类器写144条, 每台交换机上12条, S01P01 ~ S01P12,然后是S02P01 ~ S02P02
class "S01P01" {match if option agent.circuit-id=0:1:1 and option agent.remote-id=80:ae:54:91:36:c0;}
class "S01P02" {match if option agent.circuit-id=0:1:2 and option agent.remote-id=80:ae:54:91:36:c0;}subnet 10.18.18.0 netmask 255.255.255.0 {option subnet-mask 255.255.255.0;option routers 10.18.18.254;pool {allow members of "S01P01";range 10.18.18.1 10.18.18.1;}pool {allow members of "S01P02";range 10.18.18.2 10.18.18.2;}#... 写144条,每条策略一个IP地址池,每个池子里只有1个地址pool {allow members of "S12P12";range 10.18.18.144 10.18.18.144;}
}
authoritative;
log-facility local7;
使用核心交换机的DHCP功能
我们也尝试过使用一台华三的核心交接机上的DHCP功能,也可以实现同样的效果,配置方法参照华三的相关文档,其中需要用皇的命令是dhcp class XXXX,然后使用if-match命令来判断客户机的来源。在此不详细展开,最终我们在这个场景下仍然使用Linux服务器来做这件事情。 主要担心客户环境如果扩充到更多设备时,核心交换机能承载的配置长度。
以下只给一个华三核心交换下简单的示例:
# 在这个例子中,我们手动定义了交换机的Circuit-Id,每个接口定义一个名称,比如 "sw01p01", 没有使用Remote-Id
# rule命令中的hex是把"sw01p01"文本转十六进制的结果
dhcp class sw01p01
if-macth rule 1 option 82 hex 73773031703031dhcp class sw01p02
if-macth rule 1 option 82 hex 73773031703032# .... 144组分类dhcp server ip-pool TESTPC
gateway-list 10.18.18.254
network 10.18.18.0 mask 255.255.255.0
class sw01p01 range 10.18.18.1 10.18.18.1
class sw01p02 range 10.18.18.2 10.18.18.2# ... 144条