nobodd-tftpd
A read-only TFTP server capable of reading FAT boot partitions from within image files or devices. Intended to be paired with a block-device service (e.g. NBD) for netbooting Raspberry Pis.
Synopsis
usage: nobodd-tftpd [-h] [--version] [--listen ADDR] [--port PORT]
[--board SERIAL,FILENAME[,PART[,IP]]]
Options
- -h, --help
show the help message and exit
- --version
show program’s version number and exit
- --board SERIAL,FILENAME[,PART[,IP]]
can be specified multiple times to define boards which are to be served boot images over TFTP; if PART is omitted the default is 1; if IP is omitted the IP address will not be checked
- --listen ADDR
the address on which to listen for connections (default: “::” for all addresses)
- --port PORT
the port on which to listen for connections (default: “tftp” which is port 69)
Configuration
nobodd-tftpd can be configured via the command line, or from several
configuration files. These are structured as INI-style files with bracketed
[sections]
containing key=value
lines, and optionally #-prefixed
comments. The configuration files which are read, and the order they are
consulted is as follows:
/etc/nobodd/nobodd.conf
/usr/local/etc/nobodd/nobodd.conf
$XDG_CONFIG_HOME/nobodd/nobodd.conf
(where$XDG_CONFIG_HOME
defaults to~/.config
if unset)
Later files override settings from files earlier in this order.
The configuration file may contain a [tftp]
section which may contain the
following values:
- listen
This is equivalent to the
--listen
parameter and specifies the address(es) on which the server will listen for incoming TFTP connections.- port
This is equivalent to the
--port
parameter and specifies the UDP port on which the server will listen for incoming TFTP connections. Please note that only the initial TFTP packet will arrive on this port. Each “connection” is allocated its own ephemeral port on the server and all subsequent packets will use this ephemeral port.- includedir
If this is specified, it provides the name of a directory which will be scanned for files matching the pattern
*.conf
. Any files found matching will be read as additional configuration files, in sorted filename order.
For example:
[tftp]
listen = 192.168.0.0/16
port = tftp
includedir = /etc/nobodd/conf.d
For each image the TFTP server is expected to serve to a Raspberry Pi, a
[board:SERIAL]
section should be defined. Here, “SERIAL” should be replaced
by the serial number of the Raspberry Pi. The serial number can be found in the
output of cat /proc/cpuinfo
at runtime. For example:
$ grep ^Serial /proc/cpuinfo
Serial : 100000001234abcd
If the serial number starts with 10000000 (as in the example above), exclude the initial one and all leading zeros. So the above Pi has a serial number of 1234abcd (in hexadecimal). Within the section the following values are valid:
- image
Specifies the full path to the operating system image to serve to the specified Pi, presumably prepared with nobodd-prep.
- partition
Optionally specifies the number of the boot partition. If this is not specified it defaults to 1.
- ip
Optionally limits serving any files from this image unless the IP address of the client matches. If this is not specified, any IP address may retrieve files from this share.
For example:
[board:1234abcd]
image = /srv/images/ubuntu-24.04-server.img
partition = 1
ip = 192.168.0.5
In practice, what this means is that requests from a client with the IP address
“192.168.0.5”, for files under the path “1234abcd/”, will be served from the
FAT file-system on partition 1 of the image stored at
/srv/images/ubuntu-24.04-server.img
.
Such definitions can be produced by nobodd-prep when it is provided
with the nobodd-prep --serial
option.
Boards may also be defined on the command-line with the --board
option. These definitions will augment (and override, where the serial number
is identical) those definitions provided by the configuration files.
Systemd/Inetd Usage
The server may inherit its listening socket from a managing process. In the
case of inetd(8) where the listening socket is traditionally passed
as stdin (fd 0), pass “stdin” as the value of --listen
(or the
listen
option within the [tftp]
section of the configuration file).
In the case of systemd(1), where the listening socket(s) are passed
via the environment, specify “systemd” as the value of --listen
(or
the listen
option within the [tftp]
section of the configuration file)
and the service will expect to find a single socket passed in
LISTEN_FDS
. This will happen implicitly if the service is declared as
socket-activated. However, the service must not use Accept=yes
as the
TFTP protocol is connection-less. The example units provided in the source code
demonstrate using socket-activation with the server.
In both cases, the service manager sets the port that the service will listen
on, so the --port
option (and the port
option in the [tftp]
section of the configuration file) is silently ignored.
See Also
Bugs
Please report bugs at: https://github.com/waveform80/nobodd/issues