Anaconda und Kickstart

Anaconda, welches hauptsächlich aus dem Hause Red Hat stammt, ist ein Installationsprogramm zur manuellen oder automatisierten Installation eines Linux-Betriebssystems (und nicht mit der freien wissenschaftlichen Python-Distribution mit dem gleichen Namen zu verwechseln). Anaconda bietet seinen Installationsassistenten je nach Wunsch oder System-Ressourcen per GUI oder TUI an.

Anaconda wandelt sich von Version zu Version stark und wird meist einfacher und klarer. Trotzdem hält sich das Gerücht, dass Anaconda ein DAU-Filter sei, da er an den entscheidenden Stellen nicht so intuitiv und für Linux-Einsteiger wenig geeignet ist.

Die Datei, um die Installation automatisiert durchzuführen (dem Installationsassistenten also die Antworten unterzuschieben), nennt sich Kickstart. Zu jeder Neuinstallation erzeugt Anaconda automatisch die Datei /root/anaconda-ks.cfg, die als Setup-Referenz dient, und mit der man das System unbeaufsichtigt wieder in den Ursprungszustand versetzen kann.

Eine Kickstart-Datei lässt sich wie folgt auf Korrektheit prüfen:

yum -y install pykickstart
ksvalidator /root/anaconda-ks.cfg

Ist die Kickstart-Datei vailde, beendet sich ksvalidator ohne Fehler.

Aufruf einer Kickstart-Installation (früher genügte die Angabe von ks=, heute muss es inst.ks= heissen):

boot: linux inst.ks=https://www.example.com/ks/mykickstart.cfg

Weiterführende Links

Kickstart-Datei

Allgemeiner Aufbau

Innerhalb der einzelnen Sektionen kommt es seltenst auf die Reihenfolge der Kommandos an. Im Zweifel Doku zu Rate ziehen.

# mandatory sections

command section

%packages section
%end


# optional sections

%pre
%end

%pre-install
%end

%post
%end

%onerror
%end

%traceback
%end

Command Section

Sammelsurium an Befehlen in der Command Section, aus dem Alltag:

# System authorization information
auth --enableshadow --passalgo=sha512

# GUI/TUI: Use graphical install
graphical

# GUI/TUI: Use textual install
text

# Installation Media: Use CDROM installation media
cdrom

# Installation Media: Use hard drive installation media
harddrive --dir=None --partition=/dev/mapper/live-base

# Installation Media: Use HTTP or FTP
url --url="http://10.80.32.58/iso"

# System Timezone
timezone Europe/Zurich --utc

# System Timezone
timezone Europe/Zurich --isUtc --nontp

# Keyboard Layout: Swiss German
keyboard --vckeymap=ch --xlayouts='ch'

# Keyboard Layout: US
keyboard --vckeymap=us --xlayouts='us'

# System Language
lang en_US.UTF-8

# Network: Set Hostname
network --hostname=localhost.localdomain

# Network: Static
network  --bootproto=static --device=eth0 --gateway=192.168.122.1 --ip=192.168.122.111 --nameserver=1.0.0.1,1.1.1.1 --netmask=255.255.255.0 --ipv6=auto --activate

# Network: DHCP
network  --bootproto=dhcp --device=enp1s0 --ipv6=auto --activate

# Run the Setup Agent on first boot
firstboot --enable

# Root password: Set root password
rootpw --iscrypted $6$SClI7oo...Mi/waVA3Frinvz0

# Root password: Don't set a root password
rootpw --lock

# System services
services --disabled="chronyd"
services --enabled="chronyd"

ignoredisk --only-use=vda,nvme0n1

# Partition clearing information
clearpart --none --initlabel

# System bootloader configuration
bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=vda

# Disk: Automatic Partitioning
autopart --type=lvm

# Boot Partition: Manual Partitioning with BIOS-/Legacy-Boot and XFS, on one partition
part /boot --fstype="xfs" --ondisk=sda --size=1024
part pv.01 --fstype="lvmpv" --ondisk=sda --size=1024 --grow

# Boot Partition: Manual Partitioning with UEFI-Boot and Ext4, on one partition
part /boot --fstype="ext4" --ondisk=nvme0n1 --size=1024
part /boot/efi --fstype="efi" --ondisk=nvme0n1 --size=600 --fsoptions="umask=0077,shortname=winnt"

# OS Partition
part pv.01 --fstype="lvmpv" --ondisk=nvme0n1 --size=1024 --grow

# Include a file that was created in Pre-Section
%include /tmp/disk-part.ks

# LVM: Volume Group (requires >= 4GB Disk)
volgroup centos --pesize=4096 pv.01

