KVM guest // Bootstrap Slackware Linux

tested on ubuntu/focal

boostrapping slackware on a vdisk (not a v-partition for once)

Requirements

We will need pkgtools so we’re brutally installing it on Ubuntu, however it overrides the /sbin symlink so be careful

    mirror=http://nephtys.lip6.fr/pub/linux/distributions/slackware/slackware64-current/

    lftp -c "open $mirror/slackware64/a/; mget pkgtools-*.txz"

mkdir /var/tmp/pkgtools/
    tar xJf pkgtools-*.txz -C /var/tmp/pkgtools/
mv -f /var/tmp/pkgtools/sbin/* /usr/sbin/

We use SYSLINUX / EXTLINUX against the guest virtual disk from the host

apt install syslinux

Assuming you got the virbr0 bridge up and running

virsh net-start default
virsh net-list
brctl show

Bootstrap

KVM requires a boot-loader hence a full virtual disk

guest=slack

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

n
p
ENTER
ENTER
ENTER
a
w

    losetup --find --partscan --show $guest.img
mkfs.ext4 /dev/loop3p1
#mkfs.xfs /dev/loop3p1
mount /dev/loop3p1 lala/

Deploy and setup

from the KVM host directly

cd /data/guests/
wget https://pub.nethence.com/bin/slack/slackstrap.bash.txt
mv -i slackstrap.bash.txt slackstrap.bash
chmod +x slackstrap.bash

# RUSSIA
mirror=https://mirror.yandex.ru/slackware/slackware64-current/

# FRANCE
mirror=http://nephtys.lip6.fr/pub/linux/distributions/slackware/slackware64-current/

# LAN
mirror=http://x.x.x.x/slackware64-current/

cd /data/guests/$guest/
../slackstrap.bash lala/ $mirror

# KVM
../slackstrap.bash lala/ $mirror kernel

mkdir ../slack-pkgs/
mv *.txz ../slack-pkgs/
rm -f FILE_LIST tagfile

du -sh lala/
# 356M ext4/ext4 clean sparse
# 1,1G ext4/zfs clean sparse
# 1,4G ext4/zfs and kernel
# 9,7G ext4/zfs and full
# 1.3G reiser4/ext4 clean sparse

chroot lala/ ldconfig
chroot lala/ ldd /bin/bash

Setup manually

this is otherwise automated with the slackpost.bash script

cd /data/guests/
wget https://pub.nethence.com/bin/slack/slackpost.bash.txt
mv slackpost.bash.txt slackpost.bash
chmod +x slackpost.bash

default is KVM and french mirror, tune accordingly

vi slackpost.bash

# XEN
vpartition=/dev/xvda1
fs=reiser4
serial=hvc0

# KVM
vpartition=/dev/vda1
fs=ext4
serial=ttyS0

and proceed

cd $guest/
# assuming lala/
../slackpost.bash $guest

–or– proceed manually as follows

ls -ldF lala/dev/pts/ # exists
ls -ldF lala/dev/shm/ # exists
vi lala/etc/fstab # new file

#/dev/xvda1 / ext4 defaults 1 1
/dev/xvda1 / reiser4 defaults 1 1
devpts /dev/pts devpts gid=5,mode=620 0 0
proc /proc proc defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0

# KVM
/dev/vda1 / ext4 defaults 1 1

# swap
#/dev/xvda2 swap swap defaults 0 0
#/dev/vda2 swap swap defaults 0 0

only root can log in

echo non-root login has been disabled > lala/etc/nologin # new file

fix the locale – requires glibc package

chroot lala/ bash -ic "perl -e exit"
chroot lala/ bash -c "perl -e exit"
chroot lala/ perl -e exit

ls -lF lala/usr/share/locale/
ls -lF lala/usr/lib64/locale/
ls -lF lala/var/log/packages/glibc-*

chroot lala/ locale -av
vi lala/etc/bashrc # new file

export PATH=$PATH:/etc/rc.d
export MAKEFLAGS=-j$((`grep ^processor /proc/cpuinfo | tail -1 | awk '{print $NF}'` + 1))

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

    alias ll='ls -alhF'
    alias cp='cp -i'
    alias mv='mv -i'
    alias rm='rm -i'

echo source \$HOME/.bashrc > lala/root/.bash_profile
ln -s ../etc/bashrc lala/root/.bashrc

more options

#export LANGUAGE="en_US:en"
#export LC_ALL="C.UTF-8"
#export LC_COLLATE="C.UTF-8"
#export LANG="C.UTF-8"

update CA certificates

chroot lala/ which c_rehash
chroot lala/ bash -ic "update-ca-certificates"

disabling useless shit from rc.d – tag ADD

ls -lF lala/etc/rc.d/rc.cpufreq
chmod -x lala/etc/rc.d/rc.cpufreq
# lala/etc/rc.d/rc.loop

do not disable those

ls -lF lala/etc/rc.d/rc.modules lala/etc/rc.d/rc.modules.local
#chmod -x lala/etc/rc.d/rc.modules
#chmod -x lala/etc/rc.d/rc.modules.local

disabling useless shit from rc.d – tag REC

ls -lF \
    lala/etc/rc.d/rc.bluetooth \
    lala/etc/rc.d/rc.cgmanager \
    lala/etc/rc.d/rc.cgproxy \
    lala/etc/rc.d/rc.inetd
chmod -x lala/etc/rc.d/rc.bluetooth
chmod -x lala/etc/rc.d/rc.cgmanager
chmod -x lala/etc/rc.d/rc.cgproxy
chmod -x lala/etc/rc.d/rc.inetd

ls -lF \
    lala/etc/rc.d/rc.consolekit \
    lala/etc/rc.d/rc.mcelog
#chmod -x lala/etc/rc.d/rc.consolekit
#chmod -x lala/etc/rc.d/rc.mcelog

checking overall enabled scripts

ls -lF lala/etc/rc.d/
ls -lF lala/etc/rc.d/rc.udev # already executable

fix the timezone

ls -lF lala/etc/localtime-copied-from
rm -f lala/etc/localtime-copied-from
ln -s ../usr/share/zoneinfo/Europe/Moscow lala/etc/localtime # new file
ln -s ../usr/share/zoneinfo/Europe/Paris lala/etc/localtime # new file

avoid a boot time error on powersave

#cp -pi lala/etc/rc.d/rc.M lala/etc/rc.d/rc.M.dist
#chmod -x lala/etc/rc.d/rc.M.dist
#vi lala/etc/rc.d/rc.M

#/bin/setterm -blank 15 -powersave powerdown -powerdown 60

chmod -x lala/etc/rc.d/rc.setterm

fix the XEN or KVM guest userland serial console

    ls -lF lala/etc/termcap # needed
    ls -lF lala/sbin/agetty # needed

XEN serial line

    cp -pi lala/etc/inittab lala/etc/inittab.dist
    vi lala/etc/inittab

    s1:12345:respawn:/sbin/agetty --noclear --local-line hvc0 115200 linux
# 115200,38400,9600

    echo hvc0 >> lala/etc/securetty

COM1 serial line

    cp -pi lala/etc/inittab lala/etc/inittab.dist
    vi lala/etc/inittab

    s1:12345:respawn:/sbin/agetty --noclear --local-line ttyS0 115200,38400,9600 xterm

    echo ttyS0 >> lala/etc/securetty

eventually proceed with a brutal network setup – avoid ssh host keys generation for darkstar

beware of escapes in da place

short=SHORT-HOSTNAME

# kvm/libvirt
ip=192.168.122.99/24
gw=192.168.122.1

# orange
dns1=192.168.1.1
dns2=80.10.246.2
dns3=80.10.246.129

# dedibox
dns1=62.210.16.6
dns2=62.210.16.7

# opendns
dns1=208.67.222.222
dns2=208.67.220.220

cat lala/etc/HOSTNAME # darkstar.example.net
echo $short > lala/etc/HOSTNAME

mv lala/etc/hosts lala/etc/hosts.dist
echo -e "127.0.0.1\t\tlocalhost.localdomain localhost" > lala/etc/hosts
echo -e "::1\t\t\tlocalhost.localdomain localhost" >> lala/etc/hosts
echo -e "$ip\t$short.localdomain $short" >> lala/etc/hosts
[[ -n $gw ]] && echo -e "$gw\t\tgw" >> lala/etc/hosts
for dns in dns1 dns2 dns3; do
    [[ -n ${!dns} ]] && echo -e "${!dns}\t\t$dns" | tee -a lala/etc/hosts
done; unset dns

mv -i lala/etc/rc.d/rc.inet1 lala/etc/rc.d/rc.inet1.dist
chmod -x lala/etc/rc.d/rc.inet1.dist

# WARNING ESCAPES ARE IN THERE
cat > lala/etc/rc.d/rc.inet1 <<EOF
#!/bin/bash

echo rc.inet1 PATH is \$PATH

if [[ \$1 = stop || \$1 = down ]]; then
    route delete default
    ifconfig eth0 down
    ifconfig lo down
else
    echo -n lo...
    ifconfig lo up && echo done

    echo -n eth0 $ip ...
    ifconfig eth0 $ip up && echo done

    echo -n default route $gw ...
    route add default gw $gw && echo done
fi
EOF
chmod +x lala/etc/rc.d/rc.inet1

mv lala/etc/resolv.conf lala/etc/resolv.conf.dist
echo 'search nethence.com' > lala/etc/resolv.conf
for dns in dns1 dns2 dns3; do
    [[ -n ${!dns} ]] && echo -e "nameserver ${!dns}" | tee -a lala/etc/resolv.conf
done; unset dns

don’t forget to put your pubkeys over there

mkdir lala/root/.ssh/
vi lala/root/.ssh/authorized_keys

PASTE PUBKEYS

chmod 700 lala/root/.ssh/
chmod 600 lala/root/.ssh/authorized_keys

we want a clean SSHD configuration and trust a single pubkey upon first connection

# REC but forcibly installed by slackstrap/minimal
ls -lF lala/etc/rc.d/rc.sshd # already executable

mv -i lala/etc/ssh/sshd_config lala/etc/ssh/sshd_config.dist
grep -vE '^[[:space:]]*(#|$)' lala/etc/ssh/sshd_config.dist > lala/etc/ssh/sshd_config
echo 'HostKey /etc/ssh/ssh_host_ed25519_key' >> lala/etc/ssh/sshd_config
cat lala/etc/ssh/sshd_config

you can otherwise proceed with a full-blown SSH tuning if you like.

https://www.commentcamarche.net/faq/1496-serveurs-dns-des-principaux-fai

Boot-blocks

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

dd if=/usr/lib/syslinux/mbr/mbr.bin of=/dev/loop3
mkdir lala/boot/syslinux/
extlinux --install lala/boot/syslinux/ --device /dev/loop3p1
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 0
nohalt 1

default Linux
prompt 1
timeout 30

label Linux
    linux /boot/vmlinuz
    append root=/dev/vda1 ro console=ttyS0,115200n8 mitigations=off

label XEN
    kernel mboot.c32
    append /xen.gz loglvl=info guest_loglvl=info noreboot=true smt=1 ept=exec-sp com1=115200,8n1 console=com1 --- /vmlinuz root=/dev/vda1 ro console=hvc0 earlyprintk=xen nomodeset mitigations=off

you can also cumulate consoles as such

    # console=tty0 console=ttyS0,115200n8

note for XEN: yes hvc0 even for Dom0, and don’t forget to also tune agetty.

for Ubuntu / Debian also add

            net.ifnames=0 biosdevname=0

https://wiki.xenproject.org/wiki/Xen_FAQ_Console

https://wiki.xenproject.org/wiki/Xen_Serial_Console

Ready to go

umount lala/
#umount -R lala/
rmdir lala/

#dumpe2fs -i /dev/loop3p1
#dumpe2fs -h /dev/loop3p1
#fsck.ext4 -f /dev/loop3p1

# requires more recent syslinux than v3 on ubuntu
#xfs_info /dev/loop3p1

losetup --detach /dev/loop3

choose a decent machine type

qemu-system-x86_64 -machine help | grep PC

pc-i440fx-hirsute    Ubuntu 21.04 PC (i440FX + PIIX, 1996) (default)
pc                   Standard PC (i440FX + PIIX, 1996) (alias of pc-i440fx-5.2)
q35                  Standard PC (Q35 + ICH9, 2009) (alias of pc-q35-5.2)

new UUID and MAC address will be generated on the fly

cat > $guest.xml <<EOF
<domain type='kvm'>
  <name>$guest</name>
  <memory unit='GiB'>1</memory>
  <vcpu placement='static'>12</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 create $guest.xml
virsh console $guest

TAB --> to get the chance to see the syslinux prompt

^]

Maintenance

virsh list # should NOT run
losetup -a # already mapped?
    losetup --find --partscan --show $guest.img
fsck /dev/loop3p1
mount /dev/loop3p1 lala/
...

umount -R lala/
losetup --detach /dev/loop3

Troubles

"Error: AppArmor parser not found"

ERROR: Can't find apparmor_parser at /sbin/apparmor_parser

–> /sbin is a symlink since focal, did you mess it up by installing pkgtools?…

TODO

Resources

QemuKVMMigration https://wiki.ubuntu.com/QemuKVMMigration

QEMU Unsupported Machine Type ‘pc-q35-3.1’ https://forum.level1techs.com/t/qemu-unsupported-machine-type-pc-q35-3-1/140084

How can I change Qemu KVM machine architecture from 440fx to q35 with virsh edit or virt-manager https://serverfault.com/questions/637917/how-can-i-change-qemu-kvm-machine-architecture-from-440fx-to-q35-with-virsh-edit


GUIDES | LECTURES | BENCHMARKS | SMTP HEALTH