What we want to do
I would like to setup a Raspberry Pi (RPi) from scratch running raspbian, but doing it without an attached keyboard or display.
Preparing the SD Card
To get you up and running a SD with raspbian a Debian variant built for the RPi is needed. How it is prepared is well documented on the raspberry pi website:
After the flashing of the SD card is complete, a new partition called boot should show up. The RPi will be later accessed via SSH, therefore the SSH server has to be started in the RPi’s boot process. To configure it to do so, an empty file called ssh has to be placed in the boot partition. It has to have no extension.
If you plan to connect the RPi to the network via wireless networking it has to know the network name (SSID) and the credentials to connect. To also provide this information upfront, a second configuration file on the boot partition is needed. In it the networks to connect to are defined.
Now everything is ready for the first boot of the freshly prepared image.
Before booting, the RPi is connected via an ethernet cable directly to a host computer. Please make sure, that IPv6 is enabled on this computer. Then power up the RPi by attaching an approbiate power supply. The red LED should light up and the green one should flash indicating SD card access. Furthermore, the LEDs on the Ethernet Port should light up to confirm a link to the host computer.
How does one know the IP address to connect to the RPi’s SSH server?
There are several option: the cheating solution would be to attach a monitor or TV via HDMI, but this is not truely headless anymore. Another possibility is the mDNS protocol. If running macOS or a linux or windows with mDNS enable, try to ping the default hostname raspberrypi.local. This is the easiest way to connect as no IP address has to be known as the RPi announces itself on the network via mDNS.
If this fails, there is also an alternative route using a feature defined in the IPv6 protocol. This will work with any IPv6-enabled host computer. The RPi has the IPv6 protocol enabled by default.
We will use a special link-local multicast address which is defined as the all nodes address that means that every connected device to the same network will answer. Link-local addresses are valid only for one defined network interface, so one ethernet port or a WLAN. In our case the network connected to the ethernet port just consists of two devices: the host computer and the RPi. The idea is now to send a ping to all attached hosts using the special IPv6 address ff02::1%<name of interface>.
To execute the ping, start up a terminal and use the
ip a command to find out how the interface is called the RPi is connected to. In the case of my mac, the ethernet interface used to connect to the RPi is called en4. Therefore the command was as follows:
PING6(56=40+8+8 bytes) fe80::aaaa:bbbb:cccc:dddd%en4 --> ff02::1%en4 16 bytes from fe80::aaaa:bbbb:cccc:dddd%en4, icmp_seq=0 hlim=64 time=0.256 ms 16 bytes from fe80::ca1b:6999:e36:4d7c%en4, icmp_seq=0 hlim=64 time=0.658 ms
This result shows that when the special all nodes address is pinged, two hosts answer, the own link-local IPv6 address (fe80::aaaa:bbbb:cccc:dddd%en4) and the address of the RPi (fe80::ca1b:6999:e36:4d7c%en4). Please note that the interface identifier is part of this link-local address.
Connecting to the RPi via SSH
With the know address, connecting to the RPi is easy. Use the ssh-client on the terminal with the determined address (in this case an IPv6 link-local address):
ssh email@example.com(if mDNS is enabled)
Use the default password raspberry to log in. Then type in passwd and change the default passwort immediately.
You can now use the
ifconfig command to find out the address of the WLAN interface for example.
Finalizing Network Setup
If the RPi is going to be connected via cable its link-local address (fe80::ca1b:6999:e36:4d7c) stays the same. Care has to be taken that the correct output interface on the host computer is chosen, e.g. if the RPi is connected via cable but the host computer is connected to the network via a WLAN interface called en0, the correct link-local IPv6 address would then be fe80::ca1b:6999:e36:4d7c%en0.