我正在使用带有 dhclient 4.2.5 的 centos 7:
$ uname -a
Linux hostname 3.10.0-229.el7.x86_64 #1 SMP Fri Mar 6 11:36:42 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
$ dhclient -V
Internet Systems Consortium DHCP Client 4.2.5
Copyright 2004-2013 Internet Systems Consortium.
All rights reserved.
最近我注意到日志中包含大量以下记录:
Dec 14 10:12:32 hostname dhclient[4186]: DHCPREQUEST on enp5s0f0 to 10.23.0.4 port 67 (xid=0xe1a88f7)
Dec 14 10:12:49 hostname dhclient[4186]: DHCPREQUEST on enp5s0f0 to 10.23.0.4 port 67 (xid=0xe1a88f7)
Dec 14 10:13:09 hostname dhclient[4186]: DHCPREQUEST on enp5s0f0 to 10.23.0.4 port 67 (xid=0xe1a88f7)
Dec 14 10:13:23 hostname dhclient[4186]: DHCPREQUEST on enp5s0f0 to 10.23.0.4 port 67 (xid=0xe1a88f7)
Dec 14 10:13:41 hostname dhclient[4186]: DHCPREQUEST on enp5s0f0 to 10.23.0.4 port 67 (xid=0xe1a88f7)
这似乎是由于 DHCP 服务器忽略了单播请求。还有其他人也遇到了这样的问题:https://forum.pfsense.org/index.php?topic=51701.0
我尝试使用 iptables 将数据包目标 ip 更改为 255.255.255.255:
sudo iptables -t nat -I OUTPUT 1 -d 10.23.0.4 -p udp --dport 67 -j DNAT --to-destination 255.255.255.255
但出于某种原因,规则不匹配来自 的数据包dhclient
。但是它匹配来自 nc 的数据包:echo 123 | nc -u 10.23.0.4 67
我发现这个关联其中说 dhclient 的工作方式不同,iptables 不会处理:
For most operations, DHCP software interfaces to the Linux IP stack at
a level below Netfilter. Hence, Netfilter (and therefore Shorewall)
cannot be used effectively to police DHCP. The “dhcp� interface option
described in this article allows for Netfilter to stay out of DHCP's
way for those operations that can be controlled by Netfilter and
prevents unwanted logging of DHCP-related traffic by
Shorewall-generated Netfilter logging rules.
我有几个问题:
- dhclient 使用一些未被 iptables 处理的低级 API 是否正确?
- 有什么方法可以减少 dhclient 中未答复的单播请求的日志量?
答案1
- dhclient 使用一些未被 iptables 处理的低级 API 是否正确?
简短版本:对于某些 DHCP 服务器(isc-dhcp 和 dnsmasq 的早期版本)是的,但对于其他一些服务器(dnsmasq 的更高版本)则不是。
详细解释:事情的起因是raw socket
。原始套接字根据维基百科,
... 一个互联网套接字,允许直接发送和接收互联网协议数据包,而无需任何特定于协议的传输层格式。
此 ISC Wiki 页面(互联网系统联盟是最常见的 DHCP 程序的作者)指出:
DHCP 协议有一些特定的要求才能真正正常工作 - 特别是能够传输和接收发送到全 1 限制广播地址 (255.255.255.255) 的数据包,并且能够在没有 ARP 的情况下发送单播。虽然 dhcpd 也会打开一个 BSD/UDP 套接字(称为“后备接口”),但无法通过 BSD/UDP 套接字执行此操作,您可以在 netstat 中看到它。
这很有趣,因为它解释了为什么你经常会通过谷歌搜索发现人们试图iptables
通过 UDP 端口 67 和 68 控制 DHCP 请求。当然,并不是说这些端口没有打开,只是这不是服务器和客户端之间进行通信的唯一渠道。
但这并不能完全成功:有些人已经采取了彻底关闭其机器的极端措施( iptables 丢弃了所有内容!),但他们无法通过原始数据包关闭 DHCP。
另一个有趣的实验方法是,再次iptables
关闭某人的电脑,然后使用原始套接字进行 DNS 或 TCP 连接:尽管有 iptables,这些通信尝试仍会成功。
关于这一点,可以找到一个非常权威的评论在 Netfilter 网站上,其中规定:
原始套接字绕过 TCP/IP 堆栈。Netfilter 钩子以及 iptables 位于 IP 堆栈内。
这同样适用于数据包嗅探器。
他们还在这里解释了如何规避这个问题:小心,这是一个笑话,Schaaf 说
这不是一个周末项目。
最后,我还想指出,域名系统: 在一个Debian 维基页面dnsmasq 的作者 Simon Kelly 指出:
Dnsmasq 打开原始套接字,但它从不从套接字读取数据:相反,它用于与尚未完全配置且无法执行 ARP 的 DHCP 客户端通信。这不是安全问题。更高版本的 dnsmasq 使用不同的技术,不再打开原始套接字。
编辑:
有什么方法可以减少 dhclient 中未答复的单播请求的日志量?
这并不简单,因为 CLI 选项可以减少输出dhclient
,-q,可以从 CLI 调用,但不能从dhclient.conf。另外,dhclient
它通常不是由网络管理器直接调用,而是由可执行文件调用:ifup
事实上,
# strings `(which ifup)` | grep dhclient
/sbin/dhclient
/sbin/dhclient3
dhclient -v -r -pf /run/dhclient.%iface%.pid -lf /var/lib/dhcp/dhclient.%iface%.leases %iface%
dhclient3 -r -pf /run/dhclient.%iface%.pid -lf /var/lib/dhcp3/dhclient.%iface%.leases %iface%
dhclient -1 -v -pf /run/dhclient.%iface%.pid -lf /var/lib/dhcp/dhclient.%iface%.leases %iface% [[-e IF_METRIC=%metric%]]
dhclient3 -pf /run/dhclient.%iface%.pid -lf /var/lib/dhcp3/dhclient.%iface%.leases %iface% [[-e IF_METRIC=%metric%]]
dhclient -6 -r -pf /run/dhclient6.%iface%.pid -lf /var/lib/dhcp/dhclient6.%iface%.leases %iface%
dhclient -1 -6 -pf /run/dhclient6.%iface%.pid -lf /var/lib/dhcp/dhclient6.%iface%.leases %iface%
dhclient -1 -6 -S -pf /run/dhclient6.%iface%.pid -lf /var/lib/dhcp/dhclient6.%iface%.leases %iface%
正如您所见,使用(= verbose!) 选项ifup
进行调用,这与您希望的相反。dhclient
-v
你有哪些选择?
下载源代码,修改上面的调用,然后为您的内核重新编译它。这应该是小菜一碟。
您可以使用二进制编辑器将 转换
-v
为-q
。您可以修改脚本文件,
/etc/init.d/networking
通过将的调用替换ifup
为ifup .... > /dev/null 2>&1
重新启动或重新启动服务
networking
将完成此修改。这不是理想的做法,因为它会将两个无用的警告扔进垃圾桶和严重的错误消息。最后,您可以执行以下操作:移至
/sbin/dhclient
,/sbin/dhclient-true
然后创建一个名为的可执行文件,/sbin/dhclient
其内容如下:#!/bin/bash ARGS=$(echo "$@" | sed 's/ -v / /g') exec /sbin/dhclient-true "-q" "$ARGS"
答案2
DHCP 是客户端获取 IP 的首要方式,因此如果使用 IP,那么就存在先有鸡还是先有蛋的问题。因此,它在低于 L2 的级别上运行,使用 MAC 地址。因此 IP 路由对其存在一无所知。
我目前不使用 PFSense,所以我无法具体指出你的问题,但应该有一个日志详细程度设置,如果你将其设置得较低,你应该只会看到警告。