Remote access - Raspberry Pi Documentation
Remote access - Raspberry Pi Documentation
We use optional cookies, as detailed in our cookie policy, to remember your settings and understand how you use our website.
Introduction to remote
Getting started Sometimes you need to access a Raspberry Pi without connecting it to a monitor, Access a remote terminal
keyboard, and mouse. Perhaps the Raspberry Pi is embedded in a robot or mounted in
with SSH
Raspberry Pi OS
an inconvenient location. Or maybe you don’t have a spare monitor.
Screen share with VNC
Configuration
Remote access with
§ Remote control over the local network
config.txt Raspberry Pi Connect
To remotely control your Raspberry Pi from another device on your local network, use Share files with SCP
Legacy config.txt
one of the following services: Synchronise folders
options
between computers with
The Linux kernel SSH
rsync
Access a remote
terminal with SSH
Remote control over the Internet
To remotely control your Raspberry Pi from any device connected to the Internet, you
Screen share with
VNC can:
Remote access with Expose SSH or VNC on your Raspberry Pi over the open internet, within a VPN, or
Raspberry Pi using an external service like RealVNC’s cloud VNC Viewer.
Connect
Use Raspberry Pi Connect, a free screen sharing and remote shell service provided
Share files with SCP
by Raspberry Pi.
Synchronise folders
between computers
with rsync Find the IP address of your Raspberry Pi
Edit this on GitHub
Network File System
(NFS) Most methods of connecting to your Raspberry Pi from another machine require you to
know the local IP address of your Raspberry Pi.
Samba (SMB/CIFS)
Any device connected to a Local Area Network is assigned an IP address. In order to
Set up an Apache
web server connect to your Raspberry Pi from another machine using SSH or VNC, you need to
know the Raspberry Pi’s IP address. This is easy if you have a display connected, and
Network boot your
there are a number of methods for finding it remotely from another machine on the
Raspberry Pi
network.
Network boot using
IPv6 To find the local IP address of your Raspberry Pi, use one of the following methods.
Camera software
Desktop
AI Kit and AI HAT+
Hover over the network icon in the system tray, and a tooltip will appear. This tooltip
software
displays the name of the network you’re currently connected to and your IP address.
Raspberry Pi hardware
Compute Module
hardware
Processors
Command line
Run the following command to output your local IP address to the command line:
$ hostname -I
Boot output
If you use a display with your Raspberry Pi and you boot to the command line instead of
the desktop, the boot sequence includes your IP address as one of the last few output
messages before your login prompt.
Network Manager
You can use the built-in Network Manager CLI (nmcli) to access details about your
network. Run the following command:
GENERAL.DEVICE: wlan0
GENERAL.TYPE: wifi
GENERAL.HWADDR: D0:3B:FF:41:AB:8A
GENERAL.MTU: 1500
GENERAL.STATE: 100 (connected)
GENERAL.CONNECTION: exampleNetworkName
GENERAL.CON-PATH: /org/freedesktop/NetworkManag
er/ActiveConnection/2
IP4.ADDRESS[1]: 192.168.1.42/24
IP4.GATEWAY: 192.168.1.1
IP4.ROUTE[1]: dst = 192.168.1.0/24, nh = 0.
0.0.0, mt = 600
IP4.ROUTE[2]: dst = 0.0.0.0/0, nh = 192.16
8.1.1, mt = 600
IP4.DNS[1]: 192.168.1.3
IP6.ADDRESS[1]: ab80::11ab:b1fc:bb7e:a8a5/64
IP6.GATEWAY: --
IP6.ROUTE[1]: dst = ab80::/64, nh = ::, mt
= 1024
GENERAL.DEVICE: lo
GENERAL.TYPE: loopback
GENERAL.HWADDR: 00:00:00:00:00:00
GENERAL.MTU: 65536
GENERAL.STATE: 100 (connected (externally))
GENERAL.CONNECTION: lo
GENERAL.CON-PATH: /org/freedesktop/NetworkManag
er/ActiveConnection/1
IP4.ADDRESS[1]: 127.0.0.1/8
IP4.GATEWAY: --
IP6.ADDRESS[1]: ::1/128
IP6.GATEWAY: --
GENERAL.DEVICE: p2p-dev-wlan0
GENERAL.TYPE: wifi-p2p
GENERAL.HWADDR: (unknown)
GENERAL.MTU: 0
GENERAL.STATE: 30 (disconnected)
GENERAL.CONNECTION: --
GENERAL.CON-PATH: --
GENERAL.DEVICE: eth0
GENERAL.TYPE: ethernet
GENERAL.HWADDR: D0:3B:FF:41:AB:89
GENERAL.MTU: 1500
GENERAL.STATE: 20 (unavailable)
GENERAL.CONNECTION: --
GENERAL.CON-PATH: --
WIRED-PROPERTIES.CARRIER: off
IP4.GATEWAY: --
IP6.GATEWAY: --
This command outputs information about the various network interfaces accessible on
your Raspberry Pi. Check the GENERAL.TYPE row to see which kind of network interface
each block describes. For example, "ethernet" is the Ethernet port on your device, and
"wifi" refers to the Wi-Fi chip built into some devices. You’ll look at different blocks of
output to find your IP address depending on the way your device accesses the internet:
if your device connects to the internet using Wi-Fi, check the "wifi" block
if your device connects to the internet using the Ethernet port, check the "ethernet"
block
Once you’ve identified the correct network interface block, look for a field named
IP4.ADDRESS[1] for an IPv4 address or IP6.ADDRESS[1] for an IPv6 address. You can
ignore the trailing slash and number (e.g. /24) in those fields.
In the example above, the Raspberry Pi uses Wi-Fi to access the internet. Check the
block where the GENERAL.TYPE field reads "wifi" to find the IP address. In this case, you
can access this device using the IPv4 address in the IP4.ADDRESS[1] field:
192.168.1.42.
If your device supports mDNS, you can reach your Raspberry Pi by using its hostname
and the .local suffix. The default hostname on a fresh Raspberry Pi OS install is
raspberrypi, so by default any Raspberry Pi running Raspberry Pi OS responds to:
$ ping raspberrypi.local
TIP
TIP
Your router’s IP address is often http://192.168.1.1, but not always. You may be
able to find your router’s address and credentials printed on a label on your router.
This will take you to a control panel. Browse to the list of connected devices or similar
(all routers are different), and you should see some devices you recognise. Some
devices are detected as PCs, tablets, phones, printers, etc. so you should recognise
some and rule them out to figure out which is your Raspberry Pi.
TIP
If you connect your Raspberry Pi to your network with a wire, try filtering for wired
devices in the list. There should be fewer devices to choose from.
To install on Linux, install the nmap package e.g. apt install nmap.
To use nmap to scan the devices on your network, you need to know the subnet you are
connected to. First, find the local IP address of the computer you’re using:
On macOS, go to System Settings > Network, select your active network connection,
then click the Details…button
On Windows, go to the Control Panel, then under Network and Sharing Center, click
View network connections, select your active network connection and click View
status of this connection
Next, scan the whole subnet for other devices. Most local networks use IPv4, which
uses four numbers with values between 1 and 255 for each IP address. Devices on your
subnet all use the same first three numbers. For example, if your IP address is
192.168.1.5, other devices will use addresses like 192.168.1.2, 192.168.1.6 and
192.168.1.200. To scan this subnet with nmap, pass the string 192.168.1.0/24, which
covers the subnet range 192.168.1.0 to 192.168.1.255. Use the -sn flag to run a
ping scan on the entire subnet range:
TIP
A ping scan queries all IP addresses in the range for a response. For each device that
responds to the ping, the output shows the hostname and IP address as follows:
The output above shows a device with hostname raspberrypi has IP address
192.168.1.8.
2. When you open the Fing app, touch the refresh button in the upper right-hand corner
of the screen.
3. After a few seconds, you should see a list with all the devices connected to your
network.
4. Scroll down to the entry with the manufacturer "Raspberry Pi". The IP address
appears in the bottom left corner, and the MAC address in the bottom right corner of
the entry.
You can access the terminal of a Raspberry Pi remotely from another computer on the
same network using the Secure SHell (SSH) protocol.
4. Click OK.
When the connection works, you will see a security warning. Type yes to continue. You
will only see this warning the first time you connect.
<username>@<hostname> ~ $
You are now connected to the Raspberry Pi remotely, and can execute commands.
NOTE
If you receive a connection timed out error, you may have entered the wrong IP
address for the Raspberry Pi. Check the IP address of the Raspberry Pi.
NOTE
NOTE
X11 enables graphical applications over SSH. Pass the -Y flag to forward an X session
over SSH:
Once authenticated, you will see the command line as usual. However, you can also
open graphical windows that an X server can render for you. For example, type the
following command to launch a Geany window:
$ geany &
When configuring a boot image with Raspberry Pi Imager, you can preconfigure SSH
keys. You can generate a new SSH keypair or an existing SSH key.
1. Follow the install using Imager guide to configure your boot image.
2. During the OS Customisation step, navigate to the Services tab and tick the Enable
SSH checkbox.
3. Select the Allow public-key authentication only radio button. If you already have an
SSH public key stored in ~/.ssh/id_rsa.pub, Imager automatically uses that public
key to prefill the text box. If Imager doesn’t find an SSH public key, you can click the
RUN SSH-KEYGEN button to generate a new keypair.
If you already have an installation of Raspberry Pi OS, you can update your existing
configuration to use SSH key authentication.
To check for an existing SSH public key on the computer you use to remotely connect
to the Raspberry Pi, run the following command:
$ ls ~/.ssh
If you see files named id_ed25519.pub, id_rsa.pub, or id_dsa.pub, you already have
an SSH key. Skip SSH keypair generation and proceed to add the SSH key to your list of
SSH identities.
TIP
This guide provides instructions to generate a new RSA key. For additional security,
you can instead generate a Ed25519 key. Pass -t ed25519 to ssh-keygen and
replace rsa with ed25519 when referencing your public and private key file names to
use an Ed25519 key.
$ ssh-keygen
When asked where to save the key, press Enter to use the default location,
~/.ssh/id_rsa.
Run the following command to check the contents of the .ssh directory:
$ ls ~/.ssh
The id_rsa file contains your private key. Keep this secure on the computer you use to
remotely connect to the Raspberry Pi.
The id_rsa.pub file contains your public key. You will share this key with your
Raspberry Pi. When you connect with the Raspberry Pi remotely, it will use this key to
verify your identity.
Next, add your key identities to ssh-agent with the following command:
$ ssh-add ~/.ssh/id_rsa
On the computer you use to remotely connect to the Raspberry Pi, use the following
command to securely copy your public key to the Raspberry Pi:
If your operating system does not support ssh-copy-id, you can instead copy your
public key with scp.
First, on your Raspberry Pi, create the directory where Linux expects to find keys:
$ mkdir .ssh
On your usual computer, use scp to copy your public key to a file named
.ssh/authorized_keys on your Raspberry Pi:
TIP
The command above assumes you have never before authorized any keys to
access your Raspberry Pi. If you have previously added at least one key, you should
instead add a new line containing the public key to the end of the authorized_keys
file to preserve your existing keys.
When prompted, enter the password for your user account on the Raspberry Pi.
Then, on your Raspberry Pi, configure permissions for the authorized_keys file:
VNC relies upon a client and a server. The client runs on a device you can physically
interact with, such as a personal laptop, desktop, tablet, or phone. The server runs on
your Raspberry Pi. When you use VNC, the client transmits keyboard and mouse events
to the server. The server executes those events on your Raspberry Pi, and returns
screen updates to the client.
The VNC client displays the desktop of your Raspberry Pi in a window. You can interact
with the desktop as though you were working on the Raspberry Pi itself.
Raspberry Pi OS includes wayvnc. This provides a VNC server that you can enable in
your device preferences.
Before you can use VNC on your Raspberry Pi, you must enable the VNC server.
TIP
5. Click the radio button next to VNC into the active position.
$ sudo raspi-config
4. Under Would you like the VNC Server to be enabled?, highlight <Yes> and press
Enter.
your Raspberry Pi and the device running the VNC client, connected to the same
network (e.g. a home wireless network or VPN)
1. Download TigerVNC. You can install the latest version from the Releases page of
their GitHub repository. Click on the link in the latest release, and find the binary for
your platform. Windows users should download an exe; macOS users should
download the dmg; Linux users should install the jar.
2. On your client device, launch TigerVNC. On macOS and Windows, you can double-
click the binary. On Linux, install java with sudo apt install default-jre, then
run java -jar VncViewer-<version>.jar, replacing the <version> placeholder
with the version you downloaded.
3. In the "VNC server" field, enter the IP address of your Raspberry Pi.
4. Click the "Options" button. Navigate to the "Input" tab. Check the box next to "Show
dot when no cursor" to ensure that you can always see a cursor in TigerVNC.
If TigerVNC warns you that the "Hostname does not match the server certificate",
click the "Yes" button to continue.
If TigerVNC warns you that the "certificate has been signed by an unknown
authority", click the "Yes" button to grant an exception for your Raspberry Pi.
6. When prompted for a username and password, enter your credentials.
7. Click the "OK" button to authenticate with the VNC server. If your credentials are
correct, TigerVNC should open a window containing the desktop corresponding to
your account on the Raspberry Pi. You should be able to move your mouse and
keyboard to input text and interact with the desktop.
You can access a Raspberry Pi remotely from a browser on another device using
Raspberry Pi Connect. Connect handles configuration automatically, so you don’t have
to find your Raspberry Pi’s local IP address, your network’s public IP address, or modify
your local network firewall to enable external access.
Connect includes the ability to screen share on Raspberry Pi models running the
Wayland window server and remote shell (terminal) access on all Raspberry Pi models.
Secure Copy Protocol (scp) sends files over SSH. You can use scp to copy files
between your Raspberry Pi and another computer.
To copy a file to a specific directory, append the directory path after the : in the scp
command. Create the folder before you run scp, since scp won’t create folders
automatically. For instance, the following command copies a file named myfile.txt
into the project/ directory within a user’s home folder:
$ scp <username>@<pi_ip_address>:myfile.txt .
Alternatively, use a wildcard to copy all files matching a particular filter. The following
command copies all files that end with .txt:
$ scp m* <username>@<pi_ip_address>:
The following command copies all files that start with m and end with .txt:
NOTE
To copy files with names that contain spaces, enclose the file name in quotes:
Copy a folder
To copy a folder and all of its contents, pass the folder name with the -r (recursive)
flag:
You can use rsync to synchronise folders between computers. For example, you could
use rsync to transfer new pictures taken by your Raspberry Pi to your personal
computer automatically.
Before you can configure rsync, determine values for the following:
<pi_ip_address>: your Raspberry Pi’s local IP address: see Find your Raspberry Pi’s
IP address for more information
<pi_folder_name>: the name of the folder you want to copy files from on your
Raspberry Pi
<pc_folder_name>: the name of the folder you would like to synchronise on your
personal computer
To configure rsync to synchronise files, complete the following steps on your personal
computer, replacing placeholders in the commands with the values you determined
above:
$ mkdir <pc_folder_name>
This command copies all files from the selected folder on your Raspberry Pi to the
selected folder on your personal computer. If you run the command multiple times,
rsync keeps track of the files you have already downloaded and skips them. If you
delete or modify an already synchronised file on the Raspberry Pi, rsync updates the
files on your personal computer accordingly.
Network File System (NFS) allows you to share a directory located on one networked
computer with other computers or devices on the same network. The computer where
the directory is located is called the server, and computers or devices connecting to
that server are called clients. Clients usually mount the shared directory to make it a
part of their own directory structure. The shared directory is an example of a shared
resource or network share.
For easier maintenance, we will isolate all NFS exports in single directory, into which the
real directories will be mounted with the --bind option.
Suppose we want to export our users' home directories, which are in /home/users.
First we create the export filesystem:
TIP
If you plan to configure LDAP/NIS authentication, skip the chmod step below.
Grant /export and /export/users read, write, and execute permissions (777) so you
can access the NFS share from the client without LDAP/NIS authentication:
To save us from retyping this after every reboot, we add the following line to
/etc/fstab:
1. /etc/default/nfs-kernel-server
2. /etc/default/nfs-common
3. /etc/exports
In order for the ID names to be automatically mapped, the file /etc/idmapd.conf must
exist on both the client and the server with the same contents and with the correct
domain names. Furthermore, this file should have the following lines in the Mapping
section:
[Mapping]
Nobody-User = nobody
Nobody-Group = nogroup
However, note that the client may have different requirements for the Nobody-User and
Nobody-Group. For example, on RedHat variants, it is nfsnobody for both. If you’re not
sure, check via the following commands to see if nobody and nogroup are there:
$ cat /etc/passwd
$ cat /etc/group
This way, server and client do not need the users to share same UID/GUID. For those
who use LDAP-based authentication, add the following lines to the idmapd.conf of
your clients:
[Translation]
Method = nsswitch
This will cause idmapd to know to look at nsswitch.conf to determine where it should
look for credential information. If you have LDAP authentication already working,
nsswitch shouldn’t require further explanation.
To export our directories to a local network 192.168.1.0/24, add the following two
lines to /etc/exports:
/export 192.168.1.0/24(rw,fsid=0,insecure,no_subtree_check,asyn
c)
/export/users 192.168.1.0/24(rw,nohide,insecure,no_subtree_check,asyn
c)
The files on your NFS are open to anyone on the network. As a security measure, you
can restrict access to specified clients.
By blocking all clients first, only clients in /etc/hosts.allow (added below) will be
allowed to access the server.
where <list of IPv4s> is a list of the IP addresses of the server and all clients.
(These have to be IP addresses because of a limitation in rpcbind, which doesn’t like
hostnames.) Note that if you have NIS set up, you can just add these to the same line.
Please ensure that the list of authorised IP addresses includes the localhost address
(127.0.0.1), as the startup scripts in recent versions of Ubuntu use the rpcinfo
command to discover NFSv3 support, and this will be disabled if localhost is unable
to connect.
Finally, to make your changes take effect, restart the service:
On the client, we can mount the complete export tree with one command:
You can also specify the NFS server hostname instead of its IP address, but in this case
you need to ensure that the hostname can be resolved to an IP on the client side. A
robust way of ensuring that this will always resolve is to use the /etc/hosts file.
To ensure this is mounted on every reboot, add the following line to /etc/fstab:
rpcbind : ALL
By blocking all clients first, only clients in /etc/hosts.allow (added below) will be
allowed to access the server.
Use of LDAP
Use of DNS
Use of NIS
Note that you have to be careful on systems where the main user has root access: that
user can change UIDs on the system to allow themselves access to anyone’s files. This
page assumes that the administrative team is the only group with root access and that
they are all trusted. Anything else represents a more advanced configuration, and will
not be addressed here.
Group permissions
A user’s file access is determined by their membership of groups on the client, not on
the server. However, there is an important limitation: a maximum of 16 groups are
passed from the client to the server, and if a user is member of more than 16 groups on
the client, some files or directories might be unexpectedly inaccessible.
Add any client name and IP addresses to /etc/hosts. (The IP address of the server
should already be there.) This ensures that NFS will still work even if DNS goes down.
Alternatively you can rely on DNS if you want - it’s up to you.
This applies to clients using NIS. Otherwise you can’t use netgroups, and should specify
individual IPs or hostnames in /etc/exports. Read the BUGS section in man netgroup
for more information.
First, edit /etc/netgroup and add a line to classify your clients (this step is not
necessary, but is for convenience):
By blocking all clients first, only clients in /etc/hosts.allow (added below) will be
allowed to access the server.
where <list of IPs> is a list of the IP addresses of the server and all clients. These
have to be IP addresses because of a limitation in rpcbind. Note that if you have NIS
set up, you can just add these to the same line.
/home @myclients(rw,sync,no_subtree_check)
/usr/local @myclients(rw,sync,no_subtree_check)
The example above shares /home and /usr/local to all clients in the myclients
netgroup.
The example above shares /home and /usr/local to two clients with static IP
addresses. If you want instead to allow access to all clients in the private network
falling within a designated IP address range, consider the following:
/home 192.168.0.0/255.255.255.0(rw,sync,no_subtree_check)
/usr/local 192.168.0.0/255.255.255.0(rw,sync,no_subtree_check)
Here, rw makes the share read/write, and sync requires the server to only reply to
requests once any changes have been flushed to disk. This is the safest option; async
is faster, but dangerous. It is strongly recommended that you read man exports if you
are considering other options.
Restart services
Aside from the UID issues discussed above, it should be noted that an attacker could
potentially masquerade as a machine that is allowed to map the share, which allows
them to create arbitrary UIDs to access your files. One potential solution to this is IPSec.
You can set up all your domain members to talk to each other only over IPSec, which
will effectively authenticate that your client is who it says it is.
IPSec works by encrypting traffic to the server with the server’s public key, and the
server sends back all replies encrypted with the client’s public key. The traffic is
decrypted with the respective private keys. If the client doesn’t have the keys that it is
supposed to have, it can’t send or receive data.
Troubleshooting
Mounting an NFS share inside an encrypted home directory will only work after you are
successfully logged in and your home is decrypted. This means that using /etc/fstab to
mount NFS shares on boot will not work, because your home has not been decrypted at
the time of mounting. There is a simple way around this using symbolic links:
1. Edit /etc/fstab to mount the NFS share into that directory instead:
1. Create a symbolic link inside your home, pointing to the actual mount location. For
example, and in this case deleting the Music directory already existing there first:
$ rmdir /home/user/Music
$ ln -s /nfs/music/ /home/user/Music
Samba (SMB/CIFS)
Edit this on GitHub
Turn on sharing
1. Right click the system tray and select Networking and Sharing Centre from the
menu.
1. Right click the folder you want to share and select Properties.
4. Select Share this folder; by default, Windows uses the folder name as the share
name.
The folder should now be shared. You can modify shared folder permissions by
changing permissions on both the Permissions and Security pages.
On Windows 10 there is a Sharing Wizard that helps with some of these steps.
3. Right click and select New Share to begin the Sharing Wizard.
5. Select the folder you wish to share, then click the Next button.
6. Click Next to use the sharing defaults or select Custom and set the required
permissions.
$ mkdir windowshare
Now, we need to mount the remote folder to that location. The remote folder is the host
name or IP address of the Windows PC, and the share name used when sharing it. We
also need to provide the Windows username that will be used to access the remote
machine. Don’t forget to replace the <username> placeholder with your Raspberry Pi OS
username.
$ sudo mount.cifs //<hostname or IP address>/<shared windows folder>
/home/<username>/windowshare -o user=<name>
You should now be able to view the content of the Windows share on your Raspberry Pi.
$ ls windowshare/
This error occurs when SMB protocol version do not match and the Linux Samba client
returns a misleading error message. By default Raspberry Pi OS uses versions 2.1 and
above, compatible with Windows 7 and later. Older devices, including some NAS, may
require version 1.0. To fix this error, append a version entry (e.g. ,vers=1.0) to your
mount command:
You may need to try different versions to match up with the server version. Possible
values are:
Version Description
$ cd ~
$ mkdir shared
$ chmod 0740 shared
Now we need to tell Samba about your default user account when accessing that
folder. When prompted, enter your password, replacing the <username> placeholder
with the username of your primary user account:
Now we need to tell Samba to share this folder, using the Samba configuration file.
At the end of the file, add the following to share the folder, giving the remote user
read/write permissions. Replace the <username> placeholder with the username of the
primary user account on your Raspberry Pi:
[share]
path = /home/<username>/shared
read only = no
public = yes
writable = yes
In the same file, find the workgroup line, and if necessary, change it to the name of the
workgroup of your local Windows network.
Apache is a popular web server application you can install on the Raspberry Pi to allow
it to serve web pages.
On its own, Apache can serve HTML files over HTTP, and with additional modules can
serve dynamic web pages using scripting languages such as PHP.
Install Apache
First, update the available packages by typing the following command into the Terminal:
Browse to the default web page either on the Raspberry Pi or from another computer on
the network and you should see the following:
This default web page is just an HTML file on the filesystem. It is located at
/var/www/html/index.html.
Navigate to this directory in a terminal window and have a look at what’s inside:
cd /var/www/html
ls -al
This shows that by default there is one file in /var/www/html/ called index.html and
it is owned by the root user (as is the enclosing folder). In order to edit the file, you
need to change its ownership to your own username. Change the owner of the file using
the following command, replacing the <username> placeholder with the username of
your primary user account:
You can now try editing this file and then refreshing the browser to see the web page
change. If you know HTML you can put your own HTML files and other assets in this
directory and serve them as a website on your local network.
sudo rm index.html
Now save and refresh your browser. You should see "hello world". This is not dynamic
but still served by PHP. Try something dynamic:
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.
NOTE
Due to the huge range of networking devices and routers available, we can’t
guarantee that network booting will work with any device. We have had reports that,
if you cannot get network booting to work, disabling STP frames on your network
may help.
NOTE
This section only applies to the Raspberry Pi 3 Model B, as network boot is enabled
on the Raspberry Pi 3 Model B+ at the factory.
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.
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:
The client configuration is almost done. As a final step, disable USB booting. Run the
following command:
Remove the line that contains the text program_usb_boot_mode=1. Finally, shut the
client Raspberry Pi down with sudo poweroff.
Raspberry Pi 4 Model B
Network boot can be enabled on the Raspberry Pi 4 using the raspi-config tool. First,
run raspi-config as follows:
$ sudo raspi-config
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:
$ vcgencmd bootloader_config
$ ethtool -P eth0
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:
Then run:
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.
[Match]
Name=eth0
[Network]
DHCP=no
[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.
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:
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 …"
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:
# 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.
$ journalctl -f
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/firmware/* /tftpboot
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.
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
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=.
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.
1. The bootloader negotiates to get an IP address and the details of a TFTP server
using DHCP.
2. The bootloader loads the firmware via TFTP and hands over the boot process to the
firmware, passing it the details of the network.
3. The firmware loads the kernel and command line via TFTP.
4. The kernel boots the rest of the system, loading the root filesystem (rootfs) via NFS
or some other mechanism.
The bootloader and firmware (stages 1 to 3) have been enhanced to support booting
over IPv6.
IMPORTANT
How it works
To boot via IPv6 you need an updated version of the firmware (e.g. start4.elf) and
the bootloader. Using the latest release of Raspberry Pi OS and the latest stable
bootloader should be sufficient.
NOTE
The commonly used dnsmasq DHCP server doesn’t currently support the network
boot parameters required for IPv6 network boot, so for the time being you will have
to use a different DHCP server such as ISC DHCP.
To mount rootfs over the network the IPv4 netboot tutorial suggests using nfsroot.
This doesn’t support IPv6, so another method is needed to mount rootfs over the
network.
If your ISP and router don’t support IPv6 you will be limited in what you can do.
Network addresses
The first thing the bootloader does is send a router solicitation to get the details of the
network. The router responds with an advertisement packet identifying its ethernet
address, which the bootloader might need if the TFTP server is on a different network.
The router advertisement includes a flag which tells it whether to use stateful
(managed) or stateless (unmanaged) configuration for its IP address. Stateless
configuration means that the device configures its own IP address. Currently the
bootloader generates an address derived from its ethernet MAC address and a network
prefix supplied by the router.
If the router indicates that stateful configuration is enabled DHCP is used to obtain the
IP address of the device. This involves the device sending a solicitation request to a
DHCP server which responds with an advertisement. The client then requests the
address before getting a reply acknowledgement from the server.
DHCP Servers and clients identify themselves with variable length DUID (Device Unique
ID). On the Raspberry Pi this is derived from the MAC address (DUID_LL).
TFTP address
Whether using stateless or stateful configuration, the DHCP server is used to obtain the
TFTP server address. This is encoded in the BOOTFILE-URL parameter. We send the
client architecture type value 0x29 to identify a device.
See RFC 5970 and the IANA Dynamic Host Configuration Protocol for IPv6
documentation.
Boot process
The device should now have an IP address and TFTP details. It downloads the firmware
binary start4.elf from the TFTP server and continues running with this. The firmware
is passed the IP address and TFTP server details so it can download the kernel and
boot the rest of the system.
Kernel Boot
With IPv4 netboot, nfsroot is used to mount rootfs over the network. This doesn’t
support IPv6 so another solution is required. It might involve a small RAM file system
that can mount the appropriate network location before switching to the proper rootfs
contents.
NOTE
A mechanism to boot the Linux kernel with NFS via IPv6 is still to be demonstrated.
Test setup
If you want to try this out you will need another Raspberry Pi to act as the TFTP and
DHCP server.
The TFTP server can in theory be on any routable network but the DHCP server has to
be on the same network as the devices it will serve.
TFTP server
If you have a working IPv4 network boot setup you can reuse the TFTP server in
dnsmasq to supply the files (it can talk to both IPv4 and IPv6).
DHCP server
DHCP in IPv6 has changed a lot. We need DHCP to at least tell us the address of the
TFTP server, which in this case is the same machine.
DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf
INTERFACESv6="eth0"
In /etc/dhcp/dhcpd6.conf you need to specify the TFTP server address and setup a
subnet. Here the DHCP server is configured to supply some made up unique local
addresses (ULA). The host test-rpi4 line tells DHCP to give a test device a fixed
address.
not authoritative;
subnet6 fd49:869:6f93::/64 {
host test-rpi4 {
host-identifier option dhcp6.client-id 00:03:00:01:e
4:5f:01:20:24:0b;
fixed-address6 fd49:869:6f93::1000;
}
}
interface eth0
static ip6_address=fd49:869:6f93::1/64
Bootloader
Modify the configuration to tell it to attempt network boot via IPv6 rather than IPv4.
To revert to IPv4 network boot just remove the USE_IPV6 line from boot.conf.
Router
To use IPv6 you really need a router and ISP that supports IPv6. There are sites on the
internet that can check this for you or alternatively run the following command.
This sends a router solicitation to your router asking for your network details such as
the network prefix, router ethernet address and whether to use DHCP for addressing. If
there’s no response to this command it’s likely your network and ISP only supports IPv4.
If IPv6 is supported it’s most likely that it will be configured to use stateless
configuration where clients generate their own addresses.
You might be able to configure your router for stateful configuration, which means it will
use DHCP to obtain an IP address.
Debugging
Logs and traces
If the boot UART is enabled, you should see something like this from the serial port. The
lines starting RX6 indicate that IPv6 is in use.
Here dc:a6:32:6f:73:f4 is the MAC address of the TFTP server and it has an IPv6
address of fd49:869:6f93::1. The device itself has a MAC address
e4:5f:01:20:24:0b and an IPv6 address of fd49:869:6f93::1000
Boot mode: NETWORK (02) order f
GENET: RESET_PHY
PHY ID 600d 84a2
NET_BOOT: e4:5f:01:20:24:0b wait for link TFTP6: (null)
LINK STATUS: speed: 100 full duplex
Link ready
GENET START: 64 16 32
GENET: UMAC_START 0xe45f0120 0x240b0000
RX6: 12 IP: 1 MAC: 1 ICMP: 1/1 UDP: 0/0 ICMP_CSUM_ERR: 0 UDP_CSUM_ER
R: 0
NET fd49:869:6f93::1000 tftp fd49:869:6f93::1
RX6: 17 IP: 4 MAC: 4 ICMP: 2/2 UDP: 2/2 ICMP_CSUM_ERR: 0 UDP_CSUM_ER
R: 0
TFTP_GET: dc:a6:32:6f:73:f4 fd49:869:6f93::1 ab5a4158/start4.elf
Finally the bootloader hands over to firmware which should load the kernel.
Stateful configuration
Below is an extract of a TCP dump where the router is configured to use stateful
(DHCP) network configuration.
The device sends a request for an address and TFTP details to the DHCP server.
12:23:35.510763 e4:5f:01:20:24:0b (oui Unknown) > 33:33:00:01:00:02
(oui Unknown), ethertype IPv6 (0x86dd), length 132: (hlim 255, next-h
eader UDP (17) payload length: 78) fe80::e65f:1ff:fe20:240b.dhcpv6-cl
ient > ff02::1:2.dhcpv6-server: [udp sum ok] dhcp6 request (xid=8cdd5
6 (client-ID hwaddr type 1 e45f0120240b) (server-ID hwaddr/time type
1 time 671211709 dca6326f73f4) (IA_NA IAID:0 T1:0 T2:0) (option-reque
st opt_59) (opt_61) (elapsed-time 1))
The DHCP server replies, opt_59 is used to pass the address of the TFTP server.
The device sends a neighbour solicitation to the FTP server because it needs its MAC
address.
TFTP requests are made by the device which should now boot over the network.
Stateless configuration
The device sends an information request to the DHCP multicast address asking for the
TFTP details.
The DHCP server replies with the TFTP server details (opt_59).
The device asks for the TFTP server MAC address since it can tell it’s on the same
network.
You can view and edit the Raspberry Pi documentation source on Github. Please read our usage and contributions policy before you make a Pull
Request.
Raspberry Pi documentation is copyright © 2012-2025 Raspberry Pi Ltd and is licensed under a Creative Commons Attribution-ShareAlike 4.0
International (CC BY-SA) licence.
Some content originates from the eLinux wiki, and is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported licence.
The terms HDMI, HDMI High-Definition Multimedia Interface, HDMI trade dress and the HDMI Logos are trademarks or registered trademarks of
HDMI Licensing Administrator, Inc