Я пытаюсь настроить dnsmasq для работы в режиме DHCP-прокси, предоставляя клиентам информацию о загрузке сети PXE, в то время как мой маршрутизатор продолжает действовать как DHCP-сервер.
В идеале я бы хотел запустить dnsmasq в контейнере Docker.
Сначала я попытался настроить его на виртуальной машине VMware под управлением Linux, например:
# 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 и настроил ее на загрузку из сети. После долгого ожидания он начинает настройку через 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 имеет IP-адрес интерфейса контейнера Docker, который не является сетевым IP-адресом хоста, на котором запущен контейнер (который должен быть 172.16.80.2).
dnsmasq отвечает клиенту, используя широковещательный пакет UDP на порту 68, который не выходит за пределы сети Docker с мостом, если только не используется --net=host
.
Одним из обходных путей является добавление прослушивателя socat
в сеть Docker, который перенаправляет на хост:
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
Это даст ответ клиенту, но может быть еще много работы.