Building a BSD Netboot Server
Pages: 1, 2
There are three pieces of information that the clients need to know to download the appropriate booting code from the TFTP server:
option root-path: The location of its root file system on the remote NFS server.
next-server: The address of the TFTP server from which clients must receive files to continue booting.
filename: The name of the file to fetch from the TFTP server.
A little later, they also need the
root-path option to load the
kernel and mount the root file system. For now, the PXE LAN adapter of the
station automatically tries to use two of the other parameters to continue
booting. The pxeboot(8) file is a modified version of the
loader(8), which runs on the third stage of the FreeBSD booting
process (see the handbook for more details about the boot procedure). As the
diskless client expects to fetch this program via TFTP, it must be exist on the
server at 192.168.1.2.
The FreeBSD distribution includes a TFPT server, so you do not need to
install additional software. The daemon is
tftpd and usually
inetd. To start TFTP server, create a special
directory of /tftpboot and copy
server# mkdir /tftpboot server# cp /boot/pxeboot /tftpboot
Add the following line into /etc/inetd.conf:
tftp dgram udp wait root /usr/libexec/tftpd tftpd -l -s /tftpboot
-l switch turns on the logging of TFTP operations. The
-s switch specifies the root directory for
after it calls
chroot(). For more details about
man tftpd(8) and
The server is ready to run after you restart
server# killall -HUP inetd
If everything is okay, the command
server# sockstat -4l | grep 69
will return results similar to this:
root inetd 556 5 udp4 *:69 *:*
After the client successfully downloads the pxeboot file,
according to the
root-path option, it'll try to connect over NFS to
the /diskless_ro directory of the server 192.168.1.2 to find the
root filesystem with an appropriate kernel there.
You can also configure
pxeboot to upload a kernel with TFTP.
This will allow you to boot different diskless stations with different kernels.
In that case, you need to recompile
pxeboot with the option
LOADER_TFTP_SUPPORT=YES in /etc/make.conf. See also
the handbook and /usr/share/examples/etc/make.conf.
I confined the example network to using one kernel for all the workstations. As a consequence, I set up the NFS server to export the proper directories. As the name implies, the directory /diskless_ro should export as read-only. The diskless_rw directory contains subdirectories specific to each client for its writing. Each subdirectory must itself contain the special etc and var directories. For example, the test diskless workstation will have its own directory, diskless_rw/192.168.1.101, with two subdirectories named /diskless_rw/192.168.1.101/etc and /diskless_rw/192.168.1.101/var.
The directory /diskless_ro should be empty, while /diskless_rw contains something like:
/diskless_rw/192.168.1.10 /diskless_rw/192.168.1.10/etc /diskless_rw/192.168.1.10/var ... /diskless_rw/192.168.1.101 /diskless_rw/192.168.1.101/etc /diskless_rw/192.168.1.101/var ... /diskless_rw/192.168.1.254 /diskless_rw/192.168.1.254/etc /diskless_rw/192.168.1.254/var
Besides these two exports, the diskless station will use /usr from the server in read-only mode.
In order to let the diskless station use all of these directories, you must configure the NFS server accordingly. Add the following lines to the file /etc/exports on the server:
# file systems accessible only for reading: /usr -ro -maproot=0 -network 192.168.1.0 -mask 255.255.255.0 /diskless_ro -ro -maproot=0 -network 192.168.1.0 -mask 255.255.255.0 # file systems accessible for writing. All the resources # given to every diskless station are specified by one line: # # Diskless-10 /diskless_rw/192.168.1.10/etc /diskless_rw/192.168.1.10/var \ -mapall=root 192.168.1.10 # ... # Diskless-101 /diskless_rw/192.168.1.101/etc /diskless_rw/192.168.1.101/var \ -mapall=root 192.168.1.101 # ... # Diskless-254 /diskless_rw/192.168.1.254/etc /diskless_rw/192.168.1.254/var \ -mapall=root 192.168.1.254
Then change /etc/rc.conf to start the NFS server while the system boots:
You may also need to change the
nfs_server_flags="-u -t -n 48 -h 192.168.1.2"
-n switch is very important here. It specifies the number
nfsd daemons that regulate the NFS, which influences the number
of the NFS clients that can connect simultaneously. Tune this parameter
according to the number of clients. The
switches turn on UDP and TCP.
-h binds the daemon to a network
Now, start the NFS server by hand (so as not to have to reboot the server):
server# rpcbind server# nfsd -u -t -n 48 -h 192.168.1.2 server# mountd -r
After the NFS server starts correctly, check the exported file systems:
server# showmount -e Exports list on localhost: /usr 192.168.1.0 /diskless_rw/192.168.1.103/var 192.168.1.254 /diskless_rw/192.168.1.103/etc 192.168.1.254 ... /diskless_rw/192.168.1.101/var 192.168.1.101 /diskless_rw/192.168.1.101/var 192.168.1.101 ... /diskless_rw/192.168.1.101/etc 192.168.1.10 /diskless_rw/192.168.1.101/etc 192.168.1.10 /diskless_ro 192.168.1.0
Notes on Mounting
It is not a good idea to place diskless_rw and diskless_ro within the same physical file system because NFS doesn't export the directory but the whole file system. In /etc/exports, every line represents of the export of one server file system to one or several clients. For each exported file system, you can specify the same client only once.
For example, if diskless_rw and diskless_ro occupy different file systems, then this /etc/exports will be correct:
/diskless_rw 192.168.1.101 /diskless_ro -ro 192.168.1.101
A mistaken /etc/exports might be:
/usr/diskless_rw 192.168.1.101 /usr/diskless_ro -ro 192.168.1.101
If diskless_rw and diskless_ro are directories of
the same file system /usr, an error will occur while exporting
them to the same clients, which will prevent them from mounting
diskless_ro. The rules demand that you specify both resources,
/usr/diskless_ro on one line, so
you have to decide whether to make them both accessible for reading only or for
both reading and writing.
Nevertheless, you can deceive the
mountd daemon by using
IP address ranges instead of hostnames. For example, here's another mistaken
version of /etc/exports that will execute successfully:
/usr/diskless_rw -network 192.168.1.0 -mask 255.255.255.0 /usr/diskless_ro -ro -network 192.168.0.0 -mask 255.255.0.0
In this case, the server will successfully export /usr/diskless_rw and /usr/diskless_ro. As this configuration handles the whole file system and not only the directories, the subnet 192.168.1.0/24 will be able to mount both /usr/diskless_rw and /usr/diskless_ro in read-write mode, so there are security risks.
Mikhail Zakharov is presently the senior UNIX Administrator in a Moscow banks where he administers a wide spectrum of servers running various UNIX-like operating systems.
Return to the BSD DevCenter