在我的另一个线程中,我正在谈论关于iptables策略和状态的一些有趣的事情,现在我想更多地了解DHCP的工作原理以及iptables如何理解它。
ETH0连接到我的主交换机,从我的路由器接收dynamicIP,不仅可以访问互联网,还可以访问我的外部networking。
ETH1是连接到X客户端从该服务器接收IPS的内部交换机的内部卡
ETH1networking为192.168.1.0/255.255.255.0,其中服务器IP为192.168.1.254。
根据我的理解,dhcp是一个bootp协议,所以即使你有防火墙策略来删除所有的东西,你的networking仍然会收到DHCP,在我做的testing中,它似乎是真的。
从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
所以,即使使用默认的POLICY丢弃所有的东西,我仍然可以在我的networking上获得DHCP,而更新IP等方式却需要很长的时间。
如果我将下面的规则添加到我的防火墙中:
$IPT -I OUTPUT -o $INTIF -p udp --dport 67:68 --sport 67:68 -j ACCEPT
更新任何客户端dhcp将花费很less的时间。
考虑到以上情况:
如果你知道很好的链接,我不介意花很多:)
我会回答#2:不。
当获得IP地址时,dhcp守护程序会创build一个到networking接口的原始套接字,并处理UDP协议本身。 因此UDP数据包永远不会经过iptables。
dhcp守护进程必须实现UDP的原因是,当接口有一个IP地址时,内核只能处理UDP(实际上是所有的TCP / IP套件)。 以前的dhcp守护进程首先会给一个接口的IP地址0.0.0.0,但不再有效。
添加
$IPT -I INPUT -i $INTIF -p udp --dport 67:68 --sport 67:68 -j ACCEPT
应使DHCPD更新更快:)它应该工作在INPUT和OUTPUT两边。 您可以使用ebtables删除dhcpd,而不是使用iptables。 DHCPD在0.0.0.0监听,不在IP内
我最近的观察,在OpenWRT Kamikaze 7.09 = 2.4.34和busybox的udhcpc 1.4.2:
我在OUTPUT链中有一个“ACCEPT”策略,而在INPUT方向,最初我依赖于这个经典的catch-all规则:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
允许WAN接口(在我的udhcpc中)的DHCP响应。 即,这是我的ISP的上游DHCP服务器为我分配一个IP地址。
注意初始DHCP交换(discover,offer,request,ack)和DHCP租约续订(request,ack)之间的区别。
启动后,udhcpc从完整的初始交换开始。 这种交stream会成功。 而另一两个更新也会成功 – 只是一个请求和确认。 我的ISP的DHCP服务器通常要求更新时间约1小时到1.5小时,因此我的DHCP客户端要求每30到45分钟更新一次(此行为基于RFC)。
但是,在大约第三次或第四次更新时,它会开始变得有趣。 TCPdump会显示大约三次左右的更新尝试,然后进行全面的初始交换 – 在几分钟甚至几秒钟的时间内。 就好像udcpc不喜欢它回来的那样:-(最终会对整个交换感到满意,之后在半个小时内再次更新就会成功……故事会再次重演。
我想通了,这可能是内核中的连接跟踪有问题。 好像conntrack条目在两个小时左右之后过期,而后续的DHCP续订失败,因为来自服务器的ACK实际上并没有使udhcpc监听套接字。 请注意,tcpdump(libpcap)在原始接口上进行侦听,并可以在进入iptables之前看到所有进入的数据包。 一旦udhcpc放弃更新,并绝望地尝试从头开始使用完整的交换(从DISCOVER开始),内核build立一个新的conntrack条目,并可以理解相关的数据包更多的时间…
果然,一旦我添加了如下内容:
iptables -A INPUT -i $OUT_IF -p udp --sport 67 --dport 68 -j ACCEPT
更新似乎永远工作。
您可能会发现以下tcpdump cmdline参数非常有用:
tcpdump -vv -s 1500 -i eth0.1 port 67 or port 68
注意: -vv要求详细的解剖器输出。 eth0.1是我的WAN端口(也是“NAT外部”接口)。
在ACK分组中有一个有趣的属性是LT:field =build议/最大授权租约时间,以秒为单位。 DHCP请求从端口68发送到端口67.响应来自端口67到端口68。