Category: dnsmasq

Building dnsmasq docker-compose file with DHCP enabled

Building dnsmasq docker-compose file with DHCP enabled

Creating Dockerfile

Create Dockerfile as below, the VOLUME /data is pointing to configuration folder

FROM ubuntu:latest

VOLUME /data

RUN apt update
RUN apt install dnsmasq -y
RUN apt install iproute2 -y

CMD dnsmasq -q -d --conf-file=/data/dnsmasq.conf --dhcp-broadcast

Creating docker-compose.yml file

Must add cap_add parameter.

version: '2'

services:
  dnsmasq:
    container_name: dnsmasq
    image: dnsmasq
    build:
      context: .
      dockerfile: Dockerfile.dnsmasq
    restart: unless-stopped
    volumes:
      - /app/dnsmasq/data:/data
    networks:
      - my_macvlan_250
    cap_add:
      - NET_ADMIN

networks:
  my_macvlan_250:
    external: true

This is the same as below command

docker run --cap-add=NET_ADMIN --name dnsmasq -d -it --restart unless-stopped -v /app/dnsmasq/data:/data --network my_macvlan_250 dnsmasq

References

Setup dnsmasq for DNS, DHCP and TFTP

Setup dnsmasq for DNS, DHCP and TFTP

To setup DNS, DHCP and TFTP server using dnsmasq, need to consider them separately.

Environment

To ease of setup and backup, consider use docker container to run dnsmasq.

Configure macvlan

As DHCP server requires special network communication, macvlan can be used for this purpose.

Create macvlan on interface bond0 with IP address 192.168.1.250

docker network create -d macvlan -o parent=eth0 --subnet=192.168.1.0/24 --gateway=192.168.1.254 --ip-range=192.168.1.250/32 my_macvlan_250

Configure bridge macvlan

By default, the host machine who configured macvlan communicates with macvlan container, in such case, the DNS server running in dnsmasq will not be accessable by host machine.

In order to allow host machine also use DNS service running in macvlan, following configuration needs to be done, which creates another macvlan in host as bridge mode with IP address 192.168.1.249, and use it to access macvlan in docker with IP address 192.168.1.250.

Add following lines in /etc/network/interfaces

up ip link add my_macvlan_249 link eth0 type macvlan mode bridge
up ip addr add 192.168.1.249/32 dev my_macvlan_249
up ip link set my_macvlan_249 up
up ip route add 192.168.1.250/32 dev my_macvlan_249

Untested setup

Other setup likes using normal bridge network interface on physical network interface, I have tried it, so maybe it is also working.

Start container

Start container and map container /data folder to /app/dnsmasq/data, which can be used to save configuration files

docker run --name dnsmasq -d -it --restart unless-stopped -v /app/dnsmasq/data:/data --network my_macvlan_250 dnsmasq

Above command will run following command in container

dnsmasq -q -d --conf-file=/data/dnsmasq.conf --dhcp-broadcast

Troubleshooting dnsmasq

In order to debug dnsmasq, following command can be used.

docker logs -f dnsmasq

Due to so many requests on DNS from everywhere, if only want to debug DHCP service, following command can be used, and it filter out lines start with dnsmasq: .

docker logs -f dnsmasq --since 1m | grep -v -e "^dnsmasq: "

The DHCP log messages start with dnsmasq-dhcp: .

docker logs -f dnsmasq --since 1m | grep -e "^dnsmasq-dhcp: "

Note: As suggested in configuration, comment log-queries should disable logs for DNS too, but looks like useless.

#log-queries
log-dhcp

Configure TFTP boot

Configure TFTP server

Enable TFTP server

enable-tftp
tftp-root=/data/tftp

Configure DHCP boot

Sample configuration to select boot file according to option client-arch

dhcp-match=set:efi-x86_64,option:client-arch,7
dhcp-match=set:efi-x86_64,option:client-arch,9
dhcp-match=set:efi-x86,option:client-arch,6
dhcp-match=set:bios,option:client-arch,0
dhcp-boot=tag:efi-x86_64,efi64/syslinux.efi
dhcp-boot=tag:efi-x86,efi32/syslinux.efi
dhcp-boot=tag:bios,bios/lpxelinux.0