# LVM: LV - Unencrypted, XFS (/: use minimum 1024MB, but use more if available)
logvol swap  --fstype="swap" --recommended --name=swap --vgname=centos
logvol / --fstype="xfs" --grow --size=1024 --name=root --vgname=centos

# LVM: LV - Encrypted, Ext4
logvol swap --fstype="swap" --size=7857 --encrypted --luks-version=luks2 --name=swap --vgname=centos
logvol / --fstype="ext4" --size=967276 --encrypted --luks-version=luks2 --name=root --vgname=centos


# LVM: LV - CIS-compliant (/home, /tmp, /var, /var/log, /var/log/audit and /var/tmp on their own partitions)
# all sizes are in MB
# the sizes of the LVM LV's below require a disk with 30 GB
# Anaconda creates the LVs in reverse order; LVs listed at the end will be created first
logvol /backup        --fstype="xfs" --size=6144     --vgname=centos --name=backup        --fsoptions="nodev"
logvol /var           --fstype="xfs" --size=6144     --vgname=centos --name=var           --fsoptions="nodev"
logvol /              --fstype="xfs" --size=8192     --vgname=centos --name=root
logvol /home          --fstype="xfs" --size=1024     --vgname=centos --name=home          --fsoptions="nodev"
logvol /tmp           --fstype="xfs" --size=1024     --vgname=centos --name=tmp           --fsoptions="nodev,noexec,nosuid"
logvol /var/log       --fstype="xfs" --size=1024     --vgname=centos --name=var_log       --fsoptions="nodev,noexec,nosuid"
logvol /var/log/audit --fstype="xfs" --size=512      --vgname=centos --name=var_log_audit --fsoptions="nodev,noexec,nosuid"
logvol /var/tmp       --fstype="xfs" --size=1024     --vgname=centos --name=var_tmp       --fsoptions="nodev,noexec,nosuid"
logvol swap           --fstype="swap" --recommended  --vgname=centos --name=swap


# Do not configure the X Window System
skipx

repo --name="AppStream" --baseurl=file:///run/install/repo/AppStream

# Do something at the end of the setup
shutdown

%addon com_redhat_kdump --enable --reserve-mb='auto'
%end

%addon com_redhat_kdump --disable --reserve-mb='auto'
%end

%addon org_fedora_oscap
    content-type = scap-security-guide
    profile = xccdf_org.ssgproject.content_profile_cis
%end

%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end

Tipp

Zur logvol-Direktive:

  • die alleinige Angabe von --size erzeugt ein LogVol mit genau der angegebenen Grösse, in MB

  • --grow bedeutet: nimm dir mindestens --size MB, und wenn mehr Platz da ist, nimm dir den ganzen Rest, aber maximal bis zur optionalen --maxsize, und vorheriger Berücksichtigung aller statischen Grössenangaben

  • wird --grow mehrfach verwendet, werden die einzelnen LV zu gleichen Teilen erstellt

  • statt mit --size, --maxsize und --grow, die Absolutwerte darstellen, lässt sich auch mit --percent arbeiten

%packages Section

%packages
@^minimal-environment
aide
audit
chrony
firewalld
kexec-tools
libselinux
openscap
openscap-scanner
rsyslog
scap-security-guide
sudo
-mcstrans
-openldap-clients
-setroubleshoot
-squid
-telnet
-xinetd
-xorg-x11-server-common
-ypbind
%end

%pre Section

Wird vor dem Start des Setups ausgeführt. Im Beispiel wird eine Kickstart-Datei mit Informationen zu Disk-Grössen dynamisch generiert und in der Command-Section per %include eingebunden.

%pre
#!/bin/sh
touch /tmp/disk-part.ks
# get disk size in GiB
DISKSIZE=$(parted -sm /dev/sda unit GiB print | grep -e "/dev/sda:[0-9]*GiB" | cut -d: -f2 | sed -e 's/GiB$//')
if [ ! -e /sys/firmware/efi ]; then
    # boot mode: BIOS
    if [ $DISKSIZE -gt 2000 ]; then
        # and GPT needed -> create biosboot
        echo "part biosboot --fstype=biosboot --size=1 --ondisk=sda" > /tmp/disk-part.ks
    fi
fi
%end

%post Section

Die %post-Sektion wird nach der Betriebssystem-Installation und vor dem Poweroff/Reboot ausgeführt. Diese Beispiel legt unter anderem vordefinierte Public SSH-Keys auf der Maschine ab.

%post
yum -y install nano wget

#---- Install our SSH keys ----
mkdir -m0700 /root/.ssh/

cat <<EOF >/root/.ssh/authorized_keys
ssh-rsa AAAA...ddNKw== alice@linuxfabrik.ch
ssh-ed25519 AAAA...ehO bob@linuxfabrik.ch
EOF

### set permissions
chmod 0600 /root/.ssh/authorized_keys

