Raspberry Pi Documentation – Remote access

You can set up a DHCP/TFTP server which will allow you to boot a Raspberry Pi 3 or 4 from the network.

The instructions assume that you have an existing home network, and that you want to use a Raspberry Pi for the server . You will also need an additional Raspberry Pi 3 or 4 as a client to be booted. Only one SD Card is needed because the client will be booted from the server after the initial client configuration.

For further details of configuring the Raspberry Pi 4 bootloader, see Raspberry Pi 4 Bootloader Configuration .

Within raspi-config , choose Advanced Options , then Boot Order , then Network Boot . You must then reboot the device for the change to the boot order to be programmed into the bootloader EEPROM. Once the Raspberry Pi has rebooted, check that the boot order is now 0xf21 :

Network boot can be enabled on the Raspberry Pi 4 using the raspi-config tool. First, run raspi-config as follows:

The client configuration is almost done. The final thing to do is to remove the program_usb_boot_mode line from config.txt . You can do this with sudo nano /boot/config.txt , for example. Finally, shut the client Raspberry Pi down with sudo poweroff .

This adds program_usb_boot_mode=1 to the end of /boot/config.txt . Reboot the Raspberry Pi with sudo reboot . Once the client Raspberry Pi has rebooted, check that the OTP has been programmed with:

Install Raspberry Pi OS Lite, or Raspberry Pi OS with desktop, on the SD card in the usual fashion. Next, enable USB boot mode with the following command:

Before the Raspberry Pi 3 Model B will network boot it needs to be booted from an SD Card with a config option to enable USB boot mode. This will set a bit in the OTP (One Time Programmable) memory in the Raspberry Pi SoC that enables network booting. Once this is done, the Raspberry Pi 3B will attempt to boot from USB, and from the network, if it cannot boot from the SD card.

On Raspberry Pi 4 the MAC address is programmed at manufacture and there is no link between the MAC address and serial number. Both the MAC address and serial numbers are displayed on the bootloader HDMI diagnostics screen.

Before configuring network boot, make a note of the serial number and mac address so that the board can be identified by the TFTP/DHCP server.

Server Configuration

Plug the SD card into the server Raspberry Pi, and then boot the server. The client Raspberry Pi will need a root file system to boot from: we will use a copy of the server’s root filesystem and place it in /nfs/client1:

sudo mkdir -p /nfs/client1
sudo apt install rsync
sudo rsync -xa --progress --exclude /nfs / /nfs/client1

Regenerate SSH host keys on the client filesystem by chrooting into it:

cd /nfs/client1
sudo mount --bind /dev dev
sudo mount --bind /sys sys
sudo mount --bind /proc proc
sudo chroot .
rm /etc/ssh/ssh_host_*
dpkg-reconfigure openssh-server
exit
sudo umount dev sys proc

Find the settings of your local network. You need to find the address of your router (or gateway), which can be done with:

ip route | awk '/default/ {print $3}'

Then run:

ip -4 addr show dev eth0 | grep inet

which should give an output like:

inet 10.42.0.211/24 brd 10.42.0.255 scope global eth0

The first address is the IP address of your server Raspberry Pi on the network, and the part after the slash is the network size. It is highly likely that yours will be a /24. Also note the brd (broadcast) address of the network. Note down the output of the previous command, which will contain the IP address of the Raspberry Pi and the broadcast address of the network.

Finally, note down the address of your DNS server, which is the same address as your gateway. You can find this with:

cat /etc/resolv.conf

Configure a static network address on your server Raspberry Pi via the systemd networking, which works as the network handler and DHCP server.

To do that, you’ll need to create a 10-eth0.netdev and a 11-eth0.network like so:

sudo nano /etc/systemd/network/10-eth0.netdev

Add the following lines:

[Match]
Name=eth0

[Network]
DHCP=no

Then create a network file:

sudo nano /etc/systemd/network/11-eth0.network

Add the following contents:

[Match]
Name=eth0

[Network]
Address=10.42.0.211/24
DNS=10.42.0.1

[Route]
Gateway=10.42.0.1

At this point, you will not have working DNS, so you will need to add the server you noted down before to systemd/resolved.conf. In this example, the gateway address is 10.42.0.1.

sudo nano /etc/systemd/resolved.conf

Uncomment the DNS line and add the DNS IP address there. Additionally, if you have a fallback DNS server, add it there as well.

[Resolve]
DNS=10.42.0.1
#FallbackDNS=

Enable systemd-networkd and then reboot for the changes to take effect:

sudo systemctl enable systemd-networkd
sudo reboot

Now start tcpdump so you can search for DHCP packets from the client Raspberry Pi:

sudo apt install tcpdump dnsmasq
sudo systemctl enable dnsmasq
sudo tcpdump -i eth0 port bootpc

Connect the client Raspberry Pi to your network and power it on. Check that the LEDs illuminate on the client after around 10 seconds, then you should get a packet from the client “DHCP/BOOTP, Request from …​”

IP 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from b8:27:eb...

Now you need to modify the dnsmasq configuration to enable DHCP to reply to the device. Press CTRL + C to exit the tcpdump program, then type the following:

echo | sudo tee /etc/dnsmasq.conf
sudo nano /etc/dnsmasq.conf

Then replace the contents of dnsmasq.conf with:

# Note: comment out port if you want DNS services for systems on the network.
port=0
dhcp-range=10.42.0.255,proxy
log-dhcp
enable-tftp
tftp-root=/tftpboot
pxe-service=0,"Raspberry Pi Boot"

Where the first address of the dhcp-range line is, use the broadcast address you noted down earlier.

Now create a /tftpboot directory:

sudo mkdir /tftpboot
sudo chmod 777 /tftpboot
sudo systemctl enable dnsmasq.service
sudo systemctl restart dnsmasq.service

Now monitor the dnsmasq log:

tail -F /var/log/daemon.log

You should see something like this:

raspberrypi dnsmasq-tftp[1903]: file /tftpboot/bootcode.bin not found

Next, you will need to copy the contents of the boot folder into the /tftpboot directory.

First, press CTRL + C to exit the monitoring state. Then type the following:

cp -r /boot/* /tftpboot

Since the tftp location has changed, restart dnsmasq:

sudo systemctl restart dnsmasq

Set up NFS root

This should now allow your Raspberry Pi client to attempt to boot through until it tries to load a root file system (which it doesn’t have).

At this point, export the /nfs/client1 file system created earlier, and the TFTP boot folder.

sudo apt install nfs-kernel-server
echo "/nfs/client1 *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
echo "/tftpboot *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports

Restart RPC-Bind and the NFS server in order to have them detect the new files.

sudo systemctl enable rpcbind
sudo systemctl restart rpcbind
sudo systemctl enable nfs-kernel-server
sudo systemctl restart nfs-kernel-server

Edit /tftpboot/cmdline.txt and from root= onwards, and replace it with:

root=/dev/nfs nfsroot=10.42.0.211:/nfs/client1,vers=4.1,proto=tcp rw ip=dhcp rootwait

You should substitute the IP address here with the IP address you have noted down. Also remove any part of the command line starting with init=.

Finally, edit /nfs/client1/etc/fstab and remove the /dev/mmcblk0p1 and p2 lines (only proc should be left). Then, add the boot partition back in:

echo "10.42.0.211:/tftpboot /boot nfs defaults,vers=4.1,proto=tcp 0 0" | sudo tee -a /nfs/client1/etc/fstab

Good luck! If it doesn’t boot on the first attempt, keep trying. It can take a minute or so for the Raspberry Pi to boot, so be patient.