A Basic Alpine Linux XEN domU¶
Guide to configure a basic XEN Domain based on Alpine 3.16. As Dom0 we use Alpine Dom0 V3.15. But please make sure to upgrade that to 3.16 as well.
To do this I have the following extra hardware - No extra hardware is needed.
dom0 work¶
We need to create the domU installation configuration file, mount installation image location, and start the installation
Download iso and unpack kernel and initramfs see here: domu-preparation
Create Installation config¶
Now we need to create the domU configuration file.
- Observe that the MAC address has to be uniq among dom0 and all domU. A tool to help you with this is to use random_mac.py for instance.
- The cdrom points to the installer image which was prepared in the dom0 installation.
If you do it manually, please start with "00:16:3E" followed by a unique combination for you. For instance "00:16:3e:AA:AA:01"
# cat << EOF > /etc/xen/<domU-name>.cfg ##### ##### <domU-name> domU ##### vcpus = '1' memory = '256' maxmem = '256' kernel = "/domU_installer/vmlinuz-lts" ramdisk = "/domU_installer/initramfs-lts" extra = "alpine_dev=hdc:iso9660 modules=loop,squashfs,sd-mod,usb-storage console=hvc0" disk = [ 'file://domU_installer/alpine-extended-3.16.1-x86_64.iso,hdc:cdrom,r', 'phy:/<root disk path>/<root disk>,xvda1,w', 'phy:/<swap disk path>/<swap disk>,xvda2,w', ] name = '<domU-name>' ## ENSURE MAC ADDRESS IS UNIQUE!!! vif = [ 'mac=<Unique MAC Address>,bridge=br0' ] on_poweroff = 'destroy' on_reboot = 'restart' on_crash = 'restart' EOF
Suggested size for a common alpine server's disk would be 1.5GB, and 512M for swap.
If you are using zfs disks, please see the Appendix.
If you are using LVM disks, it might look like this.
'phy:/dev/vg_domU/<domU-name>-disk,xvda1,w'
If you are using normal disks, it might look like this.
'phy:/dev/sdb1,xvda1,w'
If you are using an file as a disk, you need to create the file, and then use it. Something like this.
# # Create a 3GB file to be used as a disk # dd if=/dev/zero of=/path/to/<domU-name>-disk.img bs=1M count=3000 # # And then use this disk file in the configuration file ‘file:/path/to/<domU-name>-disk.img,xvda,w’,
If you want to use a qemu disk, its very similar.
# qemu-img create -f raw /path/to/<domU-name>-disk.img 3G # # And then use this disk file in the configuration file ‘file:/path/to/<domU-name>-disk.img,xvda,w’,
Mount /domU_installer¶
And last we need to make sure that /domU_installer is mounted.
dom0 # mount /domU_installer
Start domU¶
It is time to start the installation, to do this we simple start the domU
dom0 # xl create /etc/xen/<domU-name>.cfg -c
To get back to the dom0 environment from the console, you press CTRL+]
Hint If CTRL+] does not work, CTRL+5 could work instead. Please see here for more info Xen FAQ Console
At login prompt, simply enter root and no password (default at installation time)
domU work¶
Format root disk¶
# apk add e2fsprogs # mkfs.ext4 /dev/xvda1
Mountpoints etc¶
Time to configure the mountpoints for root, as well as mount it. We will mount it under /mnt for the installation process.
# mount -t ext4 /dev/xvda1 /mnt
setup-alpine¶
Finally, time to configure (setup) the actual alpine part
Key things to remember
- Do not setup a normal user account (will be setup after first boot in this guide)
- Answer
none
on last questions (Disks, config, and apk repository) - Which disk(s) would you like to use? (or '?' for help or 'none') [none]
- Enter where to store configs ('floppy', 'usb' or 'none') [none]:
- Enter apk cache directory (or '?' or 'none') [/var/cache/apk]:
none
# setup-alpine Available keyboard layouts: af be cn fi hu it lk mm pl sy uz al bg cz fo id jp lt mt pt th vn am br de fr ie ke lv my ro tj ara brai dk gb il kg ma ng rs tm at by dz ge in kr md nl ru tr az ca ee gh iq kz me no se tw ba ch epo gr ir la mk ph si ua bd cm es hr is latam ml pk sk us Select keyboard layout: [none] us Available variants: us-alt-intl us-altgr-intl us-chr us-colemak us-colemak_dh us-colemak_dh_iso us-dvorak-alt-intl us-dvorak-classic us-dvorak-intl us-dvorak-l us-dvorak-r us-dvorak us-dvp us-euro us-haw us-hbs us-intl us-mac us-norman us-olpc2 us-rus us-symbolic us-workman-intl us-workman us Select variant (or 'abort'): us * Caching service dependencies ... [ ok ] * Setting keymap ... [ ok ] Enter system hostname (short form, e.g. 'foo') [localhost] `<domU-name>` Available interfaces are: eth0. Enter '?' for help on bridges, bonding and vlans. Which one do you want to initialize? (or '?' or 'done') [eth0] Ip address for eth0? (or 'dhcp', 'none', '?') [dhcp] `<domU-IP>/<domU-network-netmask>` Gateway? (or 'none') [none] `<your gateway>` Configuration for eth0: type=static address=`<domU-IP>` netmask=`<domU-netmask>` gateway=`<your gateway>` Do you want to do any manual network configuration? (y/n) [n] DNS domain name? (e.g 'bar.com') example.com DNS nameserver(s)? `<your dns server, or 8.8.8.8>` Changing password for root New password: Retype password: passwd: password for root changed by root Which timezone are you in? ('?' for list) [UTC] `<Your timezone, for instance Australia/Melbourne`> * Starting busybox acpid ... [ ok ] * Starting busybox crond ... [ ok ] HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none] Which NTP client to run? ('busybox', 'openntpd', 'chrony' or 'none') [chrony] * service chronyd added to runlevel default * Caching service dependencies ... [ ok ] * Starting chronyd ... [ ok ] Available mirrors: 1) dl-cdn.alpinelinux.org ... 13) mirror.aarnet.edu.au ... 55) alpine.northrepo.ca r) Add random from the above list f) Detect and add fastest mirror from above list e) Edit /etc/apk/repositories with text editor Enter mirror number (1-55) or URL to add (or r/f/e/done) [1] f Finding fastest mirror... 0.56 http://dl-cdn.alpinelinux.org/alpine/ ... 0.11 http://mirror.aarnet.edu.au/pub/alpine ... 0.09 http://alpine.northrepo.ca Added mirror alpine.northrepo.ca Updating repository indexes... done. Which SSH server? ('openssh', 'dropbear' or 'none') [openssh] * service sshd added to runlevel default * Caching service dependencies ... [ ok ] ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519 * Starting sshd ... [ ok ] Available disks are: xvda2 (0.5 GB ) Which disk(s) would you like to use? (or '?' for help or 'none') [none] Enter where to store configs ('floppy', 'usb' or 'none') [none] Enter apk cache directory (or '?' or 'none') [/var/cache/apk] none
Store filesystem¶
Time to install this domU to the filesystem on /mnt
(which points to the disk for the / partition after first reboot)
We will use the -m (write system to disk) parameters.
# setup-disk -m sys /mnt Installing system on /dev/xvda1: extlinux: Not a directory: /mnt/boot 100% ############################################==> initramfs: creating /boot/initramfs-vanilla /boot is device /dev/xvda1 extlinux: no previous syslinux boot sector found You might need fix the MBR to be able to boot
Update grub¶
We need to create a grub boot stanza
# mkdir /mnt/boot/grub # cat << EOF > /mnt/boot/grub/grub.cfg set timeout=2 set default=0 menuentry "alpine" { linux /boot/vmlinuz-lts modules=ext4 console=hvc0 root=/dev/xvda1 initrd /boot/initramfs-lts } EOF
Time to halt¶
Time to halt this newly installed system, and go back to dom0 for some changes.
# halt
Back to dom0¶
Fix dom0's domU config file¶
We need to update the domU configurationfile to use the pv grub bootloader, as well as remove the cdrom.
dom0 # cat << EOF > /etc/xen/<domU-name>.cfg #### #### <domU-name> domU #### vcpus = '1' memory = '256' maxmem = '256' kernel = "/usr/lib/grub-xen/grub-x86_64-xen.bin" disk = [ 'phy:/<root disk path>/<root disk>,xvda1,w', 'phy:/<swap disk path>/<swap disk>,xvda2,w', ] name = '<domU-name>' ## ENSURE MAC ADDRESS IS UNIQ!!! vif = [ 'mac=<Unique MAC Address>,bridge=br0' ] on_poweroff = 'destroy' on_reboot = 'restart' on_crash = 'restart' EOF
Alternatively with pvh grub
type = "pvh" kernel = "/usr/lib/grub-xen/grub-i386-xen_pvh.bin"
And lastly we need to make these changes restart safe
dom0 # etckeeper commit "Finalized domU configuration file"
Start domU¶
Finally time to start the newly created domU, and see if it all works.
dom0 # xl create /etc/xen/<domU-name>.cfg -c
Add etckeeper¶
Etckeeper will store whole /etc in a git repository, and keep track of every change
that is made there.
Just remember to do a etckeeper commit "Describe the change"
# apk add etckeeper
Add normal user¶
As per normal security, we should not use the root account for normal operations, so we need to create a normal user, add it to wheel
# adduser <username>
Add doas¶
For security reasons, and good practice, lets install doas
, and if you
are more used with sudo
command you can also install doas-sudo-shim
# apk add doas # echo "permit persist :wheel" >> /etc/doas.d/doas.conf # adduser <username> wheel # etckeeper commit "Configured doas"
Add sshguard¶
And for good measure, lets add sshguard
# apk add sshguard nftables # cat << EOF > /etc/sshguard.conf #!/bin/sh BACKEND='/usr/libexec/sshg-fw-nft-sets' FILES='/var/log/messages' EOF # rc-update add sshguard # etckeeper commit "Added sshguard"
To view the rules in nftables (which IP's are beeing blocked (if any))
# nft list ruleset
Optionally, but recommended, enable only passwordless ssh¶
Update sshd configuration and set the following options to no For more detailed information, please check [this link] (https://linuxize.com/post/how-to-setup-passwordless-ssh-login/)
Copy your public key to your server
<your local desktop/laptop> $ ssh-copy-id <username>@<domU IP> Disable normal password when using ssh ```console # sed -e 's/#PasswordAuthentication yes/PasswordAuthentication no/' -i /etc/ssh/sshd_config # etckeeper commit "Enforce passwordless authentication only"
Verify that password less ssh works
<your local desktop/laptop>$ ssh <domU IP> -l <username>
if all works fine, restart ssh on your newly created domU
<domU> # /etc/init.d/sshd restart
Add swap¶
We need to put the swap on the swap disk
# mkswap /dev/xvda2 # swapon /dev/xvda2 # echo "/dev/xvda2 none swap sw 0 0" >> /etc/fstab # swapon -a # rc-update add swap # etckeeper commit "Added swapvolume"
Confirm network ok¶
Ensure we can ping google
# ping www.google.com
Update system¶
Good practice to update the system
# apk update # apk upgrade
Switch to the -virt
kernel (optional)¶
The -virt
kernel contains drivers for virtual function NICs, so
no need for the full blown -lts
kernel and lots of firmware.
Note if you will be doing pci passthrough of non vf nic
devices, you must use the linux-lts
kernel!
# apk add linux-virt # sed -i 's/-lts/-virt/' /boot/grub/grub.cfg # apk del linux-lts
Fix autostart of domU¶
Time to fix so that this domU is automatically started on reboot
Lets stop domU
# halt
And on the dom0 we create the auto start link, remember, do not forget to give the lbu commit command.
If you want to have some control of when this particular domU will be started, preceed the config file name with a numeric part, where 00 is first in priority, and 99 is last.
For instance, if you want this particular domU to be started first, you should give it the following link name. 00-
dom0 # ln -s /etc/xen/<domU-name>.cfg /etc/xen/auto/<NN-domU-name>.cfg dom0 # etckeeper commit "Enabled autostart of domU"
Reboot to verify
dom0 # reboot
or if you prefere to just restart the service
dom0 # service xendomains restart
and after dom0 is up and running again, check that the newly created domU domain is running
dom0 # xl list
Appendix¶
Disk from a storage driver domain running ZFS¶
If you are using a storage driver domU with ZFS, like Alpine Storage DomU V3.8, you need to add the backend=
Example
disk = [ 'backend=<Storage driver domU name>,phy:/dev/zvol/tank/xen/<disk>,xvda1,w', ]
Example on my system
disk = [ 'backend=zfshost,phy:/dev/zvol/tank/xen/dns-disk,xvda1,w', ]