IPTables和DHCP有问题吗?


8

在我的另一个线程上,我正在谈论有关iptables策略和状态的一些有趣的事情,现在我想了解有关DHCP如何工作以及iptables如何理解的更多信息。

ETH0连接到我的主交换机,该交换机从我的路由器接收动态IP,不仅可以访问Internet,还可以访问我的外部网络。

ETH1是连接到内部交换机的内部卡,X客户端从此服务器接收其IPS

ETH1网络是192.168.1.0/255.255.255.0,其中服务器IP是192.168.1.254。

据我了解,dhcp是一个bootp协议,因此,即使您具有将所有内容都丢弃的防火墙策略,您的网络仍会收到DHCP,在我进行的测试中,这似乎是正确的。

从tcpdump:

root@test:~# tcpdump -i eth1 port 67 or 68
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
11:34:03.943928 IP 192.168.1.2.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 00:0c:29:29:52:8b (oui Unknown), length 303
11:34:03.957647 IP 192.168.1.254.bootps > 192.168.1.2.bootpc: BOOTP/DHCP, Reply, length 300
11:34:06.492153 IP 192.168.1.2.bootpc > 192.168.1.254.bootps: BOOTP/DHCP, Request from 00:0c:29:29:52:8b (oui Unknown), length 303
11:34:06.506593 IP 192.168.1.254.bootps > 192.168.1.2.bootpc: BOOTP/DHCP, Reply, length 300

我制定了一个简单的日志规则来查看iptables的作用:

root@test:~# tail -f /var/log/syslog
Oct 15 11:30:58 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9527 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:31:43 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9529 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:33:32 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9531 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:34:03 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9533 PROTO=UDP SPT=68 DPT=67 LEN=311

这是我当时的iptables规则:

# deny all traffic
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP

# Use stateful inspection feature to only allow incoming connections
# related to connections I have already established myself
$IPT -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# allow all traffic on lo interface
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT

因此,即使使用默认策略丢弃所有内容,我仍然可以在网络上获得DHCP,而更新IP等则需要花费更长的时间。

如果我将以下规则添加到防火墙中:

$IPT -I OUTPUT -o $INTIF -p udp --dport 67:68 --sport 67:68 -j ACCEPT

更新所有客户端dhcp都将花费很少的时间。

考虑到上述情况:

  1. 为什么即使不被阻止,更新它的确需要花费更长的时间呢?
  2. 是否可以完全关闭dhcp服务器而不关闭它?
  3. 是否可以通过BOOTP在iptables中接受dhcp服务器?那是怎么做的?

如果您知道好的链接,我不介意花很多时间:)


我对您的tcpdump和iptables日志输出有些困惑。您是否在混杂模式下监视网络接口?您的防火墙服务器是否实际上使用DHCP配置其NIC?
史蒂文

@Steven具有上述防火墙的服务器具有eth0和eth1,eth0从外部接收dhcp作为客户端,而eth1是我正在谈论的内部网络的dhcp服务器。您是什么意思,Are you monitoring the network interface in promiscuous mode我仍在学习...
Guapo

哦好的。如果您想让任何人理解您的问题,您确实需要更好地描述您的网络和服务器!
史蒂文


@Steven现在会这样做,谢谢您指出,您是否认为除了网络布局外,我还必须指定其他内容?
瓜波

Answers:


13

我会回答#2:不。

当获取IP地址时,dhcp守护程序将为网络接口创建一个原始套接字,并处理UDP协议本身。因此,UDP数据包从不通过iptables。

dhcp守护程序必须实现UDP的原因是,当接口具有IP地址时,内核只能处理UDP(实际上是所有TCP / IP套件)。以前,dhcp守护程序会首先为接口提供IP地址0.0.0.0,但该接口不再起作用。


数据包套接字。原始套接字确实会通过iptables。afaict。unix.stackexchange.com/a/447524/29483
sourcejedi

5

新增中

$IPT -I INPUT -i $INTIF -p udp --dport 67:68 --sport 67:68 -j ACCEPT

可以使DHCPD更新更快:)可以同时在INPUT和OUTPUT上工作。您可以使用ebtables而不是iptables删除dhcpd。DHCPD侦听0.0.0.0,不在IP范围内


+1我在INPUT上拥有它,它所花费的时间与我在规则上没有它所花费的时间相同。当我将其设置为输出时,确实会产生巨大的变化。我将阅读有关ebtables的感谢。
瓜波

$ IPT -I INPUT -i $ INTIF -s 0/0 -p udp --dport 67:68 --sport 67:68 -j ACCEPT
Ta Coen 2010年

