Modern network boot server.




Modern network boot server.

hydrun CI Docker CI Go Reference Matrix


bofied is a network boot server. It provides everything you need to PXE boot a node, from a (proxy)DHCP server for PXE service to a TFTP and HTTP server to serve boot files.

It enables you to ...

  • Boot nodes from the network: Using (proxy)DHCP for PXE service, it can configure nodes which are set to network boot
  • Serve boot files: The integrated TFTP and HTTP servers can provide the iPXE network bootloader, Linux distros or other boot files
  • Easily manage and script the network boot config: By using the browser or WebDAV, boot files can be managed and the scriptable configuration can be edited
  • Monitor network boot: By monitoring it's (proxy)DHCP and TFTP traffic, bofied can give an insight to the network boot process using a browser or the gRPC API
  • Remotely provision nodes: Because bofied is based on open web technologies and supports OpenID Connect authentication, it can be securely exposed to the public internet and be used to manage network boot in a offsite location



You can get the Docker container like so:

$ docker pull pojntfx/bofied-backend


If you prefer a native installation, static binaries are also available on GitHub releases.

You can install them like so:

$ curl -L -o /tmp/bofied-backend$(uname -m)
$ sudo install /tmp/bofied-backend /usr/local/bin
$ sudo setcap cap_net_bind_service+ep /usr/local/bin/bofied-backend # This allows rootless execution

About the Frontend

The frontend is also available on GitHub releases in the form of a static .tar.gz archive; to deploy it, simply upload it to a CDN or copy it to a web server. For most users, this shouldn't be necessary though; thanks to @maxence-charriere's go-app package, bofied is a progressive web app. By simply visiting the public deployment once, it will be available for offline use whenever you need it:


1. Setting up Authentication

bofied uses OpenID Connect for authentication, which means you can use almost any authentication provider, both self-hosted and as a service, that you want to. We've created a short tutorial video which shows how to set up Auth0 for this purpose, but feel free to use something like Ory if you prefer a self-hosted solution:

Setting up OpenID Connect for Internal Apps YouTube Video

2. Verifying Port Availability

First, verify that ports 67/udp, 4011/udp, 69/udp, 15256/tcp and 15257/tcp aren't in use by another app:

$ ss -tlnp | grep -E -- ':(15256|15257)'
$ ss -ulnp | grep -E -- ':(67|4011|69)'

Neither of these two commands should return anything; if they do, kill the process that listens on the port.

3. Getting the Advertised IP

bofied integrates a (proxy)DHCP server, which advertises the IP address of the integrated TFTP server. To do so, you'll have to find out the IP of the node which is running bofied; you can find it with ip a:

$ ip -4 a
# ...
2: enp0s13f0u1u3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    inet brd scope global dynamic noprefixroute enp0s13f0u1u3
       valid_lft 862274sec preferred_lft 862274sec
# ...

In the following, we'll assume that is the IP address of this node.

4 (Option 1): Starting the Backend (Containerized)

Using Docker (or an alternative like Podman), you can now easily start & configure the backend; see the Reference for more configuration parameters:

Expand containerized installation instructions

Run the following:

$ docker run \
    --name bofied-backend \
    -d \
    --restart always \
    --cap-add NET_BIND_SERVICE \
    -p 67:67/udp \
    -p 4011:4011/udp \
    -p 69:69/udp \
    -p 15256:15256/tcp \
    -p 15257:15257/tcp \
    -v ${HOME}/.local/share/bofied:/root/.local/share/bofied:z \
    -e BOFIED_BACKEND_OIDCCLIENTID=myoidcclientid \

The logs are available like so:

$ docker logs bofied-backend

4 (Option 2): Starting the Backend (Natively)

If you prefer a native setup, a non-containerized installation is also possible.

Expand native installation instructions

First, set up a config file at ~/.local/share/bofied/etc/bofied/bofied-backend-config.yaml; see the Reference for more configuration parameters:

$ mkdir -p ~/.local/share/bofied/etc/bofied/
$ cat <<EOT >~/.local/share/bofied/etc/bofied/bofied-backend-config.yaml
oidcClientID: myoidcclientid

