isc-dhcp-server的分配的地址列表在哪,linux/树莓派做无线路由器怎么查看已连接设备
标题问题答案:
/var/lib/dhcp/dhcpd.leases,这个文件记录了所有isc-dhcp-server分配的IP地址信息
dhcpd.leases文件详解:
# 推荐用 $ man dhcpd.leases 指令 查看详细含义
lease 192.168.8.24 {
starts 3 2016/05/18 10:48:59; # 分配地址的时间
ends 3 2016/05/18 10:58:59; # 租约到期时间
tstp 3 2016/05/18 10:58:59; # 租约到期时间
cltt 3 2016/05/18 10:49:04; # 客户端最后访问时间
binding state free; # 租约绑定状态 状态分别是 free 和 active
hardware ethernet 30:3a:64:50:2d:32; # 客户端mac地址
uid "\0010:dP-2"; # 客户端识别id
set vendor-class-identifier = "MSFT 5.0";
}
lease 192.168.8.25 {
starts 2 2016/06/14 04:23:16;
ends 2 2016/06/14 04:33:16;
cltt 2 2016/06/14 04:23:16;
binding state free;
next binding state free;
rewind binding state free;
hardware ethernet c0:ee:fb:25:82:92;
client-hostname "android-50efd8d429a1278b"; # 客户端主机名
}
lease 192.168.8.25 {
starts 2 2016/06/14 04:28:08;
ends 2 2016/06/14 04:38:08;
cltt 2 2016/06/14 04:28:08;
binding state active;
next binding state free;
rewind binding state free;
hardware ethernet c0:ee:fb:25:82:92;
client-hostname "android-50efd8d429a1278b";
}
你若对如何找这类文件感兴趣,可以接着往下看v
软件:isc-dhcp-server(以下简称IDS), python flask, hostapd
平台:debian8 for arm(raspberry pi 树莓派)
硬件:EP-N8508GS USB无线网卡(以下简称为无线网卡),树莓派2B(以下简称PI)
目的:
学习LINUX,制作一个基于网页端管理的无线路由器(本文主要讲怎么找DHCP的客户端列表)。
选修课大作业,非常感谢万老师开这门课,让我学到了很多linux的知识。
主要思路:
PI以任意方式通过有线网卡连接外网;
PI通过无线网卡作为Wireless Access Point,用到软件hostapd;
PI安装isc-dhcp-server作为DHCP服务器分配IPV4地址;
PI配置IP table使通过AP连接可以访问外网;
配置网页大部分已经完成,只是做功能补充,添加查看DHCP客户端列表功能。
分析:
DHCP由isc-dhcp-server控制,linux不自带DHCP服务器,所以猜测,DHCP的客户端都是由IDS记录的。
第一种情况,所有的记录文件直接以文本文件的形式保存,文件命名是isc-dhcp-*,这种方法我们读取查找起来最简单;
第二种情况,文本文件记录,存放在*/isc-dhcp/*,读取起来和上一种情况类似;
第三种情况,用了sqlite存储信息,被保存成*.db文件,这是读取起来最麻烦的;
第四种情况,DHCP客户端信息放在内存中,其他程序无法读取,如果是这样的,那就基本无解了,但是想到世面上的路由器都有查看DHCP客户端的功能,IDS这个软件应该会把这信息记录到本地文件吧。
无论是什么情况,首先得把存储信息的文件找出来,执行以下查找文件的指令:
$ sudo find / -name 'isc-dhcp*' -type f
查找结果:
pi@raspberrypi:~ $ sudo find / -name 'isc-dhcp*' -type f /var/lib/dpkg/info/isc-dhcp-client.conffiles /var/lib/dpkg/info/isc-dhcp-client.postrm /var/lib/dpkg/info/isc-dhcp-server.postrm /var/lib/dpkg/info/isc-dhcp-server.conffiles /var/lib/dpkg/info/isc-dhcp-server.prerm /var/lib/dpkg/info/isc-dhcp-server.list /var/lib/dpkg/info/isc-dhcp-server.config /var/lib/dpkg/info/isc-dhcp-client.md5sums /var/lib/dpkg/info/isc-dhcp-server.templates /var/lib/dpkg/info/isc-dhcp-server.postinst /var/lib/dpkg/info/isc-dhcp-common.list /var/lib/dpkg/info/isc-dhcp-client.list /var/lib/dpkg/info/isc-dhcp-server.md5sums /var/lib/dpkg/info/isc-dhcp-client.postinst /var/lib/dpkg/info/isc-dhcp-client.preinst /var/lib/dpkg/info/isc-dhcp-common.md5sums /run/systemd/generator.late/isc-dhcp-server.service
看到’isc-dhcp-client.list’这个文件,欣喜若狂,莫非就这么被我找到了,查看了一下结果…
pi@raspberrypi:/var/lib/dpkg/info $ cat isc-dhcp-client.list /. /var /var/lib /var/lib/dhcp /sbin /sbin/dhclient-script /sbin/dhclient /etc /etc/dhcp /etc/dhcp/dhclient.conf /etc/dhcp/dhclient-exit-hooks.d /etc/dhcp/dhclient-exit-hooks.d/debug /etc/dhcp/dhclient-exit-hooks.d/rfc3442-classless-routes /etc/dhcp/dhclient-enter-hooks.d /etc/dhcp/dhclient-enter-hooks.d/debug /usr /usr/share /usr/share/doc /usr/share/doc/isc-dhcp-client /usr/share/doc/isc-dhcp-client/copyright /usr/share/doc/isc-dhcp-client/changelog.Debian.gz /usr/share/doc/isc-dhcp-client/NEWS.Debian.gz /usr/share/man /usr/share/man/man5 /usr/share/man/man5/dhclient.conf.5.gz /usr/share/man/man5/dhclient.leases.5.gz /usr/share/man/man8 /usr/share/man/man8/dhclient-script.8.gz /usr/share/man/man8/dhclient.8.gz
继续,当查看到isc-dhcp-client.postrm这个文件时,渐渐开始明朗了起来,红色的语句,应该就是初始化dhcp服务时,需要删除的文件,那么就是本次dhcp服务的记录文件,接下来就是查看这些文件。
pi@raspberrypi:/var/lib/dpkg/info $ cat isc-dhcp-client.postrm #!/bin/sh -e # # if [ "$1" = "purge" ]; then # Remove lease database rm -f /var/lib/dhcp/dhclient*.leases rm -f /var/lib/dhcp/dhclient*.lease # Try to remove directory if [ -d /var/lib/dhcp ]; then rmdir --ignore-fail-on-non-empty /var/lib/dhcp/ fi rmdir --ignore-fail-on-non-empty /etc/dhcp fi
转到 /var/lib/dhcp/ 可以看到有这样一个文件,翻译过来是dh客户端.租约,猜想应该就是这个文件了:
pi@raspberrypi:/var/lib/dhcp $ ls -la dhclient*.leases -rw-r--r-- 1 root root 0 Mar 18 08:08 dhclient.leases pi@raspberrypi:/var/lib/dhcp $ cat dhclient.leases pi@raspberrypi:/var/lib/dhcp $
查看了一下 空欢喜,什么都没有,
那就看看这个路径还有些什么文件:
pi@raspberrypi:/var/lib/dhcp $ ls -la total 20 drwxr-xr-x 2 root root 4096 Jun 14 16:16 . drwxr-xr-x 47 root root 4096 May 18 10:32 .. -rw-r--r-- 1 root root 0 Mar 18 08:08 dhclient.leases -rw-r--r-- 1 root root 5535 Jun 14 16:50 dhcpd.leases -rw-r--r-- 1 root root 3015 Jun 14 16:16 dhcpd.leases~
文件数量不多,逐个查看,dhcpd.leases这个文件,没错就是他 运气不错,记录了DHCP客户端的连接日志:
pi@raspberrypi:/var/lib/dhcp $ cat dhcpd.leases # The format of this file is documented in the dhcpd.leases(5) manual page. # This lease file was written by isc-dhcp-4.3.1 lease 192.168.8.22 { starts 1 2016/06/14 16:55:13; ends 2 2016/06/14 17:05:13; cltt 2 2016/06/14 16:55:13; binding state active; next binding state free; rewind binding state free; hardware ethernet 0c:1d:af:e3:ab:e0; client-hostname "android-33afb4dbee873a4b"; }
# The format of this file is documented in the dhcpd.leases(5) manual page.
第一句注释说,这个格式在dhcpd.leases(5)的用户手册,用户手册中记录了每个项的详细含义
$ man dhcpd.leases
这是我们需要用到的内容
lease 192.168.8.22 { starts 1 2016/06/14 16:55:13; # 租约开始时间 ends 2 2016/06/14 17:05:13; # 租约结束时间 cltt 2 2016/06/14 16:55:13; # 客户端最后访问时间 binding state active; # 绑定状态 next binding state free; rewind binding state free; hardware ethernet 0c:1d:af:e3:ab:e0; # 客户端mac地址 client-hostname "android-33afb4dbee873a4b"; # 客户端主机名 }
接下来就是在python中写获取这些内容的方法,源代码如下:
def getDhcpClientMap(): dhcp_client_filepath = "/var/lib/dhcp/dhcpd.leases" #dhcp_client_filepath = "dhcpd.leases" # 打开文件 dhcp_client_file = open(dhcp_client_filepath) # 创建list用于存放 dhcpClientList = {} rline = dhcp_client_file.readline() while(rline): # 检查地址位置 pos192 = rline.find('192.168') if(pos192 >= 0): # 如果找到 创建对象 posdkh = rline.find('{') rIpAddr = rline[pos192:posdkh - 1] rstartTime = '' rendTime = '' rBindState = '' rMacAddr = '' rHostName = '' # 查找其他内容 while(True): rline = dhcp_client_file.readline() if(rline.find('}') >= 0): break; if(rline.find('starts') >= 0): rstartTime = rline[rline.find('starts') + 9:].replace(';\n', '') continue; if(rline.find('ends') >= 0): rendTime = rline[rline.find('ends') + 7:].replace(';\n', '') continue; if(rline.find(' binding state') >= 0): rBindState = rline[rline.find(' binding state') + 15:].replace(';\n', '').replace(' ', '') continue; if(rline.find('hardware ethernet') >= 0): rMacAddr = rline[rline.find('hardware ethernet') + 17:].replace(';\n', '').replace(' ', '') continue; if(rline.find('client-hostname') >= 0): rHostName = rline[rline.find('client-hostname') + 15:].replace(';\n', '').replace(' ', '').replace('"', '') continue; dxbDhcpClient = {} dxbDhcpClient['ipAddr'] = rIpAddr dxbDhcpClient['satrtTime'] = rstartTime dxbDhcpClient['endTime'] = rendTime dxbDhcpClient['bindState'] = rBindState dxbDhcpClient['macAddr'] = rMacAddr dxbDhcpClient['hostName'] = rHostName # 添加到存放的list dhcpClientList[rMacAddr] = dxbDhcpClient # 接着下一个循环 rline = dhcp_client_file.readline() return dhcpClientList
把状态为active 的设备放入到一个list中,供前端显示:
# 清除非连接状态的客户端 def clearDhcpClientFreeAndToList(dhcpClientMap): for tk in dhcpClientMap.keys(): if(dhcpClientMap[tk]["bindState"] == 'free'): dhcpClientMap.pop(tk) changeList = [] for tk in dhcpClientMap.keys(): changeList.append(dhcpClientMap[tk]) return changeList
控制器方法源代码如下:
@app.route("/wirelessClientList") def dhcpClientPage(): # 获取DHCP客户端列表方法 deviceList = clearDhcpClientFreeAndToList(getDhcpClientMap()) print deviceList return render_template('dhcpclient.html', dlist=deviceList)
页面中遍历(for endfor)获取到的客户端代码如下:
{% for dev in dlist %} <tr> <td>{{dev.hostName}}</td> <td>{{dev.ipAddr}}</td> <td>{{dev.macAddr}}</td> <td>{{dev.satrtTime}}</td> <td>{{dev.endTime}}</td> </tr> {% endfor %}