From Segfault
Jump to navigation Jump to search

Debian & Ubuntu

In Debian and Ubuntu this is called Preseed and is documented in the Installation Guide.[1][2]

The most difficult part was to find out how to pass the preseed file to the installer[3]. To use a preseed file on a remote web server, the following boot options got it going:[4]

auto=true priority=critical url=


  • We use auto=true to get the automatic configuration actually going[5]
  • We use priority=critical to skip non-essential question
debconf-get-selections --installer > preseed.cfg
debconf-get-selections >> preseed.cfg

We also need a server or netboot image as desktop images tend to ignore any auto-configuration parameters.[4]

The configuration file for both distributions is similar but differ in the details.

Both are heavily documented, except for the partition management part (d-i partman)[6][7]. To validate the preseeed file:

$ debconf-set-selections -c preseed.cfg
debconf: DbDriver "passwords" warning: could not open /var/cache/debconf/passwords.dat: Permission denied

For some reason we need to make a debconf file readable and try again:

sudo setfacl -m g:staff:r /var/cache/debconf/passwords.dat
debconf-set-selections -c preseed.cfg


d-i debian-installer/locale string en_US.UTF-8
d-i console-setup/ask_detect boolean false
d-i keyboard-configuration/layoutcode string us
d-i keyboard-configuration/xkb-keymap select us

# Note: to (temporarily) disable IPv6, add ipv6.disable=1 to the boot parameters.
d-i netcfg/choose_interface select auto
d-i netcfg/get_hostname string foobar
d-i netcfg/get_domain string

# Disable network autoconfiguration
# d-i netcfg/disable_autoconfig boolean true

# Continue with failed autoconfiguration
# d-i netcfg/dhcp_failed note
# d-i netcfg/dhcp_options select Configure network manually

# Static
# d-i netcfg/get_ipaddress string
# d-i netcfg/get_netmask string
# d-i netcfg/get_gateway string
# d-i netcfg/get_nameservers string
# d-i netcfg/confirm_static boolean true
# d-i netcfg/hostname string debian

# Debian
# d-i mirror/http/hostname string
# d-i mirror/http/directory string /debian

# Ubuntu
# d-i mirror/http/mirror select
# d-i mirror/http/directory string /ubuntu

# For Ubuntu:
# d-i apt-setup/restricted boolean false
# d-i apt-setup/universe boolean true
# d-i apt-setup/backports boolean false

# APT-Proxy
# d-i mirror/http/proxy string

d-i clock-setup/utc boolean true
d-i time/zone string PST8PDT
d-i clock-setup/ntp boolean true

# Partition Setup
d-i partman-auto/disk string /dev/sda
d-i partman-auto/method string regular

# The partition setup is documented in partman-auto-recipe.txt, sort of.
# In this case, our root disk is 4 GB in size and we will create two
# partitions - one for the rootfs and a small one for swap space.
d-i partman-auto/expert_recipe string			\
	root-swap ::					\
		1024 8192  -1 ext4			\
		$primary{ } $bootable{ }		\
		method{ format } format{ }		\
		use_filesystem{ } filesystem{ ext4 }	\
		mountpoint{ / }				\
		.					\
		 128  512 192 linux-swap                \
		$primary{ }				\
		method{ swap } format{ }		\

d-i grub-installer/only_debian boolean true
d-i grub-installer/bootdev string default

d-i base-installer/install-recommends boolean false
d-i base-installer/kernel/image string linux-image-amd64

d-i passwd/root-login boolean root
d-i passwd/make-user boolean true

# Passwords can be given in plain text:
# d-i passwd/root-password password s3cr3t
# d-i passwd/root-password-again password s3cr3t

# Passwords can be given as its hashed version too. In modern distribututions this would be
# a SHA-512 hash with a salt and we can use mkpasswd[8][9] or Python to generate[10][11] a password:
# > salt=$(pwgen -s 16 1)
# > salt=$(openssl rand -hex 8)                                      # If pwgen(1) is not installed
# > mkpasswd -m sha-512 -S $salt s3cr3t
# > python -c "import crypt; print(crypt.crypt('s3cr3t', \"\$6\$${salt}\"))"
d-i passwd/user-password-crypted password $6$y1MlUGqYXToNxClF$c9Bq9LgD[...]
d-i user-setup/allow-password-weak boolean true
d-i passwd/user-default-groups string sudo
d-i user-setup/encrypt-home boolean false