Now, create a systemd service for it:

$ mkdir -p ~/.config/systemd/user/
$ cat <<EOT >~/.config/systemd/user/bofied-backend.service

ExecStart=/usr/local/bin/bofied-backend -c \${HOME}/.local/share/bofied/etc/bofied/bofied-backend-config.yaml


Finally, reload systemd and enable the service:

$ systemctl --user daemon-reload
$ systemctl --user enable --now bofied-backend

You can get the logs like so:

$ journalctl --user -u bofied-backend

5. Setting up the Firewall

You might also have to open up the ports on your firewall:

$ for port in 67/udp 4011/udp 69/udp 15256/tcp 15257/tcp; do sudo firewall-cmd --permanent --add-port=${port}; done

6. Connecting the Frontend

Now that the backend is running, head over to

Alternatively, as described in About the Frontend, you can also choose to self-host. Once you're on the page, you should be presented with the following setup page:

Setup page

You'll have to enter your own information here; the Backend URL is the URL on which the backend (http://localhost:15256/ by default) runs, the OIDC Issuer, Client ID and Redirect URL are the same values that you've set the backend up with above.

Finally, click on Login, and if everything worked out fine you should be presented with the initial launch screen:

Initial page

🚀 That's it! We hope you enjoy using bofied.


Click on an image to see a larger version.

Screenshot of syntax validation Screenshot of monitoring Screenshot 2 of file operations Screenshot 3 of file operations Screenshot of sharing Screenshot of the text editor Screenshot of about modal


Command Line Arguments

$ bofied-backend --help
bofied is a network boot server. It provides everything you need to PXE boot a node, from a (proxy)DHCP server for PXE service to a TFTP and HTTP server to serve boot files.

For more information, please visit

  bofied-backend [flags]

      --advertisedIP string                IP to advertise for DHCP clients (default "")
  -c, --configFile string                  Config file to use
      --dhcpListenAddress string           Listen address for DHCP server (default ":67")
      --extendedHTTPListenAddress string   Listen address for WebDAV, HTTP and gRPC-Web server (default ":15256")
      --grpcListenAddress string           Listen address for gRPC server (default ":15257")
  -h, --help                               help for bofied-backend
  -t, --oidcClientID string                OIDC client ID (default "myoidcclientid")
  -i, --oidcIssuer string                  OIDC issuer (default "")
      --proxyDHCPListenAddress string      Listen address for proxyDHCP server (default ":4011")
  -p, --pureConfig Configuration           Prevent usage of stdlib in configuration file, even if enabled in Configuration function
  -s, --skipStarterDownload                Don't initialize by downloading the starter on the first run
      --starterURL string                  Download URL to a starter .tar.gz archive; the default chainloads (default "")
      --tftpListenAddress string           Listen address for TFTP server (default ":69")
  -d, --workingDir string                  Working directory (default "/home/pojntfx/.local/share/bofied/var/lib/bofied")

Environment Variables

All command line arguments described above can also be set using environment variables; for example, to set --advertisedIP to with an environment variable, use BOFIED_BACKEND_ADVERTISEDIP=

Configuration File

Just like with the environment variables, bofied can also be configured using a configuration file; see examples/bofied-backend-config.yaml for an example configuration file.

Config Script

The config script is separate from the config file and is used to dynamically decide which file to send to which node based on it's IP address, MAC address and processor architecture. It can be set & validated using either the frontend or WebDAV. The default config script, which is fetched from pojntfx/ipxe-binaries, returns a matching executable based on the architecture:

package config