只是尝试了上述方法,与使用OUTPUT规则相比,仍然花费了很长时间。
瓜波

由于该策略是DROP,因此您将同时使用INPUT和OUTPUT。
塔科恩

3

我最近在OpenWRT Kamikaze 7.09 = 2.4.34和busybox 1.4.2中的udhcpc上观察到:

我在OUTPUT链中有一个“ ACCEPT”策略,并且在INPUT方向上,最初我是遵循以下经典的万能规则:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

允许DHCP响应进入WAN接口上(对我的udhcpc)。即,这是我的ISP的上游DHCP服务器为我分配IP地址的地方。

注意初始DHCP交换(发现,报价,请求,确认)与DHCP租约续订(请求,确认)之间的区别。

引导后,udhcpc将通过完整的初始交换开始。那种交流将会成功。另外一两次更新也将成功-只是一个请求和确认。我的ISP的DHCP服务器通常要求大约一小时到1.5个小时的更新时间,因此我的DHCP客户端每30到45分钟请求一次更新(此行为基于RFC)。

但是,大约在第三或第四次更新时,它就会变得很有趣。TCPdump将显示大约3次左右的更新尝试,然后进行一次完整的初始交换-只需几分钟甚至几秒钟的时间。好像udhcpc不喜欢它返回的内容:-(最终将对完整的交换感到满意。在那之后,半小时内的另一个续订将成功...故事将再次发生。

我发现,也许是内核中的连接跟踪出了点问题。好像conntrack条目在两个小时左右后到期,并且以后的DHCP更新失败,因为来自服务器的ACK实际上并未使其监听套接字上的udhcpc。请注意,tcpdump(libpcap)在原始接口上进行侦听,并且可以查看所有传入的数据包,然后再对它们进行iptables处理。一旦udhcpc放弃了续约,并在绝望中尝试使用完整的交换(从DISCOVER开始)从头开始,内核就会建立一个新的conntrack条目,并且可以理解更多的相关数据包...

果然,一旦我添加了类似的内容:

iptables -A INPUT -i $OUT_IF -p udp --sport 67 --dport 68 -j ACCEPT

更新似乎永远有效。

您可能会发现以下tcpdump cmdline args有用:

tcpdump -vv -s 1500 -i eth0.1 port 67 or port 68

注意:-vv要求详细的解剖器输出。eth0.1是我的WAN端口(也是“ NAT外部”接口)。

ACK数据包中一个有趣的属性是LT:字段=建议/最大授予的租用时间(以秒为单位)。DHCP请求从端口68发送到端口67。响应从端口67发送到端口68。


你的故事没有道理。无论是初始的还是续订的,DHCP交换总是由客户端从端口68发送到端口67(以特定IP或广播)开始。随着即将离任的ACCEPT,这将始终有效。来自外发目的地的回复应始终通过ESTABLISHED规则传入,因此更新应该只适用于ESTABLISHED规则,因为每次续订也会续订或重新创建conntrack状态。
Mecki

续订将发送请求openwrt:68 -> dhcpserver:67,并且ACK将为dhcpserver:67 -> openwrt:68。这将视为已建立并将通过。如果旧的conntrack状态已过期,则会建立一个新的状态。如果有问题,则只能使用DISCOVER进行初始交换,0.0.0.0:68 -> 255.255.255.255:67而OFFER将是dhcpserver:67 -> new-openwrt:68,这不算是ESTABLISHED。这只能作为DHCP通常绕过iptables在Linux上的包插座,否则进入的规则,要求允许数据包从UDP端口67或UDP端口68
Mecki

1
您还说几次更新确实成功,但是每次更新都将更新conntrack状态,因此,如果您的conntrack状态在2小时后过期,则更新会将其再次延长2小时,依此类推,因此它将永远不会过期。但是,UDP的默认conntrack超时仅为30秒,而不是2小时,我怀疑OpenWRT会将其更改为2小时,因为这太疯狂了。所以你的故事对我来说似乎完全是有缺陷的。
Mecki

@Mecki,感谢您的宝贵反馈:-)到目前为止,我的答复是4岁。大约一年前,我的华硕WL500G Deluxe开始出现终端现象(由于电容器的更换,经过大约12年的运行时间),我随身携带了旧的神风队成员。现在,我正在现代TP-Link AP上运行最新的OpenWRT,经过一番思考,我没有重用旧的防火墙脚本。现在,OpenWRT似乎已经具备了良好的防火墙功能……我的意思是说我无法验证我过去的说法。我所知道的是,额外的iptables规则确实有所帮助。
frr
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.