1. Headless set-up

1.1. Intro

Every time I deploy a new pi, something has changed. This makes it difficult to create a simple set-up that works every time. It also means that all instructions you find on the internet are outdated. Google is great in finding set-up instructions from back in 2012, but those do not work anymore. And most instructions do not have a date in them, so you're completely lost why it doesn't work.

This instruction is made for people that have Linux running.
Version
Date
Raspian
Comment
1
28-6-2017
Jessie
2
29-12-2017
2017-11-29-raspbian-stretch
3
29-12-2017
2017-11-29-raspbian-stretch
4
19-1-2019
2018-11-13-raspbian-stretch.img
5
18-03-2020
2020-02-13-raspbian-buster

1.2. Burning the image

First get the latest Raspian:
wget http://downloads.raspberrypi.org/raspbian_latest

What you'll get is a zip-file with the latest raspian-image. Unzip and burn on the SD-card.

Many tutorials go into great length on how to identify your SD-card. In most cases, it is /dev/mmcblk0 or one of the /dev/sd* devices.
mv raspbian_latest raspbian_latest.zip
unzip raspbian_latest.zip
sudo dd if=2018-11-13-raspbian-stretch.img  of=/dev//dev/mmcblk0 status=progress

Of course, this takes a long time; that is why the status=progress is on the command line. Total is about 3.5G.

Remove the card and plug it back in. Normally, it will be mounted automatically, and you will see:
/dev/mmcblk0p1 on /run/media/ljm/boot type vfat 
/dev/mmcblk0p2 on /run/media/ljm/5c01c1ce-fe60-428a-8e68-0be0e8ed6b7a type ext4 

Otherwise, mount by hand.

For raspian-stretch, the root file system will be called rootfs instead of the big number.

1.3. The networking

Because from Jessie on, it is now using systemd, everything you knew about the configuration of networking is now of no value. In previous releases, networking was done via /etc/network/interfaces but now, dhcpcd is used. It also means that all tutorials and howto's are now obsolete.

The main configuration file for dhcpcd is /etc/dhcpcd.conf. For every connection that you want to have a fixed IP address add a block, of course with your own IP addresses:
interface eth0
static ip_address=192.168.178.53/24
static routers=192.168.178.1
static domain_name_servers=192.168.178.6
interface wlan0
static ip_address=192.168.178.3/24
static routers=192.168.178.1
static domain_name_servers=192.168.178.6

For some dark and unknown reason, you still need to edit /etc/network/interfaces to add
allow-hotplug eth0

Next, setup the wpa-supplicant in etc/wpa_supplicant/wpa_supplicant.conf :
country=GB
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="ssidforwifi"
    psk="wifipsk"
}

And that used to be enough for the network.

With the advent of Buster,I have no longer been able to boot directly with WiFi enabled. I had to plug in an ethernet cable and use raspi-config to set the WiFi country, because otherwise rfkill will not allow WiFi to start. Putting the country in the wpa_supplicant.conf has not been enough. This requires some further investigation.

1.3.1. Some notes; untried by me

To disable rfkill before boot mount the card and use mv /mnt/usr/lib/raspberrypi-sys-mods/wifi-country /mnt/usr/lib/raspberrypi-sys-mods/wifi-country+ and it won't run when you boot the card later.

You will need to define a wpa_supplicant.conf file for your particular wireless network. Put this file in the boot folder, and when the Pi first boots, it will copy that file into the correct location in the Linux root file system and use those settings to start up wireless networking. After the Pi is connected to power, make sure to wait a few (up to 5) minutes for it to boot up and register on the network. The Pi's IP address will not be visible immediately after power on, so this step is crucial to connect to it headlessly. Depending on the OS and editor you are creating this on, the file could have incorrect newlines or the wrong file extension so make sure you use an editor that accounts for this.

1.4. Enable ssh

Enabling ssh requires an ssh file in the boot directory. Normally, you see a directory
/dev/mmcblk0p1     /run/media/username/boot

if you query all mounts. So do a
touch /run/media/username/boot/ssh

and ssh will start at boot-time.

But you don't want to type passwords, so we'll distribute the keys:
cd $piroot/root
mkdir .ssh
chown root.root .ssh
chmod 700 .ssh
cp  ~/.ssh/id_rsa.pub  .ssh/authorized_keys
chmod 600 .ssh/authorized_keys

1.5. Connecting and manual actions.

If you do it in this way, everything should run and the pi should be accessible under your WiFi IP address.

Try a ssh root@192.168.178.3 (use your own IP address) and voila.

There are some manual actions to take before everything works. First, make your users that need to be present on the system. In my case, that is "ljm":
adduser ljm
mkdir /home/ljm
cp -r /root/.ssh ~ljm
chown -R ljm.ljm ~ljm/.ssh

Next item on the list: raspi-config. Use the menus to set the host name. But more importantly, under 7 Advanced Options you will find A1 Expand File system which will allow you to use the complete sd card.

Under Buster, you will need to set under
    4 Localisation Options

the Wifi country
I4 Change Wi-fi Country

otherwise, the Wifi will be disabled by rfkill.

Do not reboot after this!

Make vi our default editor:
update-alternatives --set editor /usr/bin/vim.tiny

You will also need to add the users in the sudoers-file:
ljm   ALL=(ALL)       NOPASSWD: ALL

If you want to manage your pi via Ansible, you may want to
sudo apt-get install -y aptitude

And now: reboot

1.6. Security

With this set-up you can add the pi to your local network. Not to the Internet. There are a lot of security implications that we have not considered. One of the most important is that the user pi is still present and having his default password. Also the NOPASSWD in the sudoers is practical, but a bad idea security-wise.

The goal of this part was to get the pi working; not to make it secure.

1.7. note

Raspberry Pi is a trademark of the Raspberry Pi Foundation.