KVM // Bootstrap Debian / Ubuntu / Kali

assuming the host is up and running already

this is almost a script

Bootstrap on a loop device

as root

    guest=bookworm

    mkdir -p /data/guests/$guest/lala/
    cd /data/guests/$guest/
    dd if=/dev/zero of=$guest.img bs=1G count=0 seek=26

losetup -a | grep -v snapd
    loopdevice=`losetup --find --partscan --show $guest.img`
    echo loopdevice is $loopdevice

manual partitioning

fdisk $loopdevice

n
p
ENTER
ENTER
ENTER
a
w

    fdisk -l $loopdevice

you could otherwise automate this as such

total=`fdisk -l $loopdevice | head -1 | awk '{print $7}'`

# 2048 * 512 = 1048576
echo -n writing vda.sfdisk...
cat > vda.sfdisk <<-EOF && echo done
label: dos
label-id: 0x8ae$((RANDOM % 10))$((RANDOM % 10))3cc
device: vda
unit: sectors

/dev/sda1 : start=2048, size=$((total-2048)), type=83, bootable
EOF
sfdisk $loopdevice < vda.sfdisk
#partprobe $loopdevice

prepare the file-system

    mkfs.btrfs ${loopdevice}p1
    mount ${loopdevice}p1 lala/
    mount -o bind /dev lala/dev
    mount -o bind /dev/pts lala/dev/pts
    mount -o bind /sys lala/sys
    mount -o bind /proc lala/proc

apt install debian-keyring debian-archive-keyring
ls -lF /usr/share/keyrings/debian-archive-keyring.gpg

cat /etc/apt/source.list
mirror=...
    time debootstrap --arch=amd64 $guest lala/ $mirror
du -sh lala/

Guest setup

cat lala/etc/fstab
    cat > lala/etc/fstab <<-EOF # override
    /dev/vda1 / btrfs defaults 0 0
    proc /proc proc defaults 0 0
    tmpfs /tmp tmpfs rw,nodev,nosuid,noatime,relatime 0 0
    devpts /dev/pts devpts gid=5,mode=620 0 0
    EOF

vi lala/etc/apt/sources.list

deb http://ftp.ru.debian.org/debian bookworm main contrib non-free non-free-firmware
deb http://ftp.ru.debian.org/debian bookworm-updates main contrib non-free non-free-firmware
# bookworm-backports

cp -pi lala/etc/bash.bashrc lala/etc/bash.bashrc.dist
vi lala/etc/bash.bashrc

    export LC_ALL=en_US.UTF-8
    export LANG=en_US.UTF-8
    export LANGUAGE=en_US:en

alias ll='ls --group-directories-first --color=auto -alh'
    alias ls='ls --group-directories-first --color=auto'
    alias cp='cp -i'
    alias mv='mv -i'
    alias rm='rm -i'

cat lala/etc/hostname
echo $guest lala/etc/hostname

echo "127.0.0.1       bookwworm" >> lala/etc/hosts

rmdir lala/etc/network/interfaces.d/
vi lala/etc/network/interfaces

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 192.168.122.9/24
    gateway 192.168.122.1

cat lala/etc/resolv.conf
    echo nameserver 192.168.122.1 > lala/etc/resolv.conf

Boot-blocks & kernel

we need a kernel in there as this is KVM, not XEN

chroot lala/ bash

passwd -d root

apt update
apt install locales
dpkg-reconfigure locales

==> en_US.UTF-8

    perl -e exit

apt install mlocate net-tools openssh-server manpages man-db
# ifupdown

apt install linux-image-cloud-amd64 btrfs-progs
# linux-image-kvm
# linux-image-amd64

those links should have been created by the linux-image package already

ls -lF /vmlinuz
ls -lF /initrd.img

make sure butterfs whatever additional module you need at boot-time is in there

grep -i btrfs /boot/config-*
grep -i virtio_console /boot/config-*

