Raspberry Pi Documentation - Remote Access
Raspberry Pi Documentation - Remote Access
Raspberry Pi Documentation - Remote Access
html
Remote access
You can connect to your Raspberry Pi from another machine. But in order to do so you’ll
need to know its IP Address.
NOTE
If you are using a display with your Raspberry Pi and if you boot to the command line
instead of the desktop, your IP address should be shown in the last few messages
before the login prompt. Otherwise open a Terminal window and type hostname -I
which will reveal your Raspberry Pi’s IP address.
as PCs, tablets, phones, printers, etc. so you should recognise some and rule them out to
�gure out which is your Raspberry Pi. Also note the connection type; if your Raspberry Pi is
connected with a wire there should be fewer devices to choose from.
If your device supports mDNS, you can reach your Raspberry Pi by using its hostname and
the .local su�x. 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
If you change the system hostname of the Raspberry Pi (e.g., by editing /etc/hostname),
Avahi will also change the .local mDNS address.
If you don’t remember the hostname of the Raspberry Pi, but have a system with Avahi
installed, you can browse all the hosts and services on the LAN with the avahi-browse
command.
nmap command
The nmap command (Network Mapper) is a free and open-source tool for network
discovery, available for Linux, macOS, and Windows.
• 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 �nd your own IP address, in other words the one of the computer you’re
using to �nd your Raspberry Pi’s IP address:
• On macOS, go to System Preferences then Network and select your active network
• 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 to view the IP address
Now you have the IP address of your computer, you will scan the whole subnet for other
devices. For example, if your IP address is 192.168.1.5, other devices will be at addresses
like 192.168.1.2, 192.168.1.3, 192.168.1.4, etc. The notation of this subnet range is
192.168.1.0/24 (this covers 192.168.1.0 to 192.168.1.255).
Now use the nmap command with the -sn �ag (ping scan) on the whole subnet range. This
may take a few seconds:
Ping scan just pings all the IP addresses to see if they respond. For each device that
responds to the ping, the output shows the hostname and IP address like so:
Here you can see a device with hostname raspberrypi has IP address 192.168.1.8. Note,
to see the hostnames, you must run nmap as root by prepending sudo to the command.
First �nd your own IP address(es), in other words the one of the computer you’re using to
�nd your Raspberry Pi’s IP address by hostname -I
fd00::ba27:ebff:feb6:f293 2001:db8:494:9d01:ba27:ebff:feb6:f293
The example shows two IP addresses. The �rst one is a so called unique local unicast
address(fc00::/7). The second one is the global unicast address(2000::/3). It is also
possible to see only one of them depending on your network (router) con�guration. Both
addresses are valid for reaching the Raspberry Pi within your LAN. The address out of
Now use one of IPs from the �rst step to ping all local nodes:
-I with the IP address, it sets the interface and the source address of the echo request, it
is necessary to choose the interface’s IP address, eth0 isn’t su�cient - the answer would
be the local link address(fe80::/10), we need the global or local unicast address
ff02::1 is a well known multicast address for all nodes on the link, so it behaves like a
local broadcast, usually it is de�ned in /etc/hosts so you can also use the name (ip6-
allnodes or ipv6-allnodes) instead of the literal address
Some newer systems expect the interface ID behind the multicast address.
This should result in replies from all the nodes on your (W)LAN link, with associated DNS
names.
ssh pi@2001:db8:494:9d01:dea6:32ff:fe23:6be1
The authenticity of host '2001:db8:494:9d01:dea6:32ff:fe23:6be1 (2001:db8:494:9
...
pi@raspberrypi4:~ $
The Fing app is a free network scanner for smartphones. It is available for Android and
iOS.
Your phone and your Raspberry Pi have to be on the same network, so connect your phone
to the correct wireless network.
When you open the Fing app, touch the refresh button in the upper right-hand corner of the
screen. After a few seconds you will get a list with all the devices connected to your
network. Scroll down to the entry with the manufacturer "Raspberry Pi". You will see the IP
address in the bottom left-hand corner, and the MAC address in the bottom right-hand
corner of the entry.
You can access the command line of a Raspberry Pi remotely from another computer or
device on the same network using the Secure Shell (SSH) protocol.
You will only have access to the command line, not the full desktop environment. For a full
remote desktop, see VNC.
NOTE
You will need to note down the IP address of your Raspberry Pi in order to connect to it
later. Using the ifconfig command will display information about the current network
status, including the IP address, or you can use hostname -I to display the IP
addresses associated with the device.
4. Click OK
Alternatively you can enable it from the terminal using the raspi-con�g application,
4. Choose Yes
5. Select Ok
�. Choose Finish
NOTE
For headless setup, SSH can be enabled by placing a �le named ssh, without any
extension, onto the boot partition of the SD Card. When the Raspberry Pi boots, it looks
for the ssh �le. If it is found, SSH is enabled and the �le is deleted. The content of the
�le does not matter; it could contain text, or nothing at all.
NOTE
For headless setup in addition to the ssh �le you need a userconf.txt �le, which
contains a string username:encryptedpassword. Please refer to the section on
con�guring a user in the discussions around headless setup of a Raspberry Pi.
WARNING
When enabling SSH on a Raspberry Pi that may be connected to the internet, you
should ensure that your password is not easily brute forced.
You can use SSH to connect to your Raspberry Pi from a Linux desktop, another Raspberry
Pi, or from an Apple Mac without installing additional software.
Open a terminal window on your computer replacing <IP> with the IP address of the
Raspberry Pi you’re trying to connect to,
ssh pi@<IP>
When the connection works you will see a security/authenticity warning. Type yes to
continue. You will only see this warning the �rst time you connect.
NOTE
If you receive a connection timed out error it is likely that you have entered the wrong
IP address for the Raspberry Pi.
WARNING
In the event your Raspberry Pi has taken the IP address of a device to which your
computer has connected before (even if this was on another network), you may be
given a warning and asked to clear the record from your list of known devices.
Following this instruction and trying the ssh command again should be successful.
Next you will be prompted for the password for the pi login: the default password on
Raspberry Pi OS is raspberry.
For security reasons it is highly recommended to change the default password on the
Raspberry Pi (also, you can not login through ssh if the password is blank). You should
now be able to see the Raspberry Pi prompt, which will be identical to the one found on the
Raspberry Pi itself.
If you have set up another user on the Raspberry Pi, you can connect to it in the same way,
replacing the username with your own, e.g. [email protected]
pi@raspberrypi ~ $
You are now connected to the Raspberry Pi remotely, and can execute commands.
Forwarding X11
You can also forward your X session over SSH, to allow the use of graphical applications,
by using the -Y �ag:
ssh -Y [email protected]
NOTE
X11 is no longer installed by default on macOS, so you will have to download and
install it.
Now you are on the command line as before, but you have the ability to open up graphical
windows. For example, typing:
geany &
You can use SSH to connect to your Raspberry Pi from a Windows 10 computer that is
using October 2018 Update or later without having to use third-party clients.
Open a terminal window on your computer replacing <IP> with the IP address of the
Raspberry Pi you’re trying to connect to,
ssh pi@<IP>
When the connection works you will see a security/authenticity warning. Type yes to
continue. You will only see this warning the �rst time you connect.
NOTE
If you receive a connection timed out error it is likely that you have entered the wrong
IP address for the Raspberry Pi.
WARNING
In the event your Raspberry Pi has taken the IP address of a device to which your
computer has connected before (even if this was on another network), you may be
given a warning and asked to clear the record from your list of known devices.
Following this instruction and trying the ssh command again should be successful.
Next you will be prompted for the password for the pi login: the default password on
Raspberry Pi OS is raspberry.
For security reasons it is highly recommended to change the default password on the
Raspberry Pi (also, you can not login through ssh if the password is blank). You should
now be able to see the Raspberry Pi prompt, which will be identical to the one found on the
Raspberry Pi itself.
If you have set up another user on the Raspberry Pi, you can connect to it in the same way,
replacing the username with your own, e.g. [email protected]
pi@raspberrypi ~ $
You are now connected to the Raspberry Pi remotely, and can execute commands.
ls ~/.ssh
If you see �les named id_rsa.pub or id_dsa.pub then you have keys set up already, so you
can skip the 'Generate new SSH keys' step below.
ssh-keygen
Upon entering this command, you will be asked where to save the key. We suggest saving
it in the default location (~/.ssh/id_rsa) by pressing Enter.
You will also be asked to enter a passphrase, which is optional. The passphrase is used to
encrypt the private SSH key, so that if someone else copied the key, they could not
impersonate you to gain access. If you choose to use a passphrase, type it here and press
Enter, then type it again when prompted. Leave the �eld empty for no passphrase.
ls ~/.ssh
The id_rsa �le is your private key. Keep this on your computer.
The id_rsa.pub �le is your public key. This is what you share with machines that you
connect to: in this case your Raspberry Pi. When the machine you try to connect to
matches up your public and private key, it will allow you to connect.
cat ~/.ssh/id_rsa.pub
ssh-copy-id <USERNAME>@<IP-ADDRESS>
NOTE
During this step you will need to authenticate with your password.
Alternatively, if ssh-copy-id is not available on your system, you can copy the �le manually
over SSH:
If you see the message ssh: connect to host <IP-ADDRESS> port 22: Connection
refused and you know the IP-ADDRESS is correct, then you may not have enabled SSH on
your Raspberry Pi. Run sudo raspi-config in the Raspberry Pi’s terminal window, enable
SSH, then try to copy the �les again.
Now try ssh <USER>@<IP-ADDRESS> and you should connect without a password prompt.
If you see a message "Agent admitted failure to sign using the key" then add your RSA or
DSA identities to the authentication agent ssh-agent then execute the following command:
ssh-add
NOTE
You can also send �les over SSH using the scp (secure copy) command.
tail -f /var/log/secure
# might return:
If the log says Authentication refused: bad ownership or modes for directory
/home/pi there is a permission problem regarding your home directory. SSH needs your
home and ~/.ssh directory to not have group write access. You can adjust the
permissions using chmod:
Now only the user itself has access to .ssh and .ssh/authorized_keys in which the public
keys of your remote machines are stored.
ssh-add -K ~/.ssh/id_rsa
NOTE
From macOS Monterey onwards the -K �ag has been deprecated and been replaced by the
--apple-use-keychain �ag.
Secure Copy (scp) is a command for sending �les over SSH. This means you can copy �les
between computers, say from your Raspberry Pi to your desktop or laptop, or vice-versa.
Copy the �le to the /home/pi/project/ directory on your Raspberry Pi (the project folder
must already exist):
scp [email protected]:myfile.txt .
Alternatively, use a wildcard to copy all �les matching a particular search with:
scp m* [email protected]:
NOTE
Some of the examples above will not work for �le names containing spaces. Names like
this need to be enclosed in quotes:
Using rsync
Edit this on GitHub
You can use the tool rsync to synchronise folders between computers. You might want to
transfer some �les from your desktop computer or laptop to your Raspberry Pi, for
example, and for them to be kept up to date, or you might want the pictures taken by your
Raspberry Pi transferred to your computer automatically.
Using rsync over SSH allows you to transfer �les to your computer automatically.
Here is an example of how to set up the sync of a folder of pictures on your Raspberry Pi
to your computer:
mkdir camera
Look up the Raspberry Pi’s IP address by logging in to it and running hostname -I. In this
example, the Raspberry Pi is creating a timelapse by capturing a photo every minute, and
saving the picture with a timestamp in the local folder camera on its SD card.
Now run the following command (substituting your own Raspberry Pi’s IP address):
This will copy all �les from the Raspberry Pi’s camera folder to your computer’s new camera
folder.
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 smaller networks, an NFS is perfect for creating a simple NAS (Network-attached
storage) in a Linux/Unix environment.
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 �lesystem:
Note that /export and /export/users will need 777 permissions, as we will be accessing
the NFS share from the client without LDAP/NIS authentication. This will not apply if using
authentication (see below). Now mount the real users directory with:
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 �le /etc/idmapd.conf must
exist on both the client and the server with the same contents and with the correct domain
names. Furthermore, this �le 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, we add the following two lines
to /etc/exports:
/export 192.168.1.0/24(rw,fsid=0,insecure,no_subtree_check,async)
/export/users 192.168.1.0/24(rw,nohide,insecure,no_subtree_check,async)
The �les on your NFS are open to anyone on the network. As a security measure, you can
restrict access to speci�ed clients.
By blocking all clients �rst, 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
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.
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 �le.
To ensure this is mounted on every reboot, add the following line to /etc/fstab:
If, after mounting, the entry in /proc/mounts appears as <nfs-server-IP>:// (with two
slashes), then you might need to specify two slashes in /etc/fstab, or else umount might
complain that it cannot �nd the mount.
rpcbind : ALL
By blocking all clients �rst, 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 �les. 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 con�guration, and will not
be addressed here.
Group permissions
A user’s �le access is determined by their membership of groups on the client, not on the
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 �rst, 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 �ushed 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
By default, rpcbind only binds to the loopback interface. To enable access to rpcbind from
remote machines, you need to change /etc/conf.d/rpcbind to get rid of either -l or -i
127.0.0.1.
If any changes are made, rpcbind and NFS will need to be restarted:
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 �les. 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 tra�c to the server with the server’s public key, and the server
sends back all replies encrypted with the client’s public key. The tra�c 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 �rst:
rmdir /home/user/Music
ln -s /nfs/music/ /home/user/Music
Samba (SMB/CIFS)
Edit this on GitHub
You can use Samba to mount a folder shared from a Windows machine so it appears on
your Raspberry Pi, or to share a folder from your Raspberry Pi so it can be accessed by
your Windows machine.
Turn on sharing
1. Open the Networking and Sharing Centre by right-clicking on the system tray and
selecting it
5. Save changes
You can share any folder you want, but for this example, simply create a folder called
share.
3. Click on the Sharing tab, and then the Advanced Sharing button
4. Select Share this folder; by default, the share name is the name of the folder
�. For this example, select Everyone and Full Control (you can limit access to speci�c
users if required); click OK when done, then OK again to leave the Advanced Sharing
page
7. Click on the Security tab, as we now need to con�gure the same permissions
�. Select the same settings as the Permissions tab, adding the chosen user if
necessary
9. Click OK
On Windows 10 there is a Sharing Wizard that helps with some of these steps.
3. Right-click and select New Share, which will start up the Sharing Wizard; click Next
�. Select Custom and set the required permissions, and click OK, then Finish
Mounting in Linux is the process of attaching a folder to a location, so �rstly we need that
location.
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.
You should now be able to view the content of the Windows share on your Raspberry Pi.
cd windowshare
ls
This error is caused by a combination of two things: A SMB protocol version mismatch,
and the CIFS client on Linux returning a misleading error message. In order to �x this a
version entry needs to be added to the mount command. By default Raspberry Pi OS will
only use versions 2.1 and above, which are compatible with Windows 7 and later. Older
devices, including some NAS, may require version 1.0:
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 that there is a pi user when accessing that folder. When asked,
enter the password of the pi user - this can be the default password, but that is well known
and should be changed for better security.
sudo smbpasswd -a pi
Now we need to tell Samba to share this folder, using the Samba con�guration �le.
At the end of the �le, add the following to share the folder, giving the remote user
read/write permissions:
[share]
path = /home/pi/shared
read only = no
public = yes
writable = yes
In the same �le, �nd the workgroup line, and if necessary, change it to the name of the
workgroup of your local Windows network.
That should be enough to share the folder. On your Windows device, when you browse the
network, the folder should appear and you should be able to connect to it.
Sometimes it is not convenient to work directly on the Raspberry Pi. Maybe you would like
to work on it from another device by remote control.
VNC is a graphical desktop sharing system that allows you to remotely control the desktop
interface of one computer (running VNC Server) from another computer or mobile device
(running VNC Viewer). VNC Viewer transmits the keyboard and either mouse or touch
events to VNC Server, and receives updates to the screen in return.
You will see the desktop of the Raspberry Pi inside a window on your computer or mobile
device. You’ll be able to control it as though you were working on the Raspberry Pi itself.
VNC Connect from RealVNC is included with Raspberry Pi OS. It consists of both VNC
Server, which allows you to control your Raspberry Pi remotely, and VNC Viewer, which
allows you to control desktop computers remotely from your Raspberry Pi should you
want to.
You must enable VNC Server before you can use it. By default, VNC Server gives you
remote access to the graphical desktop that is running on your Raspberry Pi, as though
you were sitting in front of it.
However, you can also use VNC Server to gain graphical remote access to your Raspberry
Pi if it is headless or not running a graphical desktop. For more information on this, see
Creating a virtual desktop, further below.
If you are not using a desktop you can install it from the command line as follows:
You can enable VNC Server at the command line using raspi-con�g:
sudo raspi-config
Direct connections are quick and simple providing you’re joined to the same private local
network as your Raspberry Pi. For example, this might be a wired or wireless network at
home, at school, or in the o�ce.
• On your Raspberry Pi (using a terminal window or via SSH) use these instructions or
run ifconfig to discover your private IP address.
• On the device you’ll use to take control, download VNC Viewer. For best results, use
the compatible app from RealVNC.
You are entitled to use RealVNC’s cloud service for free, provided that remote access is for
educational or non-commercial purposes only.
Cloud connections are convenient and encrypted end-to-end. They are highly
recommended for connecting to your Raspberry Pi over the internet. There’s no �rewall or
router recon�guration, and you don’t need to know the IP address of your Raspberry Pi, or
provide a static one.
• Sign up for a RealVNC account here: it’s free and it only takes a few seconds.
• On your Raspberry Pi, sign in to VNC Server using your new RealVNC account
credentials:
• On the device you’ll use to take control, download VNC Viewer. You must use the
compatible app from RealVNC.
• Sign in to VNC Viewer using the same RealVNC account credentials, and then either
tap or click to connect to your Raspberry Pi:
To complete either a direct or cloud connection, you must authenticate to VNC Server.
If you’re connecting from the compatible VNC Viewer app from RealVNC, enter the user
name and password you normally use to log in to your user account on the Raspberry Pi.
By default, these credentials are pi and raspberry.
If you’re connecting from a non-RealVNC Viewer app, you’ll �rst need to downgrade VNC
Server’s authentication scheme, specify a password unique to VNC Server, and then enter
that instead.
• If you are in front of your Raspberry Pi and can see its screen, open the VNC Server
dialog on your Raspberry Pi, select Menu › Options › Security, and choose VNC
password from the Authentication dropdown.
• Or if you’re con�guring your Raspberry Pi remotely from the command line, then to
make the changes for Service Mode (the default con�guration for the Raspberry Pi):
◦ In the command line, run sudo vncpasswd -service. This will prompt you to
set a password, and will insert it for you in the right con�g �le for VNC Server
running in Service Mode.
• On the device you’ll use to take control, run VNC Viewer and connect.
NOTE
Existing connections must be restarted in order for these changes to take effect.
Please note that direct screen capture is an experimental feature. If you’re connecting from
a desktop computer and mouse movements seem erratic, try pressing F8 to open the VNC
Viewer shortcut menu and selecting Relative Pointer Motion.
If your Raspberry Pi is headless (i.e. not plugged into a monitor) or controlling a robot, it is
unlikely to be running a graphical desktop.
VNC Server can create a virtual desktop for you, giving you graphical remote access on
demand. This virtual desktop exists only in your Raspberry Pi’s memory:
• On your Raspberry Pi (using Terminal or via SSH), run vncserver. Make note of the IP
address/display number that VNC Server will print to your Terminal (e.g.
192.167.5.149:1).
• On the device you’ll use to take control, enter this information into VNC Viewer.
This will also stop any existing connections to this virtual desktop.
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 �les over HTTP, and with additional modules can
serve dynamic web pages using scripting languages such as PHP.
Installing 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 �le on the �lesystem. 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
total 12
drwxr-xr-x 2 root root 4096 Jan 8 01:29 .
drwxr-xr-x 12 root root 4096 Jan 8 01:28 ..
-rw-r--r-- 1 root root 177 Jan 8 01:29 index.html
This shows that by default there is one �le 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 �le, you need to
change its ownership to your own username. Change the owner of the �le (the default pi
user is assumed here) using sudo chown pi: index.html.
You can now try editing this �le and then refreshing the browser to see the web page
change. If you know HTML you can put your own HTML �les 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 con�guration.
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.
Client Con�guration
Raspberry Pi 3 Model B
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 con�g 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 con�guration is almost done. The �nal 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.
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
Server Con�guration
Plug the SD card into the server Raspberry Pi, and then boot the server. The client
Raspberry Pi will need a root �le system to boot from: we will use a copy of the server’s
root �lesystem and place it in /nfs/client1:
Regenerate SSH host keys on the client �lesystem 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 �nd the address of your router (or
gateway), which can be done with:
Then run:
The �rst 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 �nd this with:
cat /etc/resolv.conf
Con�gure 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:
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
Now you need to modify the dnsmasq con�guration 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 �rst address of the dhcp-range line is, use the broadcast address you noted
down earlier.
tail -F /var/log/daemon.log
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
This should now allow your Raspberry Pi client to attempt to boot through until it tries to
load a root �le system (which it doesn’t have).
At this point, export the /nfs/client1 �le system created earlier, and the TFTP boot folder.
Restart RPC-Bind and the NFS server in order to have them detect the new �les.
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:
Good luck! If it doesn’t boot on the �rst attempt, keep trying. It can take a minute or so for
the Raspberry Pi to boot, so be patient.
Using pxetools
We have created a Python script that is used internally to quickly set up Raspberry Pis that
will network boot.
The script takes a serial number, which you can �nd in cat /proc/cpuinfo, an owner name
and the name of the Raspberry Pi. It then creates a root �lesystem for that Raspberry Pi
from a Raspberry Pi OS image. There is also a --list option which will print out the IP
address of the Raspberry Pi, and a --remove option.
NOTE
The following instructions describe how to set up the environment required by the
script starting from a fresh Raspberry Pi OS lite image. It might be a good idea to
mount a hard disk or �ash drive on /nfs so that your SD card isn’t providing
�lesystems to multiple Raspberry Pis. This is left as an exercise for the reader.
wget https://datasheets.raspberrypi.com/soft/prepare_pxetools.sh
bash prepare_pxetools
The prepare_pxetools script should prepare everything you need to use pxetools.
We found that we needed to restart the nfs server after using pxetools for the �rst time.
Do this with:
1. The bootloader negotiates to get an IP address and the details of a TFTP server
using DHCP.
2. The bootloader loads the �rmware via TFTP and hands over the boot process to the
�rmware, passing it the details of the network.
3. The �rmware loads the kernel and command line via TFTP.
4. The kernel boots the rest of the system, loading the root �lesystem (rootfs) via NFS
or some other mechanism.
The bootloader and �rmware (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 �rmware (e.g. start4.elf) and the
bootloader. Using the Bullseye release of Raspberry Pi OS and the latest stable bootloader
should be su�cient.
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 �rst 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 �ag which tells it whether to use stateful (managed)
or stateless (unmanaged) con�guration for its IP address. Stateless con�guration means
that the device con�gures its own IP address. Currently the bootloader generates an
address derived from its ethernet MAC address and a network pre�x supplied by the
router.
If the router indicates that stateful con�guration 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 con�guration, 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 Con�guration Protocol for IPv6 documentation.
Boot process
The device should now have an IP address and TFTP details. It downloads the �rmware
binary start4.elf from the TFTP server and continues running with this. The �rmware 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 �le 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 �les (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 con�gured to supply some made up unique local
addresses (ULA). The host test-rpi4 line tells DHCP to give a test device a �xed address.
not authoritative;
subnet6 fd49:869:6f93::/64 {
host test-rpi4 {
host-identifier option dhcp6.client-id 00:03:00:01:e4:5f:01:20:
24:0b;
fixed-address6 fd49:869:6f93::1000;
}
}
interface eth0
static ip6_address=fd49:869:6f93::1/64
Bootloader
Modify the con�guration 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 pre�x, 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 con�gured to use stateless con�guration where
clients generate their own addresses.
You might be able to con�gure your router for stateful con�guration, which means it will
use DHCP to obtain an IP address.
Debugging
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
Finally the bootloader hands over to �rmware which should load the kernel.
Stateful con�guration
Below is an extract of a TCP dump where the router is con�gured to use stateful (DHCP)
network con�guration.
The device sends a request for an address and TFTP details to the DHCP server.
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 con�guration
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.