d-i passwd/user-fullname string dummy
d-i passwd/username string dummy

# d-i passwd/user-password password s3cr3t
# d-i passwd/user-password-again password s3cr3t
d-i passwd/user-password-crypted password $6$fe396b37668fe187$dndgEbrlcUukR5RNxaXpcV9VPWM1fieuKWdKyF3qYNo9zhQvdzWAv0IqwKOQFgI8qgY9wfeWXKqXgPWE07fGt/
d-i user-setup/allow-password-weak boolean true
d-i passwd/user-default-groups string sudo
d-i user-setup/encrypt-home boolean false
# Install some basic packages
# Note: if one of these packages cannot be found/installed, the installer will stop!
d-i pkgsel/include string acl apt-file apt-listchanges atop attr autossh bc bzip2 ca-certificates chrony cryptsetup curl deborphan devscripts debsums ecryptfs-utils git-core haveged s-nail htop iftop iotop irqbalance ksh less libpam-tmpdir lsof mlocate moreutils netcat-openbsd openssh-server openvpn p7zip-full pbzip2 pigz pv pwgen pxz rsync screen sharutils smartmontools ssmtp strace subversion sudo sysstat thermald vim vnstat whois zsh
d-i pkgsel/update-policy select none
# tasksel tasksel/first multiselect ssh-server

# Post Exec
d-i preseed/late_command string cd /target/root && wget -O- | sh

d-i finish-install/reboot_in_progress note


In Fedora this is called Pykickstart (formerly Kickstart) and is documented in the manual[12]. To create a kickstart file with a GUI, we could use system-config-kickstart - of course we'd need a running Fedora instance first:

sudo dnf install system-config-kickstart xorg-x11-xauth libcanberra-gtk2 PackageKit-gtk3-module dejavu-lgc-sans-fonts
  • xorg-x11-xauth is needed so that X11 forwarding will work properly.
  • libcanberra-gtk2 is needed to prevent the Failed to load module "canberra-gtk-module" message.
  • PackageKit-gtk3-module is needed to prevent the Failed to load module "pk-gtk-module" message.
  • dejavu-lgc-sans-fonts is needed, otherwise the system-config-kickstart window may not be readable.


With that in place, we can start system-config-kickstart as a normal user now. After configuration[13], we should have something like this[14] in place:

# Install OS instead of upgrade

# Keyboard layouts
keyboard us

# System language
lang en_US.UTF-8

# System timezone
timezone Europe/Berlin --isUtc

# Use text mode install

# Use CDROM installation media

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

# Root password
rootpw --plaintext root

# Create a user account
user --name=dummy --password='dummy' --plaintext

# SELinux configuration
selinux --enforcing

# Do not configure the X Window System

# Firewall configuration
firewall --enabled --port=ssh

# Enable/disable services
services --enabled=sshd --disabled=NetworkManager

# Network information
network  --bootproto=dhcp --device=link --ipv6=auto --activate
# network

# System bootloader configuration
bootloader --location=mbr --boot-drive=sda

# Clear the Master Boot Record

# Partition clearing information
clearpart --all --initlabel --drives=sda

# Disk partitioning information
ignoredisk --only-use=sda
part    / --asprimary --fstype="ext4" --size=1 --grow
part swap --asprimary --fstype="swap" --size=128

# Repos
url                             --mirrorlist="$releasever&arch=$basearch"
repo    --name=fedora           --mirrorlist="$releasever&arch=$basearch"
repo    --name=fedora-updates   --mirrorlist="$releasever&arch=$basearch"

# yum-plugin-changelog
# yum-plugin-fastestmirror
# yum-plugin-remove-with-leaves
# yum-utils

%post --log=/root/ks-post.log
chkconfig network on

# Halt after installation

Put the resulting file on a nearby webserver and boot[15] a Fedora installation with: