Skip to content

WIP: Feature/smb pxe dhcp static - #2

Merged
phaus merged 22 commits into
mainfrom
feature/smb-pxe-dhcp-static
Aug 1, 2026
Merged

WIP: Feature/smb pxe dhcp static#2
phaus merged 22 commits into
mainfrom
feature/smb-pxe-dhcp-static

Conversation

@phaus

@phaus phaus commented Jul 30, 2026

Copy link
Copy Markdown
Member

Add portable SMB server option, fix SMB bugs, hostapd ctrl path fix

SMB: portable-smb-server support

  • New usePortableServer config flag selects fiddyschmitt/portable-smb-server instead of Samba smbd
  • Start() dispatches to startPortable() or startSamba() based on config or binary name
  • New AddUser() method for extras-driven additional SMB users (Samba mode only)

SMB: bug fixes

  • isSamba never setstartSamba() didn't set s.isSamba = true, causing AddUser() to always fail with "only supported in Samba mode"
  • extras.SMBUsers not applied — TOML extras file parsed [[smbUsers]] but the list was never used. Now hoisted extras var scope and iterated after SMB start
  • createUser refactored — uses SMB_CONF_PATH env var instead of deriving smbpasswd path from smbd bin dir; simplified add/update logic

SMB: unit tests

  • Template rendering (with/without interfaces param, custom share names)
  • AddUser guard rejects portable mode
  • New constructor baseline check

Hostapd ctrl path

  • Moved ctrl_interface from /var/run/hostapd to /tmp/hostapd/var/run may not be writable in gokrazy's minimal rootfs
  • Added MkdirAll before hostapd launch to ensure directory exists

phaus added 9 commits July 29, 2026 15:35
Add optional disk mount with TOML extras reloading, SMB server wrapper,
PXE/TFTP boot server, static DHCP reservations and per-MAC images.
Update README/spec docs and gitignore build artifacts.
Remove prebuilt gokrazy-router binaries from index.
Add unit tests for config ExpandEnv, LoadExtras, ApplyExtras and

DHCP SetReservations/SetPXEOptions. Also cover MAC normalization.
…sers

- Add UsePortableServer config + startPortable/startSamba split
- Fix isSamba never set true in startSamba (broke AddUser)
- Hoist extras scope in main, apply extras.SMBUsers after SMB start
- Add SMB unit tests (template, AddUser guard, New)
- Move hostapd ctrl_interface /var/run -> /tmp (gokrazy compat)
- MkdirAll ctrl dir before hostapd launch
Document PXE (TFTP) and HTTP boot server design, per-VLAN netboot
configuration, DHCP PXE option injection for legacy/iPXE/UEFI clients,
and static IP reservation + per-client netboot image selection via the
MAC mapping file.
Document where each configuration file is placed on the router
(/etc/gokrazy-router.json, macmap TOML, /data/netboot/). Add netboot/
directory with example router config, MAC map, iPXE script, and
pxelinux config.
Remove accidentally committed ELF binaries (gokrazy-router,
gokrazy-router-status). Update .gitignore to cover all build
artifacts. Add cross-compile examples for ARMv7 and amd64 to README.
Both architectures build cleanly.
Cherry-picked 4 commits from feature/netboot:
- a4529b6 - Add netboot service and MAC-to-IP mapping to spec and README
- 3c233c2 - Add config file location docs and netboot example configs
- 472faf9 - Remove binaries, document amd64 build support
- 1d79863 - Add amd64 to CI build matrix

Rename CLI gokrazy-router-status -> router-cli (not grcli).

Bug fix: isSamba flag, extras SMBUsers application, hostapd ctrl path
@phaus phaus closed this Jul 30, 2026
@phaus phaus reopened this Jul 30, 2026
phaus added 3 commits July 30, 2026 11:39
Add 'router-cli extras' subcommand to manage DHCP reservations and
PXE boot image mappings stored in the extras TOML file on SMB share.

- ExtrasConfig: Add Encode/Save/SetReservation/RemoveReservation/
  SetMacImage/RemoveMacImage methods + ErrNotModified sentinel
- CLI: Refactor to subcommand pattern (status, extras)
- CLI extras: list, set-reservation, remove-reservation,
  set-mac-image, remove-mac-image with --file path
- Tests: 6 new tests for extras CRUD and save/load round-trip
7 tests covering list, set-reservation, remove-reservation,
set-mac-image, remove-mac-image, and bad-arg handling.
Move DHCP option 67 bootfile and PXE default image into the
disk-based extras TOML. ApplyExtras now propagates these to
all VLAN/WiFi DHCP configs and PXE config.
@phaus phaus changed the title Feature/smb pxe dhcp static WIP: Feature/smb pxe dhcp static Jul 30, 2026
phaus added 10 commits July 30, 2026 23:15
… scoped reservations

- Add /api/reload to re-apply extras (reservations, PXE images, SMB users) without reboot

- Support per-MAC DHCP option 67 bootfiles for legacy/UEFI PXE