cd /boot/
version=`uname -r`
cp initrd.img-$version initrd.img-$version.dist

cd /etc/initramfs-tools/
cp -pi modules modules.dist
vi modules

btrfs
virtio_console

update-initramfs -k all -u

    apt install initramfs-tools
lsinitramfs /boot/initrd.img-$version | grep -i btrfs
lsinitramfs /boot/initrd.img-$version | grep -i console

unset version

make sure the serial console prompt goes serial

systemctl disable getty@tty1.service
systemctl enable serial-getty@.service

systemctl list-unit-files | grep getty
ls -lF /etc/systemd/system/getty.target.wants/

ready to leave the chroot

^D

now setup the kvm guest boot-loader and kernel-time serial console

ls -lh /usr/lib/syslinux/mbr/mbr.bin

    dd if=/usr/lib/syslinux/mbr/mbr.bin of=$loopdevice
    mkdir lala/boot/syslinux/
    extlinux --install lala/boot/syslinux --device ${loopdevice}p1
    cp -f /usr/lib/syslinux/modules/bios/mboot.c32 lala/boot/syslinux/
    cp -f /usr/lib/syslinux/modules/bios/libcom32.c32 lala/boot/syslinux/
vi lala/boot/syslinux/syslinux.cfg

    serial 0 115200
    console 1
    nohalt 1

    default Linux
    prompt 1
    timeout 30

    label Linux
            linux /vmlinuz
    initrd /initrd.img
            append root=/dev/vda1 ro console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 mitigations=off

umount -R lala/
rmdir lala/
btrfsck ${loopdevice}p1
losetup --detach $loopdevice

ls -lhF $guest.img
    du -sh $guest.img

Ready to go

echo $((`grep ^processor /proc/cpuinfo | tail -1 | awk '{print $3}'` + 1))
ls -lhF /usr/bin/qemu-system-x86_64

here with 3 vcpu and 1GiB of RAM

cd /data/guests/$guest/
cat > $guest.xml <<EOF
<domain type='kvm'>
  <name>$guest</name>
  <memory unit='GiB'>1</memory>
  <currentMemory unit='GiB'>1</currentMemory>
  <vcpu placement='static'>3</vcpu>
  <os>
    <type arch='x86_64' machine='q35'>hvm</type>
    <boot dev='hd'/>
  </os>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/data/guests/$guest/$guest.img'/>
      <target dev='vda' bus='virtio'/>
    </disk>
    <interface type='bridge'>
      <source bridge='virbr0'/>
      <model type='virtio'/>
    </interface>
    <serial type='pty'>
      <target type='isa-serial' port='0'>
    <model name='isa-serial'/>
      </target>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
  </devices>
</domain>
EOF
virsh list --all
virsh create $guest.xml --console

^]

virsh console $guest

^]

maybe add your SSH pubkey in there and we’re good

Acceptance and template

ping opendns.com
poweroff

as root

virsh list --all | grep $guest # empty
cd /data/guests/
time nice tar cSf /data/templates/$guest.tar $guest/
ls -lh /data/templates/$guest.tar
# 1,1G

GNS3-ready

eventually make it available for GNS3

Troubleshooting

grub-install: error: unknown filesystem.

==> you need to see the partition, use losetup for that

while trying to launch the guest as user

error: Failed to create domain from bookworm.xml
error: internal error: /usr/lib/qemu/qemu-bridge-helper --use-vnet --br=virbr0 --fd=31: failed to communicate with bridge helper: Transport endpoint is not connected
stderr=failed to parse default acl file `/etc/qemu/bridge.conf'

==> …

Resources

https://stackoverflow.com/questions/21596384/cannot-disable-systemd-serial-getty-service

https://unix.stackexchange.com/questions/447070/serial-getty-error-messages


HOME | GUIDES | LECTURES | LAB | SMTP HEALTH | HTML5 | CONTACT
Copyright © 2024 Pierre-Philipp Braun