Skip to content

Instantly share code, notes, and snippets.

@fractal-fumbler
Forked from d-513/arch-ovh.md
Last active October 27, 2024 17:41
Show Gist options
  • Save fractal-fumbler/bc65729d1b437cad28676e21cf761407 to your computer and use it in GitHub Desktop.
Save fractal-fumbler/bc65729d1b437cad28676e21cf761407 to your computer and use it in GitHub Desktop.
Arch Linux on KVM VPS

Install Arch on KVM VPS

How to install Arch Linux on an VPS (kvm).

Conventions

This guide assumes the following:

  • x86_64, KVM-based VPS
  • VPS has one ROM drive (virtio)
  • VPS has more around 8 GB RAM
PARTITION DEVICE TYPE
Boot /dev/vdX1 BIOS Boot (4)
Root /dev/vdX2 Linux Filesystem (ext4)

Note Remember to replace /dev/vdX with the actual drive, e.g /dev/vda

LOW on VRAM (optionally)

Assume anything reffered to as *low ram vps* in the guide to be a VPS with <8gb ram. Ignore bootstrap partition if your VPS can fit an arch bootstrap image on tmpfs, which makes it a lot simpler.

PARTITION DEVICE TYPE
Bootstrap (only low ram vps) /dev/vdX2 Linux Filesystem (ext4)

Please follow these instructions carefully. If want to blindly copy-paste commands please refer to https://wiki.archlinux.org/title/general_recommendations.

Get into recovery

If VPS using vmmanager from https://docs.ispsystem.com/v6/virtual-machines/recovery-mode Go to VPS Panel: Virtual machines →⋮Menu → Recovery mode

image

Select Recovery mode.

image

SSH to recovery

Check availability of ssh connection to VPS

ssh [email protected] <--- VPS ip address

Note: If you get a hostkey mismatch, remove ~/.ssh/known_hosts. This happens because the recovery os uses a temporary ssh fingerprint.

Note: Need to disable iptables for ssh to connect

systemctl stop iptables.service ip6tables.service

https://gitlab.com/systemrescue/systemrescue-sources/-/issues/190

Alternetivly, VNC can be used for installation proccess.

image

Adding static IP address for network discovery

Note: https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#IPv4_CIDR_blocks

If mask is 255.255.255.255, thus cidr will be /32

ip address add <VPS IP>/<cidr> broadcast + dev <ens#>
ip route add <Gateway IP>/<cidr> dev <ens#>
ip route add default via <Gateway IP>

now it's time to test if internet is up

ping 1.1.1.1
ping google.com

Download arch bootstrap image

in terminal execute

[root@VPS] cd /tmp
[root@VPS] wget https://geo.mirror.pkgbuild.com/iso/latest/archlinux-bootstrap-x86_64.tar.zst

Note:

Alternative way of partitioning — a cloud image

For this you need to have an option to install qemu-img
Make some extra room for the image: mkdir /tmp/mnt mount -t tmpfs tmpfs /tmp/mnt cd /tmp/mnt Download Archlinux cloud image:
wget https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2

Burn image to vdX: qemu-img convert -f qcow2 -O raw Arch-Linux-x86_64-cloudimg-20210315.17387.qcow2 /dev/sdb

For additional info Install Arch Linux On OVH VPS

Wipe the drive

list available drives: fdisk -l

Choose correct ROM drive to wipe fs by executing: wipefs -a /dev/vdX

Partitioning

  1. Create a GPT partition table:
[root@VPS] parted /dev/vdX mklabel gpt
  1. Create partitions on /dev/vdX
[root@VPS] parted /dev/vdX
  • FYI: bios_grub partition


    With GPT partition table also need to create a bios_grub partition of 1MiB since the default firmware for KVM virtual machine is seaBIOS which is a free and open source BIOS implementation. Later the Grub 2 boot loader will be installed inside bios_grub partition.
    Make ensure that bios_grub partition starts at least 31 KiB (63 sectors) from the start of the disk because the first 63 sectors is reserved for MBR boot code. However, it will give us performance benefit if we align partitions so the bios_grub partition might start at 1MiB from the start of the disk.

    For additional info refer to BIOS/MBR examples on Arch Wiki

  1. Create bios_grub partition with this command: mkpart primary 1MiB 2MiB

  2. Set it as a bios_grub partition set 1 bios_grub on

  3. Create the second partition. mkpart primary 2MiB 100%

