Installing Ubuntu 20.04 over SSH
I obtained a home server which I wanted to install Ubuntu 1 on. There was no serial port available and the only video out is VGA. I don’t have a VGA capable display so I was stumped on how to install Ubuntu. This post outlines my failed and successful attempts in case anyone has the same problem.
Failed Attempt 1: Installing on Another Host
My first attempt was to do the installation on another computer and then attach the hard drive to the server. This might work in cases where the other computer conducting the installation and the server are very similar. However, the only other available computers to me are MacBooks. Using a MacBook to to run the installer created two problems.
First, MacBooks only have EFI boot and the installer running on the MacBook will boot via EFI. The installer detects that it has been booted by EFI and partitions the hard drive for EFI2. Unfortunately, in my case the server has no EFI support so this results in an unbootable disk.
Second, my MacBook only has WiFi and no Ethernet whereas the server only has Ethernet. The installer will create netplan files based on the network devices available to the installer, meaning that there is no netplan
file created to activate the Ethernet link and enable DHCP. Even if the hard drive was bootable on the server, it wouldn’t be able to get an IP address on start.
The combination of above meant that I couldn’t run the installer on my MacBook and then attach the hard drive to the server.
Failed Attempt 2: “Connecting to the installer over SSH”
The Ubuntu Server documentation says that it’s possible to connect to the installer over SSH:
If the only available terminal is very basic, an alternative is to connect via SSH. If the network is up by the time the installer starts, instructions are offered on the initial screen in basic mode. Otherwise, instructions are available from the help menu once networking is configured.
The help screen of the installer does list instructions on how to ssh into the host as the installer
user. However the subiquity
installer has a code snippet to generate a random password every time the installer is run:
Without serial or VGA access to the host, it’s not possible to see the generated password and therefore ssh into the installer.
What what actually worked
The only thing that worked for me was to modify the ISO to hard code the password of the installer
user. It’s possible to do this because the Ubuntu Server documentation describes how the installation can be automated with cloud-init
. The documentation suggests how to set up a user-data
file that can fully automate the installer like so:
I didn’t want to autoinstall but I realized that the user-data
file also supports a chpasswd
section to set the password of a user. With this, it’s possible to create a user-data
file like this:
Which will have cloud-init
set the password of the installer
user to ubuntu
. To have the installer use this file, I needed to provide a nocloud cloud-init
datasource. This means I needed to create a new Ubuntu Server ISO which has the above user-data
file in it.
Creating a new ISO
To create a new ISO I first fetched a live-server
ISO. Then extract it into a temporary directory:
Inside the iso
directory I created a new directory called nocloud
and placed the user-data
file and an empty meta-data
file.
Then for the following files in the ISO:
isolinux/txt.cfg
boot/grub/grub.cfg
boot/grub/loopback.cfg
I changed the kernel parameters to have ds=nocloud;s=/cdrom/nocloud
set. These flags will be passed to cloud-init
which will discover our user-data
file and run chpasswd
. I then made a new ISO by running:
The resulting myiso.iso
can be imaged on to a USB key, and inserted to the server. Once the server has obtained and IP address it’s possible to ssh into the host with the user name installer
and password ubuntu
. The subiquity
installer will start up automatically.
Conclusion
It’s possible to install Ubuntu on a headless machine and use the installer over SSH by building a new ISO. This ISO passes in a configuration file for cloud-init
which sets the password to the installer
user. Once the installer has booted on the machine, just SSH in as the installer
user.