- Replace pin/tftp with a minimal SO_BINDTODEVICE-aware TFTP server for VLAN PXE

- Scope DHCP reservations per subnet so VLAN entries do not leak across servers

- Add VLAN address overrides in extras file
…er-class

- Add per-MAC override, legacy/UEFI/iPXE bootfiles

- Use DHCP option 77 (User Class) to detect iPXE and serve boot.ipxe

- Use DHCP option 93 (Client System Architecture) for legacy vs UEFI

- Defaults: undionly.kpxe (legacy), netboot.xyz.efi (UEFI), boot.ipxe (iPXE)
Differentiate clients by DHCP option 77 (iPXE) and option 93 (UEFI).

Add netboot.xyz chain script and runtime extras example. Update

README/spec to current services.pxe config.
…e detection

iPXE/UEFI detection previously overrode per-MAC option 67 bootfiles, so a
client configured with its own bootfile (e.g. netboot.xyz.kpxe) got the
generic ipxe/uefi/legacy default at the iPXE stage. Resolve bootfile in
order: MAC override > iPXE > UEFI > legacy.
The DefaultImage fallback redirected every TFTP RRQ to the default binary
(e.g. undionly.kpxe), so an iPXE text script requested as boot.ipxe was
served as the iPXE binary (72159 bytes), chainloading a second iPXE
instance. Plain filenames are now served literally; the default image
applies only to MAC-named requests (01-xx-xx-xx-xx-xx) without a mapping.

Also drop noisy TFTP ACK debug logging.
- boot.ipxe chains to the local netboot.xyz.ipxe via tftp://${next-server}
  with an iPXE shell fallback instead of loading a kernel directly
- netboot.xyz.ipxe uses boot.netboot.xyz/menu.ipxe; the old
  ipxe/netboot.xyz.ipxe path returns 404. HTTP is tried first because the
  legacy undionly.kpxe build lacks HTTPS support
- router-extras.toml reflects the deployed T410i setup (undionly.kpxe
  defaults, boot.ipxe as iPXE script, static reservation for the T410i)
- loadOrCreateExtras: create minimal extras from JSON config when file
  missing, at startup and on /api/reload (dedupes reload handler)
- dhcp: iPXE user-class precedence above per-MAC bootfile; only T410i
  (legacy MAC) gets the iPXE chain, all others default to UEFI
  netboot.xyz.efi
- docs: router-extras.toml key table, PXE boot-file precedence and a
  multi-interface example (VLAN 1/20/31 + WiFi reservations, per-MAC
  images, SMB users)
- docs: fix dead netboot.xyz chain URL (menu.ipxe), HTTP-first script;
  deployment fetches undionly.kpxe to match shipped extras
TFTP requests could read arbitrary router files via .. traversal,
absolute paths or escaping symlinks. Serve strictly inside the TFTP
root and validate every resolved image path (macImages/defaultImage
included) against it.

Each transfer now runs on a dedicated ephemeral UDP socket (RFC 1350
transfer ID) with ACKs validated against the full client IP:port,
isolating concurrent transfers from the same or relayed clients.

Reload fixes:
- ApplyExtras replaces PXE overrides instead of merging, so values
  removed from the extras TOML disappear at runtime (incl. clearing
  defaultImage)
- SetDefaultImage and SetMacPXEBootFiles apply unconditionally
- handler maps guarded by RWMutex; reload no longer races transfer
  goroutines

Do not auto-bind the TFTP socket to the last VLAN bridge; an unbound
listener serves every scope that advertises option 66/67.

Align docs with iPXE-first boot-file precedence; add jail, transfer,
duplicate-RRQ, reload-race and precedence-table tests. go mod tidy
drops the unused pin/tftp dependency.
…ning

Reload (/api/reload) no longer mutates live network state: it is serialized under a mutex, and changes that cannot be applied at runtime ([vlanAddresses], [[smbUsers]]) are rejected with HTTP 409 instead of being half-applied.

The admin API now binds to 127.0.0.1:8080 by default and requires a Bearer token for POST /api/reload unless allowUnauthenticatedReload is set.

SMB extras users are now granted share access: ValidUsers is rendered from primary + extras users before Samba starts, and smbpasswd runs for each user; portable mode rejects extras.

TFTP jail uses openat/O_NOFOLLOW per path component to close the TOCTOU symlink-swap gap, and the final DATA block is now ACKed with bounded retransmit. DHCP pool exhaustion returns nil allocation instead of duplicating a reserved/leased address.
Add global dns field to Config struct as fallback for DHCP scopes.
Add DNS to ExtrasConfig for runtime override via router-extras.toml.
Apply global DNS to VLAN, WiFi, LAN scopes that lack per-scope config.

New files:
- netboot/download-boot-files.sh: idempotent boot binary download

Updated templates:
- gokrazy-router.json: add DNS, VLAN 31, updated paths
- router-extras.toml: add DNS entry, MAC reservation
- macmap.toml: example entry placeholder
@phaus
phaus merged commit ff65b7c into main Aug 1, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant