Can systemd networkd be configured for netboot, PXE boot, if yes, how?

If I understand this "issue" (systemd-networkd DHCP Server ignores SendOptions #15780), SystemD can be configured to handle network booting. However, I am unable to find more information about that functionality.

I am currently using a DHCPD server with minimal configuration, why it would be nice if it could be moved to systemd-networkd, which handles all other network functionalities in my environment.

# /etc/dhcpd.conf
allow booting; # How is this defined in systemd-networkd?
allow bootp;   # How is this defined in systemd-networkd?

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative; # How is this defined in systemd-networkd?

option architecture code 93 = unsigned integer 16; # I think this corresponds to SendOption=93:uint16:architecture

host client_computer {
  hardware ethernet a1:b2:c3:d4:e5:f6; # This should be captured with [Match] MACAddress=a1:b2:c3:d4:e5:f6

  fixed-address 192.168.1.101; # I think this corresponds to something like SendOption=???:ipv4address:192.168.1.101
  next-server 192.168.1.100; # This should be defines as [Network] Address?

  option host-name "clientname"; # I think this corresponds to something like SendOption=12:string:clientname
  option root-path "/srv/tftp";  # I think this corresponds to something like SendOption=17:string:/srv/tftp

  if option architecture = 00:07 {
    filename "grub/x86_64-efi/core.efi"; # I think this corresponds to SendOption=67:string:grub/x86_64-efi/core.efi
  }
  else {
    filename "grub/i396-pc/core.0"; # I think this corresponds to SendOption=67:string:grub/i396-pc/core.0
  }
}

It seems that I need the "option" codes, but where can I find them? Is there a specification? — Found them 🙂

The SystemD NetworkD documentation.

What I have so far:

#allow booting; = ? # Not necessary?
#allow bootp;   = ? # Not necessary?
#authoritative; = ? # Not necessary?

[Match]
MACAddress=a1:b2:c3:d4:e5:f6

[Network]
DHCP=no
DHCPServer=true

Address=192.168.1.100/24 # DHCP server IP

[DHCPv4]
ClientIdentifier=mac

[DHCPServer]
PoolOffset=3
PoolSize=7

BootServerAddress=192.168.1.100/24

#SendOption=93:uint16:architecture # Failed to parse DHCP uint16 data, ignoring assignment: architecture # Not necessary?

#SendOption=???:ipv4address:192.168.1.101

SendOption=12:string:clientname # 12 "Hostname"

SendOption=17:string:/srv/tftp  # 17 "Root Path"

# BootFilename=grub/i396-pc/core.0 # Sane as code 67
# SendOption=67:string:grub/x86_64-efi/core.efi
SendOption=67:string:grub/i396-pc/core.0

[DHCPServerStaticLease]
MACAddress=a1:b2:c3:d4:e5:f6
Address=192.168.1.101


Update #1

Using tcpdump -i <INTERFACE> -nn -s0 -v -A udp port 67 I can see that SystemD NetworkD DCHP Server is interacting with the client!

However, the system does not boot, and the problem seems to be that the expected static IP address is not assigned to the client.

The [DHCPServerStaticLease] section does not seem to have an effect. I found something about a bug in systemctl --version <= 253 and added the workaround ClientIdentifier=mac. However, it should not be necessary as I am running version 255.

Oh, and I added the Pool* parameters but the DHCP server still assigns the same IP (192.168.1.242).

Asked By: user212827

||

The answer is yes! The following configuration worked for me.

[Match]
Name=<NETWORKD DEVICE NAME>

[Network]
DHCP=yes                        # Required
DHCPServer=true                 # Required

IPForward=yes                   # Required if to pass traffic from client
IPMasquerade=both               # Required if to pass traffic from client

Address=192.168.1.100/24        # Required

#[DHCPv4]                       # Was not necessary
#ClientIdentifier=mac           # Was not necessary

[DHCPServer]

#PoolOffset=100                 # Not necessaary
#PoolSize=1                     # Not necessaary

BootServerAddress=192.168.1.100 # Required

# Hostname=                     # Forgot to test but should be same as code 12
SendOption=12:string:clientname # optional

# 17 "Root Path"
SendOption=17:string:/srv/tftp  # Required

# I do not know how to select between EFI and i386 depending on the client.
# Comment out the one required. EFI worked for me.

# EFI
BootFilename=/srv/tftp/grub/x86_64-efi/core.efi # Required; providing full path but relative path should work? Forgot to test.
#SendOption=67:string:grub/x86_64-efi/core.efi   # Should be the same as BootFilename  

# i386
#SendOption=67:string:grub/i396-pc/core.0
#BootFilename=grub/i396-pc/core.0

[DHCPServerStaticLease]
MACAddress=a1:b2:c3:d4:e5:f6
Address=192.168.1.101

Gotchas

  • Don’t do this when tired 🙂
  • networkctl reload after changing configuration
  • Disable any other non-SystemD DHCP server
  • NetworkD conf files: Don’t comment on same line as assigned value, for example Address=192.168.1.100/24 # My Server
Answered By: user212827