func Filename(
	ip string,
	macAddress string,
	arch string,
	archID int,
) string {
	switch arch {
	case "x86 BIOS":
		return "ipxe-i386.kpxe"
	case "x86 UEFI":
		return "ipxe-i386.efi"
	case "x64 UEFI":
		return "ipxe-x86_64.efi"
	case "ARM 32-bit UEFI":
		return "ipxe-arm32.efi"
	case "ARM 64-bit UEFI":
		return "ipxe-arm64.efi"
		return "ipxe-i386.kpxe"

func Configure() map[string]string {
	return map[string]string{
		"useStdlib": "false",

The script is just a small Go program which exports two functions: Filename and Configure. Configure is called to configure the interpreter; for example, if you want to use the standard library, i.e. to log information with log.Println or to make a HTTP request with http.Get, you can set "useStdlib": "true",. Filename is called with the IP address, MAC address and architecture (as a string and as an ID), and should return the name of the file to send to the booting node. The following architecture values are available (see IANA Processor Architecture Types):

Expand available architecture values
archID Parameter arch Parameter
0x00 x86 BIOS
0x02 Itanium
0x04 Arc x86 (DEPRECATED)
0x05 Intel Lean Client (DEPRECATED)
0x06 x86 UEFI
0x07 x64 UEFI
0x08 EFI Xscale (DEPRECATED)
0x09 EBC
0x0a ARM 32-bit UEFI
0x0b ARM 64-bit UEFI
0x0c PowerPC Open Firmware
0x0d PowerPC ePAPR
0x0e POWER OPAL v3
0x0f x86 uefi boot from http
0x10 x64 uefi boot from http
0x11 ebc boot from http
0x12 arm uefi 32 boot from http
0x13 arm uefi 64 boot from http
0x14 pc/at bios boot from http
0x15 arm 32 uboot
0x16 arm 64 uboot
0x17 arm uboot 32 boot from http
0x18 arm uboot 64 boot from http
0x19 RISC-V 32-bit UEFI
0x1a RISC-V 32-bit UEFI boot from http
0x1b RISC-V 64-bit UEFI
0x1c RISC-V 64-bit UEFI boot from http
0x1d RISC-V 128-bit UEFI
0x1e RISC-V 128-bit UEFI boot from http
0x1f s390 Basic
0x20 s390 Extended
0x21 MIPS 32-bit UEFI
0x22 MIPS 64-bit UEFI
0x23 Sunway 32-bit UEFI
0x24 Sunway 64-bit UEFI

When bofied is first started, it automatically downloads pojntfx/ipxe-binaries to the boot file directory, so without configuring anything you can already network boot many Linux distros and other operating systems thanks to This behavior can of course also be disabled, in which case only a minimal config file will be created; see Reference.


In addition to using the frontend to manage boot files, you can also mount them using WebDAV. You can the required credentials by using the Mount directory button in the frontend:

Mount directory modal

Using a file manager like Files, you can now mount the folder:

GNOME Files WebDAV mounting

When transfering large files, using WebDAV directly is the recommended method.

GNOME Files WebDAV listing


bofied exposes a streaming gRPC and gRPC-Web API for monitoring network boot, which is also in use internally in the frontend. You can find the relevant .proto files in api/proto/v1; send the OpenID Connect token with the X-Bofied-Authorization metadata key.


  • This project would not have been possible were it not for @maxence-charriere's go-app package; if you enjoy using bofied, please donate to him!
  • The open source PatternFly design system provides a professional design and reduced the need for custom CSS to a minimium (less than 30 SLOC!).
  • pin/tftp provides the TFTP functionality for bofied.
  • studio-b12/gowebdav provides the WebDAV client for the bofied frontend.
  • The yaegi Go interpreter is used to securely evaluate the config script.
  • All the rest of the authors who worked on the dependencies used! Thanks a lot!


To contribute, please use the GitHub flow and follow our Code of Conduct.

To build and start a development version of bofied locally, run the following:

$ git clone
$ cd bofied
$ make depend

The backend should now be started and the frontend be available on http://localhost:15225/. Whenever you change a source file, the back- and frontend will automatically be re-compiled.

Have any questions or need help? Chat with us on Matrix!

Related Projects

If you want to have persistent inventory of services and nodes on your network or turn the nodes in it on remotely, check out liwasc!


bofied (c) 2021 Felix Pojtinger and contributors

SPDX-License-Identifier: AGPL-3.0

  • Add TFTP and HTTP ports to metadata

    Add TFTP and HTTP ports to metadata

    Previously, the frontend was hard-coded to use the server's default TFTP port and the HTTP port was infered from the frontend's URL. This PR adds the TFTP and HTTP ports to the metadata, which removes the need for the frontend to assume them.

    opened by pojntfx 0
  • Improve reliability over wifi

    Improve reliability over wifi

    This adds some docs and better error handling for complex network configurations such as running bofied over Wifi; it also fixes the docs to use --net host for DHCP support by using the host networking stack.

    opened by pojntfx 0
  • Unable to use frontend

    Unable to use frontend


    It should be obvious but i've tried many combinations without being able to use the frontend. The default values + what is on the screenshot + what is described in the documentation are not in line, so it doesn't help...

    I'm running the backend in a docker container on a headless server (with IP

    The backend is running with defaults, i have in the log :

    2021/11/07 16:58:08 bofied backend listening on :67 (DHCP), :4011 (proxyDHCP), :69 (TFTP), :15256 (WebDAV on /private, HTTP on /public and gRPC-Web on /grpc) and :15257 (gRPC), advertising IP to DHCP clients

    So what should i put :

    • as backend URL ? Documentation speaks about "http://" but default value at is about ws:// + which IP / which port ?
    • redirect URL ? Documentation speaks about the redirect URL previously configured ... but there is no previously configured redirect URL anywhere ... (or i missed it) ... also screenshot is about :15255

    I tryed a lot of IP like :

    • backend URL : or :15257 or same with ws://[15256|15257]
    • redirect URL : or :15255 or :15256 or :15257

    So i'm quite confused :

    • is this supposed to work with another IP than localhost (instead of having everything deployed on the same local computer) ?
    • what are the exact ports and protocols to be used ? (this is not obvious, per the documentation)

    I'm running the container with :

    docker run \
        --name bofied-backend \
        -d \
        --restart always \
        --net host \
        --cap-add NET_BIND_SERVICE \
        -v /home/datas/docker-datas/bofied/:/root/.local/share/bofied:z \
        -e BOFIED_BACKEND_OIDCCLIENTID=myclientidinlowercasewithoutspecialcharacters \

    Thanks in advance.

    opened by SR-G 4
  • Expose more configurability

    Expose more configurability

    An example is using DNSMasq which allows tagging based on DHCP options and the workflow of booting iPXE then running a http based ipxe script if the DHCP ipxe vendor class is set.

    If this is possible now let me know.

    opened by nwmcsween 1
  • Service quits as soon as I log out of SSH

    Service quits as soon as I log out of SSH

    Running it on my Ubuntu 20.04 server which is running headless (its actually running on an old PC that's inside a cupboard in my spare room with nothing but power and Ethernet) meaning I HAVE to use SSH to control it, which is usually fine.

    Installed this yesterday (full self hosted if that makes a difference) and everything is working great however as soon as I close my SSH session the service stops meaning I have to log back in and run it again then leave SSH open while I use.

    I have tried enabling the service using --now to symlink it to systemd so it starts at boot up, doesn't work. I have also tried running it with &, while I get a PID for the service from this the exact same behavior happens.

    This software is awesome, I was using a clunky windows based PXE and TFTP server before hand, this replaces both and assuming I can get it running all the time works better.

    Is there any reason why I cannot run the service as a system service instead of a user one?

    opened by Dungeonseeker 2
Felix Pojtinger
20 | Software Engineer (Go/JS) | Lefty | He/they
Felix Pojtinger
Sabakan is a versatile network boot server designed for large on-premise data centers.

Sabakan is a versatile network boot server designed for large on-premise data centers. Currently, it is made only for Flatcar Container Linux.

Cybozu Go 106 Jan 2, 2023
Ugg boot is a tool for people wanting to have some comfort in their lives.

Ugg Boot Ugg boot is a tool for people wanting to have some comfort in their lives. It provides a simple way to update Go executables and list availab

Dan Kortschak 15 Aug 28, 2022
:vulcan_salute: Fast, modern, easy-to-use network scanner

sx is the command-line network scanner designed to follow the UNIX philosophy. The goal of this project is to create the fastest network scanner with

null 1.2k Jan 2, 2023
TCPProbe is a modern TCP tool and service for network performance observability.

TCPProbe is a modern TCP tool and service for network performance observability. It exposes information about socket’s underlying TCP session, TLS and HTTP (more than 60 metrics). you can run it through command line or as a service. the request is highly customizable and you can integrate it with your application through gRPC. it runs in a Kubernetes cluster as cloud native application and by adding annotations on pods allow a fine control of the probing process.

Mehrdad Arshad Rad 333 Dec 15, 2022
🐶 A modern alternative network traffic sniffer.

sniffer A modern alternative network traffic sniffer inspired by bandwhich(Rust) and nethogs(C++). Introduction 中文介绍 sniffer is designed f

dongdong 530 Dec 29, 2022
Simple, secure and modern Go HTTP server to serve static sites, single-page applications or a file with ease

srv srv is a simple, secure and modern HTTP server, written in Go, to serve static sites, single-page applications or a file with ease. You can use it

Kevin Pollet 55 Sep 7, 2022
Package socket provides a low-level network connection type which integrates with Go's runtime network poller to provide asynchronous I/O and deadline support. MIT Licensed.

socket Package socket provides a low-level network connection type which integrates with Go's runtime network poller to provide asynchronous I/O and d

Matt Layher 49 Dec 14, 2022
Magma is an open-source software platform that gives network operators an open, flexible and extendable mobile core network solution.

Connecting the Next Billion People Magma is an open-source software platform that gives network operators an open, flexible and extendable mobile core

Magma 1.5k Dec 31, 2022
Optimize Windows's network/NIC driver settings for NewTek's NDI(Network-Device-Interface).

windows-ndi-optimizer[WIP] Optimize Windows's network/NIC driver settings for NewTek's NDI(Network-Device-Interface). How it works This is batchfile d

Nil Hiiragi 3 Apr 15, 2022
A simple network analyzer that capture http network traffic

httpcap A simple network analyzer that captures http network traffic. support Windows/MacOS/Linux/OpenWrt(x64) https only capture clienthello colorful

null 2 Oct 25, 2022
Zero Trust Network Communication Sentinel provides peer-to-peer, multi-protocol, automatic networking, cross-CDN and other features for network communication.

Thank you for your interest in ZASentinel ZASentinel helps organizations improve information security by providing a better and simpler way to protect

ZTALAB 8 Nov 1, 2022
webrpc is a schema-driven approach to writing backend services for modern Web apps and networks

webrpc is a schema-driven approach to writing backend servers for the Web. Write your server's api interface in a schema format of RIDL or JSON, and t

null 505 Jan 7, 2023
A modern, fast and scalable websocket framework with elegant API written in Go

About neffos Neffos is a cross-platform real-time framework with expressive, elegant API written in Go. Neffos takes the pain out of development by ea

Gerasimos (Makis) Maropoulos 494 Jan 4, 2023
A modern layer 7 load balancer from baidu

BFE BFE is a modern layer 7 load balancer from baidu. Advantages Multiple protocols supported, including HTTP, HTTPS, SPDY, HTTP2, WebSocket, TLS, Fas

null 5.7k Dec 30, 2022
gobetween - modern & minimalistic load balancer and reverse-proxy for the ☁️ Cloud era.

gobetween - modern & minimalistic load balancer and reverse-proxy for the ☁️ Cloud era. Current status: Maintenance mode, accepting PRs. Currently in

Yaroslav Pogrebnyak 1.8k Dec 25, 2022
[WIP] gg is a portable tool to redirect the traffic of a given program to your modern proxy without installing any other programs.

gg gg (go-graft), was inspired by graftcp. go-graft is a pure golang implementation with more useful features. TODO: Use system DNS as the fallback. R

mzz 428 Dec 28, 2022
Simple and modern beanstalkd library for Golang

go-jackd package main import "" func main() {

null 7 Sep 27, 2022
🖥️ Fast, modern and cross-platform SSH client

??️ Fast, modern and cross-platform SSH client Installation Build from source Requirements for building the project from source: Node 16 Go >= 1.17 Wa

Kamil Marut 2 Mar 20, 2022
Making it easier to run Minecraft on a modern platform.

Minecraft Overseer An application easing configuration and operation of Minecraft in a modern environment. Deployment Scenarios Docker docker run --rm

Mark Eschbach 2 May 21, 2022