### fix selinux context
restorecon -R /root/.ssh/
%end

Gehärtete Kickstart-Datei

Diese Kickstart-Datei (getestet mit CentOS 8) setzt die Security-Anforderungen der Security-Profile der CIS, PCI-DSS, E8, OSPP, STIG etc. um - die Haupt-Anforderung liegt im Partitionierungsschema; nachträgliche System-Anpassungen nimmt man am besten per Ansible oder Shell-Skript vor:

#version=RHEL8

# Use text mode install
text

# Run the Setup Agent on first boot
firstboot --enable

# Keyboard layouts
keyboard --vckeymap=ch --xlayouts='ch'

# System language
lang en_US.UTF-8

# Root password
# Plaintext password is: password
rootpw --iscrypted $6$YxsFrMkfy1PIRvCU$GJfIziATCSEOIaGLIrTa6aO1INNiNRforoW1k4N1AVju4FnCltEp6fOaq1GJdHTFaVuOmTpuTcrCAOXsXmtov1


# Do not configure the X Window System
skipx

# System services
services --disabled="chronyd"

# System timezone
timezone Europe/Zurich --isUtc --nontp


# We will restrict root login
# Add a user that can login and escalate privileges
# Plaintext password is: password
user --name=linuxfabrik --groups=wheel --iscrypted --password=$6$YxsFrMkfy1PIRvCU$GJfIziATCSEOIaGLIrTa6aO1INNiNRforoW1k4N1AVju4FnCltEp6fOaq1GJdHTFaVuOmTpuTcrCAOXsXmtov1

# Configure firewall settings for the system (optional)
# --enabled reject incoming connections that are not in response to outbound requests
# --ssh     allow sshd service through the firewall
firewall --enabled --ssh

# State of SELinux on the installed system (optional)
# Defaults to enforcing
selinux --enforcing


# System bootloader configuration
bootloader --location=mbr --append="audit=1 audit_backlog_limit=8192 slub_debug=P page_poison=1 vsyscall=none"

# Initialize (format) all disks (optional)
zerombr

# The following partition layout scheme assumes disk of size 20GB or larger
# Modify size of partitions appropriately to reflect actual machine's hardware
#
# Remove Linux partitions from the system prior to creating new ones (optional)
# --linux   erase all Linux partitions
# --initlabel   initialize the disk label to the default based on the underlying architecture
clearpart --linux --initlabel


# Boot Partition: Manual Partitioning with BIOS-/Legacy-Boot and XFS, on one partition
part /boot --fstype="xfs" --size=1024

# OS Partition
part pv.01 --fstype="lvmpv" --size=1024 --grow


# LVM: Volume Group
volgroup centos --pesize=4096 pv.01


# LVM: LV - CIS-compliant (/home, /tmp, /var, /var/log, /var/log/audit and /var/tmp on their own partitions)
# all sizes are in MB
# the sizes of the LVM LV's below require a disk with 30 GB
# Anaconda creates the LVs in reverse order; LVs listed at the end will be created first
logvol /var           --fstype="xfs" --size=6144     --vgname=centos --name=var           --fsoptions="nodev"
logvol /              --fstype="xfs" --size=8192     --vgname=centos --name=root
logvol /home          --fstype="xfs" --size=1024     --vgname=centos --name=home          --fsoptions="nodev"
logvol /tmp           --fstype="xfs" --size=1024     --vgname=centos --name=tmp           --fsoptions="nodev,noexec,nosuid"
logvol /var/log       --fstype="xfs" --size=1024     --vgname=centos --name=var_log       --fsoptions="nodev,noexec,nosuid"
logvol /var/log/audit --fstype="xfs" --size=512      --vgname=centos --name=var_log_audit --fsoptions="nodev,noexec,nosuid"
logvol /var/tmp       --fstype="xfs" --size=1024     --vgname=centos --name=var_tmp       --fsoptions="nodev,noexec,nosuid"
logvol swap           --fstype="swap" --recommended  --vgname=centos --name=swap


# Reboot after the installation is complete (optional)
# --eject   attempt to eject CD or DVD media before rebooting
reboot --eject


%packages
@^minimal-environment
%end


%pre

%end


%post
#---- Install SSH keys ----
mkdir -m0700 /root/.ssh/

cat <<EOF >/root/.ssh/authorized_keys
ssh-rsa AAAAB3Nz...
ssh-ed25519 AAAAC3Nz...
EOF

### set permissions
chmod 0600 /root/.ssh/authorized_keys

### fix up selinux context
restorecon -R /root/.ssh/
%end

Troubleshooting

DNF error: Error in POSTTRANS scriptlet in rpm package kernel-core

Kann an zu wenig Platz für /var/tmp liegen. Hier sind mindestens 384 MB empfohlen.

Built on 2022-06-03