Actual configuration

dhcp-match=set:efi-x86_64,option:client-arch,7
dhcp-boot=tag:efi-x86_64,ipxe.efi
#dhcp-boot=tag:efi-x86_64,grubx64.efi

Set tag for iPXEBOOT, and configure ipxe options

# set tag to IPXEBOOT when has option 175
dhcp-match=IPXEBOOT,175
#dhcp-match=set:ipxe,175 # iPXE sends a 175 option.

dhcp-boot=tag:!IPXEBOOT,undionly.kpxe,dnsmasq,192.168.1.250
dhcp-boot=tag:IPXEBOOT,boot.ipxe,dnsmasq,192.168.1.250

# Configure iSCSI for ipxe boot
#dhcp-option=175,8:1:1
#dhcp-option=tag:IPXEBOOT,17,"iscsi:192.168.1.17::::iqn.2012-12.net.bx:ds1812.pxe-ubuntu"
#dhcp-option-force=vendor:175, 190, user
#dhcp-option-force=vendor:175, 191, password

Configure DHCP

DHCP global configuration, and set host using files in /data/hosts folder, and dhcp-host using files in /data/ethers folder.

no-hosts
hostsdir=/data/hosts
#addn-hosts=/data/banner_add_hosts
dhcp-hostsdir=/data/ethers
dhcp-leasefile=/data/dnsmasq.leases
expand-hosts
dhcp-option=44,192.168.1.250 # set netbios-over-TCP/IP nameserver(s) aka WINS server(s)
#dhcp-option=option:domain-search,bx.net,bianxi.com

DHCP Domain and rang

Following lines set up for dhcp hosts which are tagged as home

domain=bx.net,192.168.1.0/24
dhcp-range=tag:home,192.168.1.96,192.168.1.127,255.255.255.0,12h
dhcp-option=tag:home,option:router,192.168.1.254

DHCP mapping

To map MAC address to IP, tag, etc., use dhcp-host. Sample of mapping are shown below

dhcp-host=00:1b:77:07:08:af,set:home
dhcp-host=00:26:4a:18:82:c6,192.168.1.9,set:home
dhcp-host=win10,192.168.1.235,set:home

Note: contents in dhcp-host file, such as /etc/ethers should not have prefix of dhcp-host= as in main configuration file dnsmasq.conf does.

00:1b:77:07:08:af,set:home
00:26:4a:18:82:c6,192.168.1.9,set:guest
win10,192.168.1.235,set:home

DHCP reject unknown hosts

Using following configuration line to ignore all unknown hosts, so all hosts much registered using dhcp-host option.

dhcp-ignore=tag:!known

Guest domain

Another way to deal with unknown hosts is to setup guest network.

Following lines define a DHCP services for hosts without tag home

dhcp-range=tag:!home,192.168.1.128,192.168.1.143,255.255.255.0,4h
dhcp-option=tag:!home,option:router,192.168.1.254
dhcp-option=tag:!home,option:domain-name,guest.net
#dhcp-option=tag:!home,option:domain-search,guest.net

Another way is to define guest network range as below for those hosts with tag guest.

#domain=guest.net,192.168.1.0/24
#dhcp-range=tag:guest,192.168.1.128,192.168.1.143,255.255.255.0,4h
#dhcp-option=tag:guest,option:router,192.168.1.254

#dhcp-host=00:a0:98:5f:9e:81,set:guest

DHCP mapping consideration

