我是试在私有 Docker 网桥后面运行 DHCP 服务器。
我现在可以将DHCPDISCOVER
广播数据包重新路由到 Docker 桥后面的 DHCP 服务器,并让 DHCP 响应DHCPOFFER
:
table netdev filterearly {
chain ingress {
type filter hook ingress device enp1s0.10 priority -500; policy accept;
ether daddr ff:ff:ff:ff:ff:ff udp sport 68 ip daddr 255.255.255.255 ether daddr set a0:ce:c8:ef:42:64 ip saddr set 192.168.1.0 ip daddr set 172.25.10.5 meta pkttype set host;
}
}
root@debian:~# tcpdump -i br-a039f83f0bc5 port 67 and port 68 or arp -nne
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on br-a039f83f0bc5, link-type EN10MB (Ethernet), snapshot length 262144 bytes
08:47:48.520078 02:42:b6:0c:71:65 > 02:42:ac:19:0a:05, ethertype IPv4 (0x0800), length 342: 192.168.1.0.68 > 172.25.10.5.67: BOOTP/DHCP, Request from 08:00:27:b7:6d:8e, length 300
08:47:51.528778 02:42:ac:19:0a:05 > 02:42:b6:0c:71:65, ethertype IPv4 (0x0800), length 342: 172.25.10.5.67 > 192.168.1.144.68: BOOTP/DHCP, Reply, length 300
然而,由于系统不断发送 ARP 请求,这DHCPOFFER
并没有使其脱离接口:
root@debian:~# tcpdump -i enp1s0.10 port 67 and port 68 or arp -nne
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on enp1s0.10, link-type EN10MB (Ethernet), snapshot length 262144 bytes
08:46:12.556651 08:00:27:b7:6d:8e > ff:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 342: 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 08:00:27:b7:6d:8e, length 300
08:46:12.557763 f0:2f:74:2d:28:88 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.144 tell 192.168.1.1, length 28
08:46:13.577352 f0:2f:74:2d:28:88 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.144 tell 192.168.1.1, length 28
为了解决这个问题,我从CHADDR
字段中设置目标 MAC 地址DHCPOFFER
:
table inet mangle {
chain postrouting {
type filter hook postrouting priority 50;
udp sport 67 @ll,0,48 set @th,288,48;
}
}
尽管如此,ARP 请求仍在发送。
从图中nft monitor trace
我可以看到,在遍历结束时,数据包到达了inet nat postrouting
,这大概是 ARP 查找开始的时候。
...
trace id 537265a7 inet filter forward packet: iif "br-a039f83f0bc5" oif "enp1s0.10" ether saddr 02:42:ac:19:0a:05 ether daddr 02:42:b6:0c:71:65 ip saddr 172.25.10.5 ip daddr 192.168.1.144 ip dscp cs6 ip ecn not-ect ip ttl 63 ip id 53344 ip protocol udp ip length 328 udp sport 67 udp dport 68 udp length 308 @th,64,96 0x2010600fc731d6f00000000
trace id 537265a7 inet filter forward rule meta nftrace set 1 (verdict continue)
trace id 537265a7 inet filter forward verdict continue
trace id 537265a7 inet filter forward policy accept
trace id 537265a7 inet mangle postrouting packet: iif "br-a039f83f0bc5" oif "enp1s0.10" ether saddr 02:42:ac:19:0a:05 ether daddr 08:00:27:b7:6d:8e ip saddr 172.25.10.5 ip daddr 192.168.1.144 ip dscp cs6 ip ecn not-ect ip ttl 63 ip id 53344 ip protocol udp ip length 328 udp sport 67 udp dport 68 udp length 308 @th,64,96 0x2010600fc731d6f00000000
trace id 537265a7 inet mangle postrouting rule udp sport 67 @ll,0,48 set @th,288,48 (verdict continue)
trace id 537265a7 inet mangle postrouting verdict continue
trace id 537265a7 inet mangle postrouting policy accept
trace id 537265a7 inet nat postrouting packet: iif "br-a039f83f0bc5" oif "enp1s0.10" ether saddr 02:42:ac:19:0a:05 ether daddr 08:00:27:b7:6d:8e ip saddr 172.25.10.5 ip daddr 192.168.1.144 ip dscp cs6 ip ecn not-ect ip ttl 63 ip id 53344 ip protocol udp ip length 328 udp sport 67 udp dport 68 udp length 308 @th,64,96 0x2010600fc731d6f00000000
trace id 537265a7 inet nat postrouting rule meta nftrace set 1 (verdict continue)
trace id 537265a7 inet nat postrouting rule iifname "br-a039f83f0bc5" oifname "enp1s0.10" masquerade (verdict accept)
有没有办法告诉netfilter不执行ARP,只是将数据包与当前的标头信息一起发送出去?
谢谢