我正在尝试配置 dnsmasq 以 DHCP 代理模式运行,向客户端提供 PXE 网络启动信息,同时我的路由器继续充当 DHCP 服务器。
理想情况下,我想在 Docker 容器中运行 dnsmasq。
我首先尝试在运行 Linux 的 VMware VM 中进行设置,如下所示:
# Verbose DHCP logging
log-dhcp
# Disable DNS
port=0
# Enable TFTP
enable-tftp
tftp-root=/tftproot
# Answer DHCP discovery requests coming in over the virtual machine
dhcp-range=172.0.0.0,proxy,255.0.0.0
dhcp-vendorclass=set:bios,PXEClient:Arch:00000
pxe-service=tag:bios,x86PC,"Netboot",netboot.xyz.kpxe,172.16.80.2
我启动了另一台 VMware VM,并将其设置为从网络启动。经过漫长的等待后,它确实开始通过 DHCP 进行配置,并成功启动。这是 dnsmasq 的输出:
dnsmasq-dhcp: 705858459 available DHCP subnet: 172.0.0.0/255.0.0.0
dnsmasq-dhcp: 705858459 vendor class: PXEClient:Arch:00000:UNDI:002001
dnsmasq-dhcp: 705858459 PXE(ens33) 00:0c:29:12:8b:9b proxy
dnsmasq-dhcp: 705858459 tags: bios, ens33
dnsmasq-dhcp: 705858459 broadcast response
dnsmasq-dhcp: 705858459 sent size: 1 option: 53 message-type 2
dnsmasq-dhcp: 705858459 sent size: 4 option: 54 server-identifier 172.16.80.2
dnsmasq-dhcp: 705858459 sent size: 9 option: 60 vendor-class 50:58:45:43:6c:69:65:6e:74
dnsmasq-dhcp: 705858459 sent size: 17 option: 97 client-machine-id 00:56:4d:e4:12:5a:70:00:5b:07:fb:d3:7b:cc...
dnsmasq-dhcp: 705858459 sent size: 31 option: 43 vendor-encap 06:01:03:0a:04:00:50:58:45:08:07:80:00:01...
dnsmasq-dhcp: 705858459 available DHCP subnet: 172.0.0.0/255.0.0.0
dnsmasq-dhcp: 705858459 vendor class: PXEClient:Arch:00000:UNDI:002001
dnsmasq-dhcp: 705858459 available DHCP subnet: 172.0.0.0/255.0.0.0
dnsmasq-dhcp: 705858459 vendor class: PXEClient:Arch:00000:UNDI:002001
dnsmasq-dhcp: 705858459 PXE(ens33) 172.16.80.3 00:0c:29:12:8b:9b netboot.xyz.kpxe
dnsmasq-dhcp: 705858459 tags: bios, ens33
dnsmasq-dhcp: 705858459 bootfile name: netboot.xyz.kpxe
dnsmasq-dhcp: 705858459 next server: 172.16.80.2
dnsmasq-dhcp: 705858459 sent size: 1 option: 53 message-type 5
dnsmasq-dhcp: 705858459 sent size: 4 option: 54 server-identifier 172.16.80.2
dnsmasq-dhcp: 705858459 sent size: 9 option: 60 vendor-class 50:58:45:43:6c:69:65:6e:74
dnsmasq-dhcp: 705858459 sent size: 17 option: 97 client-machine-id 00:56:4d:e4:12:5a:70:00:5b:07:fb:d3:7b:cc...
dnsmasq-dhcp: 705858459 sent size: 7 option: 43 vendor-encap 47:04:80:00:00:00:ff
dnsmasq-tftp: error 0 TFTP Aborted received from 172.16.80.3
dnsmasq-tftp: failed sending /tftproot/netboot.xyz.kpxe to 172.16.80.3
dnsmasq-tftp: sent /tftproot/netboot.xyz.kpxe to 172.16.80.3
现在我在 Docker 容器内运行同样的事情:
docker run --rm -it \
--cap-add NET_ADMIN \
-v /tftproot:/tftproot:ro \
-v $(pwd)/dnsmasq.conf:/etc/dnsmasq.conf:ro \
-p 67:67/udp \
-p 69:69/udp \
-p 4011:4011/udp \
andyshinn/dnsmasq:2.81 --no-daemon
容器检测到客户端正在执行以下任务DHCPDISCOVER
并尝试响应:
dnsmasq-dhcp: 705858459 available DHCP subnet: 172.0.0.0/255.0.0.0
dnsmasq-dhcp: 705858459 vendor class: PXEClient:Arch:00000:UNDI:002001
dnsmasq-dhcp: 705858459 PXE(eth0) 00:0c:29:12:8b:9b proxy
dnsmasq-dhcp: 705858459 tags: bios, eth0
dnsmasq-dhcp: 705858459 broadcast response
dnsmasq-dhcp: 705858459 sent size: 1 option: 53 message-type 2
dnsmasq-dhcp: 705858459 sent size: 4 option: 54 server-identifier 172.17.0.2
dnsmasq-dhcp: 705858459 sent size: 9 option: 60 vendor-class 50:58:45:43:6c:69:65:6e:74
dnsmasq-dhcp: 705858459 sent size: 17 option: 97 client-machine-id 00:56:4d:e4:12:5a:70:00:5b:07:fb:d3:7b:cc...
dnsmasq-dhcp: 705858459 sent size: 31 option: 43 vendor-encap 06:01:03:0a:04:00:50:58:45:08:07:80:00:01...
[above repeats a few times]
客户端才不是当 dnsmasq 在 Docker 容器内以相同的配置运行时,确认网络启动信息。
我有两个理论:
由于 Docker 网络的一些特性,发送到客户端的数据包从未到达那里。
dnsmasq返回
server-identifier
的是 Docker 容器接口的 IP 地址,而不是运行容器的主机的面向网络的 IP 地址(应为 172.16.80.2)。
答案1
dnsmasq 使用端口 68 上的 UDP 广播数据包响应客户端,除非使用,否则该数据包不会离开桥接的 Docker 网络--net=host
。
一种解决方法是在 Docker 网络中添加一个socat
转发到主机的监听器:
socat:
image: alpine/socat
command: >
UDP4-LISTEN:68,reuseaddr,fork
TCP4:172.18.0.1:24000
然后在主机上监听并重新广播到网络:
socat \
TCP4-LISTEN:24000,bind=172.18.0.1,reuseaddr,fork \
UDP-DATAGRAM:255.255.255.255:68,broadcast
这将会得到客户端的响应,但可能还有很多工作要做。