The logic of DHCP tags is described below

  • Host request DHCP, then it has one tag, which is interface name, such as eth0

  • If it is mapped with one dhcp-host line, they will be tagged as known

  • Tags can be given by various ways

    • Set in dhcp-host line. For example, set guest in following line
    dhcp-host=00:a0:98:5f:9e:81,set:guest
    • Set by IP range
    dhcp-range=set:red,192.168.0.50,192.168.0.150
    • Set by host matching
    dhcp-vendorclass=set:red,Linux
    dhcp-userclass=set:red,accounts
    dhcp-mac=set:red,00:60:8C:*:*:*
  • Tags can be used by various ways

    • Used in IP range
    dhcp-range=tag:green,192.168.0.50,192.168.0.150,12h
  • Tags can be used in not condition

    dhcp-option=tag:!home,option:router,192.168.1.254

DHCP options

DHCP options and their numbers, can be found in DHCP log, such as below.

dnsmasq-dhcp: 2177430021 available DHCP range: 192.168.1.96 -- 192.168.1.127
dnsmasq-dhcp: 2177430021 available DHCP range: 192.168.1.128 -- 192.168.1.143
dnsmasq-dhcp: 2177430021 vendor class: MSFT 5.0
dnsmasq-dhcp: 2177430021 client provides name: baidu-windows
dnsmasq-dhcp: 2177430021 DHCPREQUEST(eth0) 192.168.1.113 00:a0:98:1d:b0:fc 
dnsmasq-dhcp: 2177430021 tags: home, known, eth0
dnsmasq-dhcp: 2177430021 DHCPACK(eth0) 192.168.1.113 00:a0:98:1d:b0:fc baidu-windows
dnsmasq-dhcp: 2177430021 requested options: 1:netmask, 3:router, 6:dns-server, 15:domain-name, 
dnsmasq-dhcp: 2177430021 requested options: 31:router-discovery, 33:static-route, 43:vendor-encap, 
dnsmasq-dhcp: 2177430021 requested options: 44:netbios-ns, 46:netbios-nodetype, 47:netbios-scope, 
dnsmasq-dhcp: 2177430021 requested options: 119:domain-search, 121:classless-static-route, 
dnsmasq-dhcp: 2177430021 requested options: 249, 252
dnsmasq-dhcp: 2177430021 bootfile name: undionly.kpxe
dnsmasq-dhcp: 2177430021 server name: dnsmasq
dnsmasq-dhcp: 2177430021 next server: 192.168.1.250
dnsmasq-dhcp: 2177430021 broadcast response
dnsmasq-dhcp: 2177430021 sent size:  1 option: 53 message-type  5
dnsmasq-dhcp: 2177430021 sent size:  4 option: 54 server-identifier  192.168.1.250
dnsmasq-dhcp: 2177430021 sent size:  4 option: 51 lease-time  12h
dnsmasq-dhcp: 2177430021 sent size:  4 option: 58 T1  6h
dnsmasq-dhcp: 2177430021 sent size:  4 option: 59 T2  10h30m
dnsmasq-dhcp: 2177430021 sent size:  4 option:  1 netmask  255.255.255.0
dnsmasq-dhcp: 2177430021 sent size:  4 option: 28 broadcast  192.168.1.255
dnsmasq-dhcp: 2177430021 sent size:  6 option: 15 domain-name  bx.net
dnsmasq-dhcp: 2177430021 sent size: 23 option: 81 FQDN  03:ff:ff:62:61:69:64:75:2d:77:69:6e:64:6f...
dnsmasq-dhcp: 2177430021 sent size:  4 option:  6 dns-server  192.168.1.250
dnsmasq-dhcp: 2177430021 sent size:  4 option:  3 router  192.168.1.254
dnsmasq-dhcp: 2177430021 sent size:  4 option: 44 netbios-ns  192.168.1.250

Configure DNS

Set up link DNS server

# DNS Server
server=165.21.83.88
#server=165.21.100.88
server=8.8.8.8

DNS mapping

DNS entries are defined as the format of /etc/host file

192.168.1.1     host1 host-alias

Sample configuration steps

Add a static IP entry for a known mac address

In ethers file, add following entry for DHCP

44:55:66:77:88:99,192.168.1.222,set:home

In banner_add_hosts file add following entry for DNS

192.168.1.222    cat