Raspberry Pi - Headless Installation

From Alpine Linux
Revision as of 00:21, 13 April 2021 by Sodface (talk | contribs)
Jump to: navigation, search


Note: On 6 Feb 2021, I updated the wifi config to just include SSID and Password, per a suggestion via email and it seems to work fine. I've updated the download also. This changes the format of the wifi.txt file originally documented and how the script reads and uses the file. Please update any existing files you are using. Tested with 3.13.1 on Pi Zero W and x86_64 Wyse 3040.

This wiki describes a method to prep an sd card for a raspberry pi so that the pi will connect to your local network on first boot and allow password-less root login over ssh to continue setup. This allows you to setup a raspberry pi without connecting a keyboard or monitor.

This method assumes that you are working from a linux machine and are already familiar with prepping an sd card with Alpine Linux for a raspberry pi. The basic procedure is to first create the sd card as normal but then also copy a one-time use overlay file into the root of the sd card. This file gets extracted on boot and creates /etc/.default_boot_services, enables the local script service, and creates a local startup script.

The local startup script attempts to read wifi ssid/credential information from a file in the same directory as the custom overlay file named wifi.txt (format described below). If the file does not exist, then eth0 is assumed.

I've tested this with Alpine Linux 3.12.0 on a RPi 4, Zero W, A+ and original model A.

You can download a pre-built overlay file from my website: http://www.sodface.com/repo/headless.apkovl.tar.gz

Create Overlay File

It is assumed that you have already extracted the Alpine Linux archive to the sd card. In a working directory on your local machine (not on the sd card) create the following directory/file structure:

[sodface@sodpro working]$ tree -a └── etc ├── .default_boot_services ├── local.d │ └── headless.start └── runlevels └── default └── local -> /etc/init.d/local

Edit etc/local.d/headless.start as follows (note that the cat heredoc identation in the functions needs to be tabs):

Contents of etc/local.d/headless.start

#!/bin/sh __create_eni() { cat <<-EOF > /etc/network/interfaces auto lo iface lo inet loopback auto ${iface} iface ${iface} inet dhcp hostname localhost EOF } __create_eww() { cat <<-EOF > /etc/wpa_supplicant/wpa_supplicant.conf network={ ssid="${ssid}" psk="${psk}" } EOF } __edit_ess() { cat <<-EOF >> /etc/ssh/sshd_config PermitEmptyPasswords yes PermitRootLogin yes EOF } __find_wint() { for dev in /sys/class/net/* do if [ -e "${dev}"/wireless -o -e "${dev}"/phy80211 ] then echo "${dev##*/}" fi done } ovlpath=$(find /media -name *.apkovl.tar.gz -exec dirname {} \;) read ssid psk < "${ovlpath}/wifi.txt" if [ ${ssid} ] then iface=$(__find_wint) apk add wpa_supplicant __create_eww rc-service wpa_supplicant start else iface="eth0" fi __create_eni rc-service networking start /sbin/setup-sshd -c openssh cp /etc/ssh/sshd_config /etc/ssh/sshd_config.orig __edit_ess rc-service sshd restart mv /etc/ssh/sshd_config.orig /etc/ssh/sshd_config

Make the headless.start file executable and create the overlay file:

[sodface@sodpro working]$ chmod +x etc/local.d/headless.start [sodface@sodpro working]$ tar czvf headless.apkovl.tar.gz etc/ etc/ etc/local.d/ etc/local.d/headless.start etc/.default_boot_services etc/runlevels/ etc/runlevels/default/ etc/runlevels/default/local

Copy the headless.apkovl.tar.gz into the root of the sd card and if using wifi, create a wifi.txt file with the following format, replacing ssid and password to match your network.

Contents of wifi.txt

ssid password

Unmount the sd card, insert into the pi and boot. Monitor your dhcp server and watch for a new lease to determine the IP address assigned to the pi.

Once you know the IP address, you should be able to ssh to the pi as root without a password and continue setup. Do not run the setup-alpine script directly since networking and sshd are already started. The setup script isn't expecting this and things go wrong during the network and repo setup steps. I would recommend running the /sbin/setup-* scripts one at a time, in the following order:

setup-ntp setup-keymap setup-hostname setup-timezone setup-apkrepos setup-lbu setup-apkcache

Set the root password and add a user that you can ssh with after the next reboot.
To make sure that new user can sudo, install sudo, run visudo and uncomment one of the lines for the wheel group, then add the new user to the wheel group.

passwd adduser USERNAME apk add sudo visudo addgroup USERNAME wheel

I would also recommend installing rng-tools and updating startup services:

apk add rng-tools rc-update add rngd boot rc-update add wpa_supplicant boot rc-update add urandom boot

You should delete the overlay file and wifi.txt file (if present) from the sd card, though by default it will be mounted read only. Remount rw to delete those files:

mount -o remount,rw /media/mmcblk0p1 rm /media/mmcblk0p1/*.apkovl.tar.gz rm /media/mmcblk0p1/wifi.txt

Remove the local script service from the default runlevel and delete the headless setup script so it's not saved when the new overlay is created later:

rc-update del local default rm /etc/local.d/headless.start

Be sure to create a new overlay file before the first reboot:

lbu commit -d reboot