diff options
author | Stefan Kreutz <mail@skreutz.com> | 2023-11-03 19:45:01 +0100 |
---|---|---|
committer | Stefan Kreutz <mail@skreutz.com> | 2023-11-03 19:45:01 +0100 |
commit | f36c7dd006864566acba130b3088dca6bdca7a41 (patch) | |
tree | 9e3e556cec33ba7309b8d216228bed7ad14649cb /posts/unattended-installation-of-alpine-linux.md | |
parent | 6ac068de55d1b1e0cff60838fd6ce57255f07a9d (diff) | |
download | blog-f36c7dd006864566acba130b3088dca6bdca7a41.tar |
Add Alpine Linux post
Diffstat (limited to 'posts/unattended-installation-of-alpine-linux.md')
-rw-r--r-- | posts/unattended-installation-of-alpine-linux.md | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/posts/unattended-installation-of-alpine-linux.md b/posts/unattended-installation-of-alpine-linux.md new file mode 100644 index 0000000..a77e55c --- /dev/null +++ b/posts/unattended-installation-of-alpine-linux.md @@ -0,0 +1,154 @@ +--- +title: "Unattended installation of Alpine Linux" +description: "How to customize Alpine Linux installation images for unattended installation." +published: 2023-11-03 +--- + +Today I would like to share a quick and dirty way to perform unattended installations of [Alpine Linux][]. +I use it to spin up offline and diskless local virtual machines on OpenBSD's built-in virtual machine monitor [`vmm(4)`][vmm] for one-off tasks such as testing or cross-compiling a piece of software. +However, the method I describe is also suitable for headless installations on your favorite single board computer, and remote installations in the cloud. + +The idea is to modify one of Alpine's official ISO 9660 images to run a custom script on boot. +The script feeds prepared answers to Alpine's main installation script, [`setup-alpine`][setup-alpine], and performs some optional adjustments. + +To begin with, download one of Alpine's installation images from the official [downloads page][downloads]. +I chose the *virtual* image because of it's small size, but you can also use the *extended* image if you like. + + $ curl --location --remote-name-all \ + https://dl-cdn.alpinelinux.org/alpine/v3.18/releases/x86_64/alpine-virt-3.18.4-x86_64{.iso,.iso.sha256,.iso.asc} + $ sha256 -c alpine-*.iso.sha256 + +If you wish to verify the PGP signature, you need to import Alpine's PGP key first. + + $ curl --location https://alpinelinux.org/keys/ncopa.asc | + gpg --import - + $ gpg --verify alpine*.iso.asc + +Next, we create a so-called *overlay file*. +This is essentially a tarball to be extracted in the file system root. +See the [wiki page][lbu] on Alpine's local backup utility. + +Create a directory for the overlay: + + $ mkdir ovl + +Enable the default boot services as described [here][custom_iso]: + + $ mkdir -p ovl/etc + $ touch ovl/etc/.default_boot_services + +Enable the `local` service. +This service will run our custom installation script on boot. + + $ mkdir -p ovl/etc/runlevels/default + $ ln -sf /etc/init.d/local ovl/etc/runlevels/default + +Configure the APK repositories in `ovl/etc/apk/repositories`: + + /media/cdrom/apks + https://dl-cdn.alpinelinux.org/alpine/v3.18/main + https://dl-cdn.alpinelinux.org/alpine/v3.18/community + +Add our custom installation script `ovl/etc/local.d/auto-setup-alpine.start`. +Feel free to adapt the script to your personal needs. +Take care though. +You cannot see the script's output on the console. + +``` +#! /bin/sh + +set -o errexit +set -o nounset + +# Uncomment to shutdown on completion. +#trap 'poweroff' EXIT INT + +# Close standard input. +exec 0<&- + +# Run only once. +rm -f /etc/local.d/auto-setup-alpine.start +rm -f /etc/runlevels/default/local + +timeout 300 setup-alpine -ef /etc/auto-setup-alpine/answers +rm -rf /etc/auto-setup-alpine + +# Disable password authentication +sed -i -e 's/^root:x:/root:*:/' -e 's/^stefan:x:/stefan:*:/' /etc/passwd +sed -i -e 's/^root:[^:]*/root:*/' -e 's/^stefan:[^:]*/stefan:*/' /etc/shadow + +apk update +apk upgrade + +apk add man-pages mandoc mandoc-apropos docs + +cat >/etc/doas.d/site.conf <<EOF +permit nopass :wheel +permit nopass keepenv root +EOF + +# Uncomment for sys install. +#sed -i -e 's/relatime/noatime/' /etc/fstab +``` + +Ensure that the script is executable: + + $ chmod 755 ovl/etc/local.d/auto-setup-alpine.start + +Put the answers for the [`setup-alpine`][setup-alpine] script into `ovl/etc/auto-setup-alpine/answers`. +Feel free to adapt the answers to your personal needs. +You can run `setup-alpine -c answers` to create a new answer file with the defaults. +Or you can [read the source][default_answers]. + +``` +KEYMAPOPTS=none +HOSTNAMEOPTS=alpine +DEVDOPTS=mdev +TIMEZONEOPTS="-z UTC" +PROXYOPTS=none +APKREPOSOPTS="-1" +SSHDOPTS=openssh +NTPOPTS="openntpd" + +# Diskless +DISKOPTS=none +LBUOPTS=none +APKCACHEOPTS=none + +# Admin user name and ssh key. +USEROPTS="-a -u -g audio,video,netdev stefan" +USERSSHKEY="ssh-rsa AAA... stefan@localhost" + +# Contents of /etc/network/interfaces +INTERFACESOPTS="auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet dhcp +" +``` + +Create the actual overlay file using GNU tar: + + $ tar --owner=0 --group=0 -czf localhost.apkovl.tar.gz -C ovl . + +Add the overlay file to the ISO 9660 image using [GNU xorriso][]. +Note that the prefix of the overlay file name must be the hostname of the target machine, in this case `localhost`. + + $ xorriso \ + -indev alpine-virt-3.18.4-x86_64.iso \ + -outdev my-alpine.iso \ + -map localhost.apkovl.tar.gz /localhost.apkovl.tar.gz \ + -boot_image any replay + +That's it. +You can boot off this image and await a completely unattended installation of Alpine Linux. + +[Alpine Linux]: https://www.alpinelinux.org/ +[setup-alpine]: https://wiki.alpinelinux.org/w/index.php?title=Alpine_setup_scripts&oldid=25337#setup-alpine +[downloads]: https://www.alpinelinux.org/downloads/ +[lbu]: https://wiki.alpinelinux.org/w/index.php?title=Alpine_local_backup&oldid=25418 +[custom_iso]: https://wiki.alpinelinux.org/w/index.php?title=How_to_make_a_custom_ISO_image_with_mkimage&oldid=25379#Create_the_ISO +[GNU xorriso]: https://www.gnu.org/software/xorriso/ +[vmm]: https://man.openbsd.org/OpenBSD-7.4/vmm +[default_answers]: https://gitlab.alpinelinux.org/alpine/alpine-conf/-/blob/80370671291376ee040e5e25c0ea38a9c0780f2a/setup-alpine.in#L81 |