[Raspberry Pi 3] Installing Ubuntu 18.04 LTS (No Keyboard or Display Required)

Linux

A memo from setting up a home server on a Raspberry Pi.
This covers installing Ubuntu on the Raspberry Pi and logging in from a PC over SSH.

Update: I wrote the memo from trying this on a Raspberry Pi 4 here.[Raspberry Pi 4] Headless Install of Ubuntu 20.10: How to Install Without a Keyboard or Display

washi
washi

The method I used on the Raspberry Pi 4 is easier, so I recommend that one.

Test Environment

Raspberry Pi 3
Ubuntu 18.04.04 LTS 32-bit
16GB Transcend microSD card

Download and Install Ubuntu

Download the OS image from https://ubuntu.com/download/raspberry-pi . Since the Raspberry Pi 3 has little memory, the benefit of choosing 64-bit is limited, so I downloaded 32-bit this time.

Extract the downloaded ubuntu-18.04.4-preinstalled-server-armhf+raspi3.img.xz file (7Zip on Windows, gunzip on macOS) and write it to the SD card.
The official site describes how to write it on Ubuntu, Windows, and macOS. The procedure using diskutil or dd is a little troublesome, so in my case I rename the extracted img extension to bin and write it to the SD card with the Chromebook Recovery Utility.

$ gunzip ubuntu-18.04.4-preinstalled-server-armhf+raspi3.img.xz
$ mv ubuntu-18.04.4-preinstalled-server-armhf+raspi3.img ubuntu-18.04.4-preinstalled-server-armhf+raspi3.bin 

You can select a local image from the gear button in the upper right, so select the extracted and renamed Raspberry Pi image.

Select the SD card slot to write to.

Press the "Create now" button to start writing. (Administrator privileges are required.)

It finishes in about three minutes.

Me
Me

Writing to the SD card is easy on both Mac and Windows if you use the Chromebook Recovery Utility. Since I will only connect power to the Raspberry Pi, I will do a little more setup on the PC side.

If you remove the SD card and insert it into the Raspberry Pi, Ubuntu will boot.
However, this time there is no keyboard or display on the Raspberry Pi, so before booting Ubuntu, configure Wi-Fi with a static IP so that SSH connections are possible immediately after boot.

Configure the Network Before Booting

On the SD card's system-boot partition, there is a file called network-config, and you can configure network settings for startup there.
Open it in an editor and set the Wi-Fi settings: SSID, password, static IP, and default gateway. If using wired LAN, I think setting a static IP for eth0 is enough.

# This file contains a netplan-compatible configuration which cloud-init
# will apply on first-boot. Please refer to the cloud-init documentation and
# the netplan reference for full details:
#
# https://cloudinit.readthedocs.io/
# https://netplan.io/reference
#
# Some additional examples are commented out below

version: 2 ethernets: eth0: dhcp4: true optional: true wifis: wlan0: dhcp4: false gateway4: 192.168.11.254 nameservers: addresses: - 192.168.11.254 addresses: - 192.168.11.3/24 optional: false access-points: HomeSSID-012345: password: “HomePassword012345”

#wifis:

wlan0:

dhcp4: true

optional: true

access-points:

homessid:

password: “S3kr1t”

myotherlan:

password: “correct battery horse staple”

workssid:

auth:

key-management: eap

method: peap

identity: “me@example.com

password: “passw0rd”

ca-certificate: /etc/my_ca.pem

Memo:
Wi-Fi did not connect unless wlan0 was set to optional: false. Maybe it is a timing issue?

User Settings

If you edit the file called user-data on the SD card, you can configure users and similar settings. I wanted to delete the ubuntu user and use a different user ID, but it does not seem possible here. First I will log in as the ubuntu user, then rename the ubuntu user afterward. I have not tried it, but it looks like users can be added in the users: section and packages can be added in the packages: section.

#cloud-config

This is the user-data configuration file for cloud-init. By default this sets

up an initial user called “ubuntu” with password “ubuntu”, which must be

changed at first login. However, many additional actions can be initiated on

first boot from this file. The cloud-init documentation has more details:

https://cloudinit.readthedocs.io/

Some additional examples are provided in comments below the default

configuration.

Enable password authentication with the SSH daemon

ssh_pwauth: true

On first boot, set the (default) ubuntu user’s password to “ubuntu” and

expire user passwords

どうせ後で変えるから初回ログイン時のパスワード変更はしない

chpasswd: expire: false list:

  • ubuntu:ubuntu

Add users and groups to the system, and import keys with the ssh-import-id

utility

#groups: #- robot: [robot] #- robotics: [robot] #- pi

#users: #- default #- name: robot

gecos: Mr. Robot

primary_group: robot

groups: users

ssh_import_id: foobar

lock_passwd: false

passwd: $5$hkui88$nvZgIle31cNpryjRfO9uArF7DYiBcWEnjqq7L1AQNN3

Update apt database and upgrade packages on first boot

#package_update: true #package_upgrade: true

Install additional packages on first boot

#packages: #- pwgen #- pastebinit #- [libpython2.7, 2.7.3-0ubuntu3.1]

Write arbitrary files to the file-system (including binaries!)

#write_files: #- path: /etc/default/keyboard

content: |

# KEYBOARD configuration file

# Consult the keyboard(5) manual page.

XKBMODEL=“pc105”

XKBLAYOUT=“gb”

XKBVARIANT=""

XKBOPTIONS=“ctrl: nocaps”

permissions: ‘0644’

owner: root:root

#- encoding: gzip

path: /usr/bin/hello

content: !!binary |

H4sIAIDb/U8C/1NW1E/KzNMvzuBKTc7IV8hIzcnJVyjPL8pJ4QIA6N+MVxsAAAA=

owner: root:root

permissions: ‘0755’

Run arbitrary commands at rc.local like time

#runcmd: #- [ ls, -l, / ] #- [ sh, -xc, “echo $(date) ‘: hello world!’” ] #- [ wget, “http://ubuntu.com”, -O, /run/mydir/index.html ]

Save the settings and boot the Raspberry Pi, and you can connect over SSH. Wait for it to start while running ping from the PC. If you can connect with PuTTY or similar, it is OK.
The Raspberry Pi only needs to be powered on. After that, it is easier to perform the remaining setup from the PC.

Me
Me

If you expose it externally while leaving the user ID as ubuntu, it will definitely become a cracking target. Before publishing it, change the user ID, disable password login, configure fail2ban, and so on.