Finished provisioning and installation sections of alpine-server setup.
This commit is contained in:
parent
2a4df0dab4
commit
7f039d4f55
3 changed files with 236 additions and 1 deletions
|
@ -1,3 +1,3 @@
|
||||||
# An Alpine Linux server installation
|
# An Alpine Linux server installation
|
||||||
|
|
||||||
This is a relatively simple and easy setup for an [Alpine Linux](https://www.alpinelinux.org/) server. Alpine Linux makes a good base for a server because of its simplicity, lightweightness and security. Check out the [Alpine Linux wiki](https://wiki.alpinelinux.org/wiki/Main_Page) for additional resources and information.
|
This guide will demonstrate how to install [Alpine Linux](https://www.alpinelinux.org/) for server application. With tpm encryption, secureboot, a copy on write filesystem and Podman to handle containers. Alpine Linux makes a good base for a server because of its simplicity, lightweightness and security. Check out the [Alpine Linux wiki](https://wiki.alpinelinux.org/wiki/Main_Page) for additional resources and information.
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
To install the Alpine Linux distribution on the system, the main partition and the efi partition have to be mounted to the main system.
|
||||||
|
|
||||||
|
```
|
||||||
|
# mount -o subvol=@root /dev/mapper/luks /mnt -t btrfs
|
||||||
|
# mkdir /mnt/efi -p
|
||||||
|
# mount /dev/<disk>1 /mnt/efi -t vfat
|
||||||
|
```
|
||||||
|
|
||||||
|
Then set up the base system using `setup disk`:
|
||||||
|
|
||||||
|
```
|
||||||
|
# setup-disk -m sys /mnt
|
||||||
|
```
|
||||||
|
|
||||||
|
This will also add grub as bootloader which will be replaced but for now it will reside on the boot partition.
|
||||||
|
|
||||||
|
To make it possible to chroot into the system, mount the other directories:
|
||||||
|
|
||||||
|
```
|
||||||
|
# for i in dev proc sys run; do
|
||||||
|
> mount --rbind --make-rslave /$i /mnt/$i
|
||||||
|
> done
|
||||||
|
# chroot /mnt
|
||||||
|
```
|
||||||
|
|
||||||
|
The other setup scripts can be used to configure key aspects of the system. Besides that a few necessary services have to be activated.
|
||||||
|
|
||||||
|
```
|
||||||
|
# setup-hostname <hostname>
|
||||||
|
# setup-keymap us us-euro
|
||||||
|
# setup-timezone -i <area>/<subarea>
|
||||||
|
# setup-ntp openntpd
|
||||||
|
# rc-update add acpid default
|
||||||
|
# rc-update add seedrng boot
|
||||||
|
# rm -rf /var/tmp ; ln -s /tmp /var/tmp
|
||||||
|
# passwd root
|
||||||
|
```
|
||||||
|
|
||||||
|
> The root password does not really matter because it is going to be locked after a user has been created.
|
||||||
|
|
||||||
|
Set the `hwclock` to use `UTC` in `/etc/conf.d/hwclock` and disable writing the time to hardware. Running a NTP negates its usability.
|
||||||
|
|
||||||
|
```
|
||||||
|
clock="UTC"
|
||||||
|
clock_hctosys="NO"
|
||||||
|
clock_systohc="NO"
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit `/etc/fstab` for correct mounts:
|
||||||
|
|
||||||
|
```
|
||||||
|
/dev/disk/by-label/efi /efi vfat defaults,nodev,nosuid,noexec 0 2
|
||||||
|
/dev/disk/by-label/main / btrfs defaults,noatime,subvol=/@root 0 1
|
||||||
|
/dev/disk/by-label/main /home btrfs defaults,noatime,nosuid,nodev,subvol=/@home 0 2
|
||||||
|
/dev/disk/by-label/main /var btrfs defaults,nodev,nosuid,noexec,subvol=/@var 0 2
|
||||||
|
/dev/disk/by-label/main /nix btrfs defaults,noatime,nodev,nosuid,subvol=/@nix 0 2
|
||||||
|
tmpfs /tmp tmpfs rw,size=4G,nr_inodes=5k,noexec,nodev,nosuid,mode=1777 0 0
|
||||||
|
proc /proc proc nosuid,nodev,noexec,hidepid=2 0 0
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Alpine Linux uses `mkinitfs` to create an initial ram filesystem, although it is minimal that also means that it lacks some functionality which is needed for a proper setup. Because of this `mkinitfs` and `grub-efi `will be replaced with `booster` and `secureboot-hook`.
|
||||||
|
|
||||||
|
```
|
||||||
|
# apk add booster secureboot-hook sbctl
|
||||||
|
# apk del mkinitfs grub-efi
|
||||||
|
```
|
||||||
|
|
||||||
|
To configure booster edit `/etc/booster.yaml`:
|
||||||
|
|
||||||
|
```
|
||||||
|
busybox: false
|
||||||
|
modules: vfat,nls_cp437,nls_iso8859_1
|
||||||
|
```
|
||||||
|
|
||||||
|
The most important step is the creation of a UKI using `secureboot-hook` which also automatically signs them. First the hook itself will have to be tweaked to use `booster` instead of `mkinitfs`, edit `/etc/kernel-hooks.d/50-secureboot.hook` and change the line:
|
||||||
|
|
||||||
|
```
|
||||||
|
/sbin/mkinitfs -o "$tmpdir"/initramfs "$NEW_VERSION-$FLAVOR"
|
||||||
|
```
|
||||||
|
|
||||||
|
to:
|
||||||
|
|
||||||
|
```
|
||||||
|
/usr/bin/booster build "$tmpdir"/initramfs --kernel-version "$NEW_VERSION-$FLAVOR"
|
||||||
|
```
|
||||||
|
|
||||||
|
and configure `/etc/kernel-hooks.d/secureboot.conf` for cmdline and secureboot.
|
||||||
|
|
||||||
|
```
|
||||||
|
cmdline="rw rd.luks.name=<uuid>=luks root=/dev/disk/by-label/main rootflags=subvol=/@root quiet splash"
|
||||||
|
|
||||||
|
signing_cert="/usr/share/secureboot/keys/db/db.pem"
|
||||||
|
signing_key="/usr/share/secureboot/keys/db/db.key"
|
||||||
|
|
||||||
|
output_dir="/efi/EFI/Linux"
|
||||||
|
|
||||||
|
output_name="alpine-linux-{flavor}.efi"
|
||||||
|
```
|
||||||
|
|
||||||
|
Here `<uuid>` has to be replaced with the uuid of the partition which contains the volume group:
|
||||||
|
|
||||||
|
```
|
||||||
|
# blkid /dev/<disk>2 >> /etc/kernel-hooks.d/secureboot.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `sbctl` to create secureboot keys and sign them.
|
||||||
|
|
||||||
|
```
|
||||||
|
# sbctl create-keys
|
||||||
|
# sbctl enroll-keys
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
> Whilst enrolling the keys it might be necessary to add the `--microsoft` flag if you are unable to use custom keys.
|
||||||
|
|
||||||
|
Now to see if everything went succesfully run:
|
||||||
|
|
||||||
|
```
|
||||||
|
# apk fix kernel-hooks
|
||||||
|
```
|
||||||
|
|
||||||
|
and it should give no warnings if done properly.
|
||||||
|
|
||||||
|
As discussed earlier `grub` will be replaced, install `gummiboot` as a bootloader.
|
||||||
|
|
||||||
|
```
|
||||||
|
# apk add gummiboot
|
||||||
|
# gummiboot install --path=/efi
|
||||||
|
# sbctl sign -s /efi/EFI/gummiboot/gummibootx64.efi
|
||||||
|
# sbctl sign -s /efi/EFI/Boot/BOOTX64.EFI
|
||||||
|
```
|
||||||
|
|
||||||
|
And also remove some remnants of `grub`.
|
||||||
|
|
||||||
|
```
|
||||||
|
# rm -rf /efi/EFI/alpine
|
||||||
|
# rm -rf /efi/grub
|
||||||
|
# rm -rf /etc/default
|
||||||
|
# cd /boot && unlink boot
|
||||||
|
```
|
||||||
|
|
||||||
|
`gummiboot` can be configured with the file `/efi/loader/loader.conf` with which the timeout and the default OS can be specified.
|
||||||
|
|
||||||
|
```
|
||||||
|
default alpine-linux-lts.efi
|
||||||
|
timeout 2
|
||||||
|
editor no
|
||||||
|
```
|
||||||
|
|
||||||
|
Now exit the chroot and you should be able to reboot into a working Alpine system.
|
||||||
|
|
||||||
|
```
|
||||||
|
# exit
|
||||||
|
# umount -lf /mnt
|
||||||
|
# reboot
|
||||||
|
```
|
||||||
|
|
||||||
|
When booting up your screen might appear blank, this is the encryption prompt. Enter the encryption key and press enter to boot.
|
||||||
|
|
||||||
|
> Do note that "Linux Boot Manager" will have to be set to load first in your bios.
|
|
@ -0,0 +1,73 @@
|
||||||
|
# Provisioning
|
||||||
|
|
||||||
|
After flasing the Alpine Linux extended ISO, partition a disk. For this action internet is required since `gptfdisk` is not included on the extended ISO, therefore it needs to be obtained from the repository.
|
||||||
|
|
||||||
|
To set it up `setup-interfaces` and `setup-apkrepos` will be used.
|
||||||
|
|
||||||
|
```
|
||||||
|
# setup-interfaces -ar
|
||||||
|
# setup-apkrepos -c1
|
||||||
|
```
|
||||||
|
|
||||||
|
A few packages will have to be installed first:
|
||||||
|
|
||||||
|
```
|
||||||
|
# apk add cryptsetup lsblk btrfs-progs gptfdisk dosfstools acpid
|
||||||
|
```
|
||||||
|
|
||||||
|
The drive should be partitioned using `gdisk` (or `cfdisk`). It should have at least two partitions with one `EFI System` partition and one `Linux filesystem` partition and look something like this:
|
||||||
|
|
||||||
|
| Number of partition | Size | Type |
|
||||||
|
|:-----:|:-----:|:-----:|
|
||||||
|
| 1 | 512 MB or more | EFI System |
|
||||||
|
| 2 | Rest of the drive | Linux filesystem |
|
||||||
|
|
||||||
|
Then to create the filesystem on the efi partition.
|
||||||
|
|
||||||
|
```
|
||||||
|
# mkfs.fat -F 32 -n efi /dev/<disk>1
|
||||||
|
```
|
||||||
|
|
||||||
|
The main partition of the system is going to be encrypted using `cryptsetup`. First generate a key that will be used to encrypt the device and save it temporarily to the file `/tmp/crypt-key.txt` with:
|
||||||
|
|
||||||
|
```
|
||||||
|
# cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1 > /tmp/crypt-key.txt && cat /tmp/crypt-key.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Later on in the guide `clevis` will be used for automatic decryption, so this key only has to be entered a few times. However, if any changes are made to the bios or secureboot then this key will be needed again so make sure to write it down.
|
||||||
|
|
||||||
|
Then format the partition using `cryptsetup`:
|
||||||
|
|
||||||
|
```
|
||||||
|
# cryptsetup luksFormat /dev/<disk>2 --type luks2 --cipher aes-xts-plain64 --hash sha512 --iter-time 4000 --key-size 512 --pbkdf argon2id --verify-passphrase
|
||||||
|
[Enter the generated key]
|
||||||
|
# cryptsetup open --type luks /dev/<disk>2 luks
|
||||||
|
```
|
||||||
|
|
||||||
|
Now to create a btrfs filesystem on the main partition use:
|
||||||
|
|
||||||
|
```
|
||||||
|
# mkfs.btrfs -L main -n 32k /dev/mapper/luks
|
||||||
|
```
|
||||||
|
|
||||||
|
with `-n` the `nodesize`, larger nodesize gives better packing and less fragmentation at the cost of more expensive memory operations while updating metadata blocks. The default is 16k.
|
||||||
|
|
||||||
|
The main partition needs to be mounted.
|
||||||
|
|
||||||
|
```
|
||||||
|
# mount /dev/mapper/luks /mnt -t btrfs
|
||||||
|
```
|
||||||
|
|
||||||
|
To create the necessary subvolumes in the main volume:
|
||||||
|
|
||||||
|
```
|
||||||
|
for i in root home var nix; do
|
||||||
|
> btrfs subvolume create /mnt/@$i
|
||||||
|
> done
|
||||||
|
```
|
||||||
|
|
||||||
|
Unmount the main partition.
|
||||||
|
|
||||||
|
```
|
||||||
|
# umount -lf /mnt
|
||||||
|
```
|
Loading…
Reference in a new issue