Perl programmer for hire: download my resume (PDF).
John Bokma's Hacking & Hiking

Wireless Headless Raspberry Pi

October 17, 2019

Today I set up a wireless, headless, Raspberry Pi 3B. This was easier than expected, it worked at the first try. The following instructions are for preparing an SD card on macOS for booting a headless and wireless Pi.

Downloading and verifying the SD card image

First I downloaded Raspbian Buster Lite from the official Raspbian download page. I selected the Lite version as I don't need a desktop for this specific headless setup.

When clicking the download button I held the Command button on the keyboard to prevent Safari from automatically unzipping the download. This way I could verify the integrity of the downloaded zip file using:

shasum -a 256 2019-09-26-raspbian-buster-lite.zip

The digest reported matched the one given on the Raspbian page for the Raspbian Buster Lite Minimal image based on Debian Buster:

a50237c2f718bd8d806b96df5b9d2174ce8b789eda1f03434ed2213bbca6c6ff

Writing the Image to the SD Card

I used diskutil to obtain the identifier of the SD card I had plugged into my Mac mini:

diskutil list

The following output was given for the 32GB SD card I had inserted:

/dev/disk3 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *31.9 GB    disk3
   1:             Windows_FAT_32 NO NAME                 31.9 GB    disk3s1

To be on the safe side I had unplugged all external disks, but from the above it's obvious that this is a 32GB SD card. It's identifier is disk3. Don't use disk3s1 in the commands below, as this is the partition.

Note that the identifier on your computer might be different. Make sure to modify the commands below accordingly.

First, I unzipped the downloaded file to obtain the image file:

unzip 2019-09-26-raspbian-buster-lite.zip

Next, I unmounted the SD card as follows:

diskutil unmountDisk /dev/disk3

Now I could write the image file to the SD card as follows. If you copy these steps make very sure you use the correct identifier!

sudo dd bs=1m if=2019-09-26-raspbian-buster-lite.img of=/dev/rdisk3 conv=sync

On my computer this took just 108 seconds. After this operation the card should be mounted automatically by macOS. At least that was the case on my system.

Configuring the Boot Image

To configure the boot image I changed the working directory to the "root" directory of the SD card, which is named boot:

cd /Volumes/boot/

SSH

To enable SSH an empty file named ssh must be present. I created this empty file as follows:

touch ssh

This file is used to configure SSH during the first boot and deleted afterwards by the operating system.

Wi-Fi

To make it possible to login over Wi-Fi I create a file named wpa_supplicant.conf based on the following template:

country=us
update_config=1
ctrl_interface=/var/run/wpa_supplicant

network={
 ssid="<Name of your WiFi>"
 psk="<Password for your WiFi>"
}

As I am currently living in the Netherlands I used the following file:

country=nl
update_config=1
ctrl_interface=/var/run/wpa_supplicant

network={
 ssid="LakeSide"
 psk="hunter2"
}

Well, except for the password, hunter2.

During the first boot this file is moved to /etc/wpa_supplicant/, see below.

First Boot

With these steps done, I moved to a working directory not located on the SD card and ejected it:

cd ~
sudo diskutil eject /dev/rdisk3

I inserted the SD card into the Raspberry Pi and turned the little computer on; first boot.

Obtaining the IP address

To connect via SSH I needed the IP address of the Raspberry Pi. Because multicast DNS is supported by Raspbian out of the box ping -c1 raspberrypi.local should give the IP address on macOS:

Johns-Mac-mini:~ john$ ping -c1 raspberrypi.local
PING raspberrypi.local (192.168.11.115): 56 data bytes
64 bytes from 192.168.11.115: icmp_seq=0 ttl=64 time=6.747 ms

--- raspberrypi.local ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 6.747/6.747/6.747/0.000 ms

Note that the -c1 option makes that ping stops by itself after one roundtrip.

If this works, and it should on macOS, you can reach the Raspberry Pi using ssh pi@raspberrypi.local.

Another way to obtain the IP address is using nmap:

sudo nmap -sS -p 22 192.168.11.0/24

This checks if in the range 192.168.11.0 - 192.168.11.255 port 22 (SSH) is open. On Ubuntu, running in a virtual machine on my Mac mini, this reported for IP address 192.168.11.115:

Nmap scan report for 192.168.11.115
Host is up (-0.047s latency).

PORT   STATE SERVICE
22/tcp open  ssh
MAC Address: B8:27:EB:xx:xx:xx (Raspberry Pi Foundation)

I tried ssh pi@192.168.11.115 with the default password; raspberry, and it worked!

Security

To improve the security of the little computer I first changed the default password of the SSH account to something else (no, not hunter2) with the passwd command.

Next, I made the Wi-Fi password harder to get at. First I used wpa_passphrase with the SSID of the Wi-Fi network, and entered the password:

wpa_passphrase LakeSide
# reading passphrase from stdin
hunter2!
network={
	ssid="LakeSide"
	#psk="hunter2!"
	psk=62665d453bfcaefd7852262428b32ea9253b3305f68d16d363fadb5f5e18ae60
}

Next, I used vi to modify the wpa_supplicant.conf file:

sudo vi /etc/wpa_supplicant/wpa_supplicant.conf

I replaced the plain text psk value with the encrypted psk value inside this file and saved it.

Further reading