From f650c894b01399a5e4fb29591050dcd55681079a Mon Sep 17 00:00:00 2001 From: Bourne-ID Date: Sun, 17 Jul 2022 14:39:02 -0400 Subject: [PATCH] refactor(pxe)!: combine dhcpd and tftpd to dnsmasq (#69) * Add DNSMasq as an opt-in option * Default to original * Remove commented commands * Remove dhcpd, replaced with dnsmasq * Remove dhcpd, replaced with dnsmasq * Move to dnsmasq * dnsmasq output to stdout * dnsmasq * dnsmasq * Remove unused code, update tag * Correct title Co-authored-by: Khue Doan * Remove TFTP Co-authored-by: Khue Doan * rename to Dnsmasq Moving to use proxy by default Co-authored-by: Khue Doan * Rename for consistency Co-authored-by: Khue Doan * Correct terminology Co-authored-by: Khue Doan * formatting Co-authored-by: Khue Doan * Additional logging * proxy-by-default * naming consistency * naming consistency * Revert Dnsmasq proxy ask * proxy enabled by default * naming consistency * naming consistency * Formatting Co-authored-by: Robin Bourne Co-authored-by: Khue Doan --- docs/runbooks/dnsmasq.md | 10 +++++++ docs/troubleshooting.md | 4 +-- metal/roles/pxe_server/defaults/main.yml | 1 + metal/roles/pxe_server/files/dhcp/Dockerfile | 7 ----- .../roles/pxe_server/files/dnsmasq/Dockerfile | 5 ++++ .../roles/pxe_server/files/docker-compose.yml | 20 +++++++------- metal/roles/pxe_server/files/tftp/Dockerfile | 7 ----- metal/roles/pxe_server/tasks/main.yml | 6 ++--- .../roles/pxe_server/templates/dhcpd.conf.j2 | 20 -------------- .../pxe_server/templates/dnsmasq.conf.j2 | 26 +++++++++++++++++++ 10 files changed, 56 insertions(+), 50 deletions(-) create mode 100644 docs/runbooks/dnsmasq.md delete mode 100644 metal/roles/pxe_server/files/dhcp/Dockerfile create mode 100644 metal/roles/pxe_server/files/dnsmasq/Dockerfile delete mode 100644 metal/roles/pxe_server/files/tftp/Dockerfile delete mode 100644 metal/roles/pxe_server/templates/dhcpd.conf.j2 create mode 100644 metal/roles/pxe_server/templates/dnsmasq.conf.j2 diff --git a/docs/runbooks/dnsmasq.md b/docs/runbooks/dnsmasq.md new file mode 100644 index 00000000..4e1a72d6 --- /dev/null +++ b/docs/runbooks/dnsmasq.md @@ -0,0 +1,10 @@ +# Dnsmasq + +## Overview +Dnsmasq is used as either a DHCP server or DHCP proxy server for PXE metal provisioning. + +Proxy mode is enabled by default allowing the use of existing DHCP servers on the network. A good description on how DHCP Proxy works can be found on the related [FOG project wiki page](https://wiki.fogproject.org/wiki/index.php?title=ProxyDHCP_with_dnsmasq) + +## Disabling Proxy Mode + +Certain scenarios will require this project to use a DHCP server, such as an air-gap deployment or dedicated VLAN. To disable proxy mode thereby using dnsmasq as a DHCP server, modify `metal/roles/pxe_server/defaults/main.yml` and set `dhcp_proxy` to `false` diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 3c19b3e7..ff66cf7d 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -13,8 +13,8 @@ To view PXE server (includes DHCP, TFTP and HTTP server) logs: You can view the logs of one or more containers selectively, for example: ```sh - ./scripts/pxe-logs dhcp - ./scripts/pxe-logs tftp http + ./scripts/pxe-logs dnsmasq + ./scripts/pxe-logs http ``` ## Nodes not booting from the network diff --git a/metal/roles/pxe_server/defaults/main.yml b/metal/roles/pxe_server/defaults/main.yml index 9c236419..280e0401 100644 --- a/metal/roles/pxe_server/defaults/main.yml +++ b/metal/roles/pxe_server/defaults/main.yml @@ -1,3 +1,4 @@ iso_url: "https://download.rockylinux.org/pub/rocky/8.6/isos/x86_64/Rocky-8.6-x86_64-minimal.iso" iso_checksum: "sha256:a9ece0e810275e881abfd66bb0e59ac05d567a5ec0bc2f108b9a3e90bef5bf94" timezone: Asia/Ho_Chi_Minh +dhcp_proxy: true diff --git a/metal/roles/pxe_server/files/dhcp/Dockerfile b/metal/roles/pxe_server/files/dhcp/Dockerfile deleted file mode 100644 index b6405ee3..00000000 --- a/metal/roles/pxe_server/files/dhcp/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM alpine:20220316 - -RUN apk add dhcp - -RUN touch /var/lib/dhcp/dhcpd.leases - -CMD [ "dhcpd", "-d", "-f", "-cf", "/etc/dhcp/dhcpd.conf" ] diff --git a/metal/roles/pxe_server/files/dnsmasq/Dockerfile b/metal/roles/pxe_server/files/dnsmasq/Dockerfile new file mode 100644 index 00000000..21ad9b62 --- /dev/null +++ b/metal/roles/pxe_server/files/dnsmasq/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine:3.11 + +RUN apk --no-cache add dnsmasq + +ENTRYPOINT ["dnsmasq", "-k"] diff --git a/metal/roles/pxe_server/files/docker-compose.yml b/metal/roles/pxe_server/files/docker-compose.yml index c8814857..1ce9e677 100644 --- a/metal/roles/pxe_server/files/docker-compose.yml +++ b/metal/roles/pxe_server/files/docker-compose.yml @@ -1,19 +1,17 @@ version: "3" services: - dhcp: - build: ./dhcp + dnsmasq: + build: ./dnsmasq volumes: - - ./data/pxe-config/dhcpd.conf:/etc/dhcp/dhcpd.conf + - ./data/pxe-config/dnsmasq.conf:/etc/dnsmasq.conf + - ./data/pxe-config/grub.cfg:/tftp/grub.cfg + - ./data/os/EFI/BOOT/grubx64.efi:/tftp/grubx64.efi + - ./data/os/images/pxeboot/initrd.img:/tftp/initrd.img + - ./data/os/images/pxeboot/vmlinuz:/tftp/vmlinuz network_mode: host - tftp: - build: ./tftp - network_mode: host - volumes: - - ./data/pxe-config/grub.cfg:/var/lib/tftpboot/grub.cfg - - ./data/os/EFI/BOOT/grubx64.efi:/var/lib/tftpboot/grubx64.efi - - ./data/os/images/pxeboot/initrd.img:/var/lib/tftpboot/initrd.img - - ./data/os/images/pxeboot/vmlinuz:/var/lib/tftpboot/vmlinuz + cap_add: + - NET_ADMIN http: build: ./http network_mode: host diff --git a/metal/roles/pxe_server/files/tftp/Dockerfile b/metal/roles/pxe_server/files/tftp/Dockerfile deleted file mode 100644 index ada70c71..00000000 --- a/metal/roles/pxe_server/files/tftp/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM alpine:20220316 - -RUN apk add busybox tftp-hpa - -ENTRYPOINT [ "/bin/sh", "-c" ] - -CMD [ "busybox syslogd -n -O /dev/stdout & in.tftpd -vvv --foreground --secure /var/lib/tftpboot" ] diff --git a/metal/roles/pxe_server/tasks/main.yml b/metal/roles/pxe_server/tasks/main.yml index ddebbafa..e4d59cba 100644 --- a/metal/roles/pxe_server/tasks/main.yml +++ b/metal/roles/pxe_server/tasks/main.yml @@ -11,10 +11,10 @@ cmd: "xorriso -osirrox on -indev {{ iso.dest }} -extract / {{ role_path }}/files/data/os" creates: "{{ role_path }}/files/data/os/.treeinfo" -- name: Generate DHCP config +- name: Generate dnsmasq config ansible.builtin.template: - src: dhcpd.conf.j2 - dest: "{{ role_path }}/files/data/pxe-config/dhcpd.conf" + src: dnsmasq.conf.j2 + dest: "{{ role_path }}/files/data/pxe-config/dnsmasq.conf" mode: 0644 - name: Generate GRUB config diff --git a/metal/roles/pxe_server/templates/dhcpd.conf.j2 b/metal/roles/pxe_server/templates/dhcpd.conf.j2 deleted file mode 100644 index ae5ded00..00000000 --- a/metal/roles/pxe_server/templates/dhcpd.conf.j2 +++ /dev/null @@ -1,20 +0,0 @@ -option space pxelinux; -option pxelinux.magic code 208 = string; -option pxelinux.configfile code 209 = text; -option pxelinux.pathprefix code 210 = text; -option pxelinux.reboottime code 211 = unsigned integer 32; -option architecture-type code 93 = unsigned integer 16; - -subnet {{ ansible_default_ipv4.network }} netmask {{ ansible_default_ipv4.netmask }} { - option routers {{ ansible_default_ipv4.gateway }}; - range {{ ansible_default_ipv4.network | ansible.netcommon.ipmath(1) }} {{ ansible_default_ipv4.broadcast | ansible.netcommon.ipmath(-1) }}; - - class "pxeclients" { - match if substring (option vendor-class-identifier, 0, 9) = "PXEClient"; - next-server {{ ansible_default_ipv4.address }}; - - if option architecture-type = 00:07 { - filename "grubx64.efi"; - } - } -} diff --git a/metal/roles/pxe_server/templates/dnsmasq.conf.j2 b/metal/roles/pxe_server/templates/dnsmasq.conf.j2 new file mode 100644 index 00000000..a0dea61c --- /dev/null +++ b/metal/roles/pxe_server/templates/dnsmasq.conf.j2 @@ -0,0 +1,26 @@ +# Disable DNS Server. +port=0 +{% if dhcp_proxy == true %} +# We're DHCP proxying on the network of the homelab host +dhcp-range={{ ansible_default_ipv4.address }},proxy +pxe-service=X86-64_EFI, "Boot From Network, (UEFI)", grubx64.efi +{% else %} +# We're DHCP configuring on this range +dhcp-range={{ ansible_default_ipv4.network | ansible.netcommon.ipmath(1) }},{{ ansible_default_ipv4.broadcast | ansible.netcommon.ipmath(-1) }},{{ ansible_default_ipv4.netmask }},12h +dhcp-option=3,{{ ansible_default_ipv4.gateway }} + +# Match Arch Types efi x86 and x64 +dhcp-match=set:efi-x86_64,option:client-arch,7 +dhcp-match=set:efi-x86_64,option:client-arch,9 + +# Set the Boot file based on the tag from above +dhcp-boot=tag:efi-x86_64,grubx64.efi +{% endif %} +# Log DHCP queries to stdout +log-queries +log-dhcp +log-facility=- + +# Enable TFTP server +enable-tftp +tftp-root=/tftp