100% means it will use all the following space of the disk. This tutorial use a single root partition. If you need advanced setup, you can adjust it.

Make ext4 labels:

  • FYI: reasons to use ext4

    it doesn't make sense to use other partition types than ext4 here really, because of RAID on servers and most features of the other filesystems wont be useful in a virtualized environment

[root@VPS] mkfs.ext4 /dev/vdX2
  • Partitioning: Low ram VPS

    /ToDo


    mkfs.ext4 /dev/vdX2
    This will be tricky, as the bootstrap image loaded on the drive before extraction.
    For this, create your main partition, which will span the entire drive, minus 6 gigabyes.
    To make this easier, just say `-6G` when fdisk asks you for the last sector
    Now need to make another partition, which will span the 6 gigabytes left free for bootstrap image. There is an option to reclaim the space later.
    Check Bonus: Low ram VPS: Reclaim space.

Bootstrap preparation

  1. Making bootstrap folder
[root@VPS] mkdir /tmp/bootstrap
[root@VPS] mount -t tmpfs tmpfs /tmp/bootstrap
  1. extracting bootstrap image & removing leftovers
[root@VPS] cd /tmp/bootstrap
[root@VPS] tar xzf /tmp/archlinux-bootstrap-*-x86_64.tar.zst --numeric-owner
[root@VPS] mv root.x86_64/* .
[root@VPS] rmdir root.x86_64

Mount system

[root@VPS] mount /dev/vdX2 /tmp/bootstrap/mnt

Enable a mirror in the bootstrap system

# uncomment a mirror, e.g the rackspace one
sed -i 's|#Server = https://mirror.rackspace.com|Server = https://mirror.rackspace.com|g' etc/pacman.d/mirrorlist 
  • Optional: enable pacman parrarel downloading

    sed -i 's/#ParallelDownloads/ParallelDownloads/g' etc/pacman.conf

Chroot to bootstrap

[root@VPS] /tmp/bootstrap/bin/arch-chroot /tmp/bootstrap

Initialize pacman

[root@VPS] pacman-key --init
[root@VPS] pacman-key --populate archlinux

Note this can take a while because of entropy generation.

Pacstrap base system

[root@VPS] pacstrap /mnt base linux linux-firmware sudo openssh grub os-prober micro xfsprogs pacman-contrib bash-completion
  • Optional: alternative kernel to install you can use another kernel: linux-lts may be optimal for servers

Generate fstab:

[root@VPS] genfstab -U mnt >> mnt/etc/fstab

Now exit your bootstrap chroot:

[root@VPS] exit

Chroot to newly installed system

[root@VPS] /tmp/bootstrap/bin/arch-chroot /tmp/bootstrap/mnt/

Install bootloader

Optional: Configure grub

default config is fine, but you can make it better.

# change GRUB_TIMEOUT= to a lower value for faster boot
[root@VPS] sed -i 's/GRUB_TIMEOUT=.*/GRUB_TIMEOUT=2/g' /etc/default/grub
# remove everything from GRUB_CMDLINE_LINUX_DEFAULT=, hiding logs is useless and makes debugging harder
[root@VPS] sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT.*/GRUB_CMDLINE_LINUX_DEFAULT=""/g' /etc/default/grub

Install grub

# install bootloader
# Since we are using BIOS firmware, so the target should be i386-pc
[root@VPS] grub-install --target=i386-pc /dev/vdX
# create bootloader entries
[root@VPS] grub-mkconfig -o /boot/grub/grub.cfg

Post-Installation

Post-config steps to make after initial installation is complete

Network

  1. Configure and launch systemd-networkd
# starting service
[root@VPS] systemctl enable systemd-networkd.service
# adjust to your needs
# if ip is public, so need to add Destination= with gateway ip and subnet prefix
cat << EOF > /etc/systemd/network/20-wired.network
[Match]
Name=en*
[Network]
Address=xxx.xxx.xxx.xxx/32
Gateway=10.0.0.1
DNS=1.1.1.1
[Route]
Destination=10.0.0.1/32
EOF

The preinstalled systemd-resolved provides resolver services for DNS, DNSSEC, DNS over TLS, mDNS and LLMNR.

  1. Configure DNS in /etc/systemd/resolved.conf
[Resolve]
DNS = 1.1.1.1
FallbackDNS = 9.9.9.9
  1. Start resolved with DNS stub file mode
# creating stub file
[root@VPS] ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
# starting service
[root@VPS] systemctl enable systemd-resolved.service

Locale

[root@VPS] echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
[root@VPS] echo "LANG=en_US.UTF-8" >> /etc/locale.conf
[root@VPS] locale-gen

Timezone

For VPS public ip Timezone can be check at ipinfo.io

[root@VPS] ln -sf /usr/share/zoneinfo/<REGION>/<CITY> /etc/localtime

Generate Mirrorlist by country

This will take a while depending on VPS network speed, as it should test and choose the fastest mirror.

[root@VPS] cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.backup
[root@VPS] awk '/^## Country Name$/{f=1; next}f==0{next}/^$/{exit}{print substr($0, 1);}' /etc/pacman.d/mirrorlist
[root@VPS] sed -i 's/^#Server/Server/' /etc/pacman.d/mirrorlist

Hostname

[root@VPS] echo "Hostname" > /etc/hostname

Build the initramfs

[root@VPS] mkinitcpio -P

Set root password

[root@VPS] passwd

Add a new non-privileged user

# create user
[root@VPS] useradd -m <username>
# give user a password
[root@VPS] passwd <username>
# configure sudo using drop-in files in https://wiki.archlinux.org/title/sudo#Configure_sudo_using_drop-in_files_in_/etc/sudoers.d
# it is strongly advised to use `visudo`
[root@VPS] nano /etc/sudoers.d/<username>
# add desired sudo magic
<username> ALL=(ALL:ALL) ALL
# optionally permit passwordless execution (for example, networkctl)
<username> ALL=(ALL:ALL) NOPASSWD: /usr/bin/networkctl

Force public key authentication instead of password https://wiki.archlinux.org/title/OpenSSH#Force_public_key_authentication

# login into <username>
[root@VPS] sudo -u <username> bash
# create keys
[<username>@VPS] ssh-keygen
# copy public key id_rsa.pub from host to VPS into file ~/.ssh/authorized_keys
# chown authorized_keys
[<username>@VPS] chown <username>:<username> ~/.ssh/authorized_keys
# return to root
[<username>@VPS] exit
# restart sshd service
[root@VPS] systemctl restart sshd

Additional configuration of ssh in /etc/ssh/sshd_config

  • Disable root login
  • Disable password authentication
# (?) Port SSHD_PORT
PermitRootLogin no
PasswordAuthentication no
ClientAliveInterval 30
ClientAliveCountMax 60
LogLevel VERBOSE
AuthorizedKeysFile .ssh/authorized_keys

Enable ssh at boot

[root@VPS] systemctl enable sshd

Start&Enable qemu-guest-agent for vmmanager integration

[root@VPS] systemctl start qemu-guest-agent
# https://docs.ispsystem.com/v6/virtual-machines/how-to-check-and-restore-qemu-guest-agent
[root@VPS] systemctl enable --now qemu-guest-agent.service

Finish

[root@VPS] exit
[root@VPS] umount /tmp/bootstrap/mnt
[root@VPS] umount /tmp/bootstrap
[root@VPS] exit

Done!

Now go to control panel and reboot the VPS. It should boot right into Arch.
If you can't ssh to it, connect using KVM in the control panel and debug the issue.

  • Bonus: Low ram VPS: Reclaim space

    Remember the bootstrap partition we made?
    Yeah, we don't need that anymore. fdisk /dev/vdX Then type d and choose partition number 2. This will remove useless partition.
    Now, the tricky part: also remove partition 10. Type d, followed by 10. BUT, when it asks you, DO NOT erase the ext4 header, otherwise you will have to redo the process.
    Now make another partition with id 10 and fill entire drive with it. Write the changes with w and reboot. It should automatically fsck the filesystem and fix up stuff. Now the filesystem is reclaimed.

credits:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment