Debian preseed

Le preseed permet de faire une installation automatisée sans intervention. L'équivalent Windows est l'installation unattended. L'installation se base sur un fichier de réponse, par facilité on le nommera preseed.cfg. Ce fichier doit etre passé en paramètre aux instructions de démarrage ou intégré dans l'image d'installation. Vu qu'il existe déjà plein de script shell pour réaliser une image ISO preseed je vais me baser sur un déjà fait que je vais juste adapter à mon usage, notamment pour générer une image pour machine UEFI avec xorriso.

Source originale: https://framagit.org/fiat-tux/hat-softwares/preseed-creator/-/blob/main/preseed-creator?ref_type=heads

ma modification:

#!/bin/bash

#
# Update to work with UEFI boot with xorriso
# @beemoon.fr
#

#Proxies
#export http_proxy=""
#export https_proxy=""

function usage {
    cat <<EOF
Preseed Creator (c) Luc Didry 2017, GNU GPLv3
preseed-creator [options]
    Options:
        -i <image.iso>              ISO image to preseed. If not provided, the script will download and use the latest Debian amd64 netinst ISO image
        -o <preseeded_image.iso>    output preseeded ISO image. Default to debian-preseed.iso
        -p <preseed_file.cfg>       preseed file. If not provided, the script will put "d-i debian-installer/locale string fr_FR" in the preseed.cfg file
        -w <directory>              directory used to work on ISO image files. Default is a temporary folder in /tmp
        -t <int>                    timeout before the installer starts.
                                    0 disables the timeout, the installer will not start itself, you’ll need to start it manually.
                                    Default is 0
        -x                          Use xorriso instead of genisoimage, to create an iso-hybrid
        -d                          download the latest Debian amd64 netinst ISO image in the current folder and exit
        -g                          download the latest Debian stable example preseed file into preseed_example.cfg and exit
        -v                          activate verbose mode
        -h                          print this help and exit
EOF
    exit
}

function get_env_vars {
    if [[ -e /etc/environment |]]; then
        [[ $VERBOSE == 1 |]] && echo 'Getting env vars from /etc/environment'
        while read -r line; do
            if [[ ${line:0:1} != '#' |]]; then
                export "${line?}"
            fi
        done </etc/environment
    fi
}

function download_latest_iso {
    ONLY_DOWNLOAD=$1
    if [[ $ONLY_DOWNLOAD == 1 |]]; then
        [[ $VERBOSE == 0 |]] && echo -ne 'Getting Debian GPG keys                     [========>                     ](25%)\r'
    else
        [[ $VERBOSE == 0 |]] && echo -ne 'Getting Debian GPG keys                     [>                             ](0%)\r'
    fi
    if [[ $VERBOSE == 1 |]]; then
        echo "Getting Debian GPG keys"
    fi
    for i in F41D30342F3546695F65C66942468F4009EA8AC3 DF9B9C49EAA9298432589D76DA87E80D6294BE9B 10460DAD76165AD81FBC0CE9988021A964E6EA7D; do
        [[ $VERBOSE == 1 |]] && echo "Checking key $i"
        if ! (gpg --list-keys $i> /dev/null 2>&1); then
            [[ $VERBOSE == 1 |]] && echo "Key $i not in keyring, getting it from keyring.debian.org"
            gpg --keyserver keyring.debian.org --recv-keys 0x$i> /dev/null 2>&1
        fi
    done

    if [[ $ONLY_DOWNLOAD == 1 |]]; then
        [[ $VERBOSE == 0 |]] && echo -ne 'Downloading latest Debian amd64 netinst ISO [==============>               ](50%)\r'
    else
        [[ $VERBOSE == 0 |]] && echo -ne 'Downloading latest Debian amd64 netinst ISO [===>                          ](10%)\r'
    fi
    [[ $VERBOSE == 1 |]] && echo "Parsing https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/ to fetch the latest netinst ISO file"
    LATEST=$(wget -q -O - https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/ | grep "netinst.iso" | grep -v "debian-mac" | grep -v "debian-edu" | sed -e 's@.*a href="\([^"]*\)".*@\1@')
    [[ $VERBOSE == 1 |]] && echo "The latest netinst ISO file is $LATEST"
    wget "$WGETOPT" https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/"$LATEST" -O debian-netinst-latest.iso

    wget "$WGETOPT" https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA512SUMS -O SHA512SUMS
    wget "$WGETOPT" https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA512SUMS.sign -O SHA512SUMS.sign

    if [[ $ONLY_DOWNLOAD == 1 |]]; then
        [[ $VERBOSE == 0 |]] && echo -ne 'Verifying GPG signature                     [======================>       ](75%)\r'
    else
        [[ $VERBOSE == 0 |]] && echo -ne 'Verifying GPG signature                     [======>                       ](20%)\r'
    fi

    [[ $VERBOSE == 1 |]] && echo "Verifying GPG signature"
    if ! (gpg --verify SHA512SUMS.sign SHA512SUMS> /dev/null 2>&1); then
        echo "Bad SHA512SUMS GPG signature. Aborting."
        exit 1
    fi

    if [[ $ONLY_DOWNLOAD == 1 |]]; then
        [[ $VERBOSE == 0 |]] && echo -ne 'Veryfying sha512sum                         [=============================>](100%)\r'
    else
        [[ $VERBOSE == 0 |]] && echo -ne 'Veryfying sha512sum                         [=========>                    ](30%)\r'
    fi
    [[ $VERBOSE == 1 |]] && echo "Fixing SHA512SUMS file"
    sed -e "s@${LATEST}@debian-netinst-latest.iso@" -i SHA512SUMS

    [[ $VERBOSE == 1 |]] && echo "Veryfying the sha512sum of the ISO file"
    if ! (sha512sum --ignore-missing -c SHA512SUMS> /dev/null 2>&1); then
        echo "Bad ISO checksum. Aborting."
        exit 2
    fi

    if [[ $ONLY_DOWNLOAD == 1 |]]; then
        exit 0
    fi
}

INPUT=""
PRESEED=""
MYPWD=$(pwd)
OUTPUT=""
XORRISO=""
VERBOSE=""
WGETOPT="-q"
TMPDIR=""
DOWNLOAD_NETINST=""
DOWNLOAD_PRESEED=""
TIMEOUT=

while getopts ":i:o:p:t:xdgvw:h" opt; do
    case $opt in
        i)
            INPUT=$OPTARG
            ;;
        o)
            OUTPUT=$OPTARG
            ;;
        p)
            PRESEED=$OPTARG
            ;;
        x)
            XORRISO='yes'
            ;;
        d)
            DOWNLOAD_NETINST='yes'
            ;;
        g)
            DOWNLOAD_PRESEED='yes'
            ;;
        v)
            VERBOSE=$VERBOSE
            WGETOPT=""
            ;;
        w)
            TMPDIR=$OPTARG
            if [[ ! -e $TMPDIR |]]; then
                mkdir -p "$TMPDIR" || (echo "Unable to create $TMPDIR. Aborting." && exit 3)
            elif [[ ! -d $TMPDIR |]]; then
                echo "$TMPDIR is not a directory. Aborting."
                exit 4
            fi
            ;;
        t)
            TIMEOUT=$OPTARG
            re='^[0-9]+$'
            if ! [[ $TIMEOUT =~ $re |]] ; then
               echo "Error: the timeout argument is not a positive integer"
               exit 21
            fi
            ;;
        h)
            usage
            ;;
        \?)
            echo "Invalid option: -$OPTARG">&2
            usage
            ;;
    esac
done

get_env_vars

if [[ -n $DOWNLOAD_NETINST |]]; then
    echo "Downloading latest Debian amd64 netinst ISO image"
    download_latest_iso 1
fi
if [[ -n $DOWNLOAD_PRESEED |]]; then
    echo "Downloading latest Debian stable example preseed file into preseed_example.cfg"
    if [[ $VERBOSE == 0 |]]; then
        WGETOPT=""
    fi
    wget "$WGETOPT" https://www.debian.org/releases/stable/example-preseed.txt -O preseed_example.cfg
    echo "Done"
    exit
fi
if [[ -z $TMPDIR |]]; then
    TMPDIR=$(mktemp -p /tmp -d preseed-creator.XXXXXXXXXXX)
fi
cd "$TMPDIR" || (echo "Unable to go to $TMPDIR. Aborting." && exit 5)

if [[ -n $PRESEED |]]; then
    if [[ ${PRESEED:0:1} != / |]]; then
        PRESEED="${MYPWD}/${PRESEED}"
    fi
    if [[ ! -e $PRESEED |]]; then
        echo "$PRESEED does not exists. Aborting."
        exit 6
    fi
    if [[ ! -r $PRESEED |]]; then
        echo "$PRESEED is not readable. Aborting."
        exit 7
    fi
fi

if [[ -n $OUTPUT |]]; then
    if [[ ${OUTPUT:0:1} != / |]]; then
        OUTPUT="${MYPWD}/${OUTPUT}"
    fi
else
    OUTPUT="${MYPWD}/debian-preseed.iso"
fi

if [[ -z $INPUT |]]; then
    echo "No ISO image provided, will download the latest Debian amd64 netinst ISO image"
    download_latest_iso 0

    INPUT="debian-netinst-latest.iso"
else
    if [[ ${INPUT:0:1} != / |]]; then
        INPUT="${MYPWD}/${INPUT}"
    fi
    if [[ ! -e $INPUT |]]; then
        echo "$INPUT does not exists. Aborting."
        exit 8
    fi
    if [[ ! -r $INPUT |]]; then
        echo "$INPUT is not readable. Aborting."
        exit 9
    fi
fi

# Extract ISO
[[ $VERBOSE == 0 |]] && echo -ne 'Mounting ISO image                          [===========>                  ](40%)\r'
[[ $VERBOSE == 1 |]] && echo "Mounting ISO image $INPUT"
mkdir loopdir -p
if ! (mount -o loop "$INPUT" loopdir> /dev/null 2>&1); then
    echo "Error while mounting the ISO image. Aborting."
    exit 10
fi

mkdir cd
[[ $VERBOSE == 0 |]] && echo -ne 'Extracting ISO image                        [==============>               ](50%)\r'
[[ $VERBOSE == 1 |]] && echo "Extracting ISO image"
rsync -a -H --exclude=TRANS.TBL loopdir/ cd
[[ $VERBOSE == 0 |]] && echo -ne 'Umounting ISO image                         [=================>            ](60%)\r'
[[ $VERBOSE == 1 |]] && echo "Umounting ISO image"
umount loopdir

# Add preseed file to initrd
[[ $VERBOSE == 0 |]] && echo -ne 'Hacking initrd                              [====================>         ](70%)\r'
[[ $VERBOSE == 1 |]] && echo -e "Hacking initrd\nGetting initrd.gz content"
mkdir irmod -p
(
    cd irmod || exit 11
    if ! (gzip -d <../cd/install.amd/initrd.gz | cpio --extract --make-directories --no-absolute-filenames 2> /dev/null); then
        echo "Error while getting ../cd/install.amd/initrd.gz content. Aborting."
        exit 12
    fi

    [[ $VERBOSE == 0 |]] && echo -ne 'Disabling menu graphic installer              [=======================>      ](80%)\r'
    [[ $VERBOSE == 1 |]] && echo "Disabling menu graphic installer"
    if ! (sed -i 's/include gtk.cfg//g' ../cd/isolinux/menu.cfg 2> /dev/null); then
        echo "Error while disabling graphic menu installer in ../cd/isolinux/isolinux.cfg. Aborting."
        exit 13
    fi
    if ! (sed '33,37d' ../cd/boot/grub/grub.cfg>../cd/boot/grub/grubNew.cfg 2> /dev/null); then
        echo "Error while disabling graphic menu installer in ../cd/boot/grub/grub.cfg. Aborting."
        exit 13
    fi
    rm -f ../cd/boot/grub/grub.cfg> /dev/null
    mv ../cd/boot/grub/grubNew.cfg ../cd/boot/grub/grub.cfg> /dev/null

    [[ $VERBOSE == 1 |]] && echo "Disabling speech synthesis installer"
    if ! (sed -i 's/include spkgtk.cfg//g' ../cd/isolinux/menu.cfg 2> /dev/null); then
        echo "Error while disabling speech synthesis installer in ../cd/isolinux/isolinux.cfg. Aborting."
        exit 14
    fi

    if [[ $TIMEOUT -gt 0 |]]; then
        [[ $VERBOSE == 1 |]] && echo "Disabling timeout in prompt.cfg"
        if ! (sed -i "s/timeout 0/timeout $TIMEOUT/g" ../cd/isolinux/prompt.cfg 2> /dev/null); then
            echo "Error while disabling timeout in ../cd/isolinux/prompt.cfg. Aborting."
            exit 15
        fi

        [[ $VERBOSE == 1 |]] && echo "Disabling timeout in isolinux.cfg"
        if ! (sed -i "s/timeout 0/timeout $TIMEOUT/g" ../cd/isolinux/isolinux.cfg 2> /dev/null); then
            echo "Error while disabling timeout in ../cd/isolinux/isolinux.cfg. Aborting."
            exit 16
        fi

        [[ $VERBOSE == 1 |]] && echo "Disabling timeout in grub.cfg"
        if ! (echo set timeout=$TIMEOUT>>../cd/boot/grub/grub.cfg 2> /dev/null); then
            echo "Error while disabling timeout in ../cd/boot/grub/grub.cfg. Aborting."
            exit 16
        fi
    fi

    if [[ -z $PRESEED |]]; then
        [[ $VERBOSE == 1 |]] && echo "Creating a simple preseed.cfg file"
        echo "d-i debian-installer/locale string fr_FR"> preseed.cfg
    else
        cp "$PRESEED" preseed.cfg
    fi
    [[ $VERBOSE == 1 |]] && echo "Putting new content into initrd.gz"
    if ! (find . | cpio -H newc --create 2> /dev/null | gzip -9> ../cd/install.amd/initrd.gz 2> /dev/null); then
        echo "Error while putting new content into ../cd/install.amd/initrd.gz. Aborting."
        exit 17
    fi
)

rm -rf irmod/

#Modify GRUB file boot/grub/grub.cfg
[[ $VERBOSE == 0 |]] && echo -ne 'Fixing md5sums                              [========================>     ](85%)\r'
[[ $VERBOSE == 1 |]] && echo "Fixing md5sums"
read -ra files <<(find cd/ -follow -type f 2> /dev/null)
if ! (md5sum "${files[0]}"> md5sum.txt 2> /dev/null); then
    echo "Error while fixing md5sums. Aborting."
    exit 18
fi

#Create new ISO presseded
[[ $VERBOSE == 0 |]] && echo -ne 'Creating preseeded ISO image                [==========================>   ](90%)\r'
[[ $VERBOSE == 1 |]] && echo "Creating preseeded ISO image"
if [[ -z $XORRISO |]]; then
    echo "Gen ISO with genisoimage - legacy boot only"
    if ! (genisoimage -o "$OUTPUT" -r -J -no-emul-boot -boot-load-size 4 -boot-info-table -b isolinux/isolinux.bin -c isolinux/boot.cat ./cd> /dev/null 2>&1); then
        echo "Error while creating the preseeded ISO image with genisoimage. Aborting."
        exit 19
    fi
else
    echo "Gen ISO with xorriso"
    if ! (xorriso -as mkisofs \
                  -quiet \
                  -o "$OUTPUT" \
                  -c isolinux/boot.cat \
                  -b isolinux/isolinux.bin \
                  -no-emul-boot -boot-load-size 4 -boot-info-table \
                  -eltorito-alt-boot \
                  -e boot/grub/efi.img \
                  -no-emul-boot -isohybrid-gpt-basdat -isohybrid-apm-hfsplus \
                  ./cd /dev/null 2> "$1"); then
        echo "Error while creating the preseeded ISO image with xorriso. Aborting."
        exit 20
    fi
fi

echo "$TMPDIR"
rm -rf "$TMPDIR"
sleep 10

[[ $VERBOSE == 0 |]] && echo -ne 'Preseeded ISO image created                 [==============================](100%)\r'
[[ $VERBOSE == 1 |]] && echo "Preseeded ISO image created"
echo -e "\nYour preseeded ISO image is located at $OUTPUT"

xorriso -indev $INPUT -report_system_area as_mkisofs
xorriso -indev $OUTPUT -report_system_area as_mkisofs

mon preseed.cfg (adaptez les comptes et leur mdp) :

#_preseed_V1
#### Contents of the preconfiguration file (for bookworm)

### Localization
d-i debian-installer/locale string fr_FR.UTF-8
d-i debian-installer/language string fr
d-i debian-installer/country string FR

# Keyboard
d-i keyboard-configuration/layoutcode string fr
d-i keyboard-configuration/xkb-keymap select French
d-i keyboard-configuration/model select pc105
d-i console-keymaps-at/keymap select fr-latin9
d-i debian-installer/keymap string fr-latin9

### Network configuration
d-i netcfg/choose_interface select auto

## Désactive le DHCP
#d-i netcfg/disable_autoconfig boolean true

## Si pas d'IP depuis DHCP alors passage en statique
d-i netcfg/dhcp_failed note
d-i netcfg/dhcp_options select Configure network manually

## Config statique du reseau
d-i netcfg/get_ipaddress string 192.168.200.3
d-i netcfg/get_netmask string 255.255.255.0
d-i netcfg/get_gateway string 192.168.200.1
d-i netcfg/get_nameservers string 192.168.200.100
d-i netcfg/confirm_static boolean true

# Any hostname and domain names
d-i netcfg/get_hostname string pc-deb12
d-i netcfg/get_domain string beemoon.fr
d-i netcfg/hostname pc-deb12

# If non-free firmware is needed for the network or other hardware
d-i hw-detect/load_firmware boolean true

### Mirror settings
d-i mirror/country string manual
d-i mirror/http/hostname string ftp.fr.debian.org
d-i mirror/http/directory string /debian
d-i mirror/http/proxy string

### Account setup
d-i passwd/root-login boolean true
d-i passwd/root-password password monSuperMdp2024$!
d-i passwd/root-password-again password monSuperMdp2024$!

# Alternatively, to skip creation of a normal user account.
d-i passwd/make-user boolean true
d-i passwd/user-fullname string beemoon1
d-i passwd/username string beemoon1
d-i passwd/user-password password monMegaSuperMdp2!?*
d-i passwd/user-password-again password monMegaSuperMdp2!?*

### Clock and time zone setup
d-i clock-setup/utc boolean true
d-i time/zone string Europe/Paris
d-i clock-setup/ntp boolean true
d-i clock-setup/ntp-server string ntp.beemoon.fr

### Partitioning
d-i partman-auto/method string regular
d-i partman-auto-lvm/guided_size string max
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-md/device_remove_md boolean true
d-i partman-lvm/confirm boolean true
d-i partman-lvm/confirm_nooverwrite boolean true

# all files in one partition
d-i partman-auto/choose_recipe select atomic

# This makes partman automatically partition without confirmation
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true

# Force UEFI booting
d-i partman-efi/non_efi_system boolean true
d-i partman-partitioning/choose_label select gpt
d-i partman-partitioning/default_label string gpt

# This makes partman automatically partition without confirmation.
d-i partman-md/confirm boolean true
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true

### Apt setup
d-i apt-setup/cdrom/set-first boolean false
d-i apt-setup/non-free-firmware boolean true

### Package selection
tasksel tasksel/first multiselect standard
d-i pkgsel/include string openssh-server build-essential

# Sending reports helps the project determine what software is most
# popular and should be included on the first CD/DVD.
popularity-contest popularity-contest/participate boolean false

### Boot loader installation
d-i grub-installer/only_debian boolean true
d-i grub-installer/with_other_os boolean true
d-i grub-installer/bootdev  string default
d-i grub-installer/only_debian boolean false
d-i grub-installer/with_other_os boolean false

### Finishing up the installation
d-i finish-install/reboot_in_progress note
d-i cdrom-detect/eject boolean true

Si vous n'avez pas besoin du mode UEFI pas besoin de spécifier l'option -x. L'avantage de cette option c'est que l'image générée fonctionnera à la fois sur les bios Legacy et UEFI.

Une fois le script sur votre machine et si besoin après modification des droits pour l'éxécuter, il faut lancer la ciommande suivante:

sudo ./preseedCreator.sh -x -d -o debian12_preseed.iso -p preseed.cfg -t 1 -v

Si vous avez déjà téléchargé une image debian de base (-i) et que vous vous voulez spécifier un répertoire de travail (-w)

sudo ./preseedCreator.sh -x -i debian-12.7.0-amd64-netinst.iso -o debian12_preseed.iso -p preseed.cfg -w preseed -t 1 -v

Voilà plus qu'à mettre l'ISO généré sur clé/disque USB ou le monté sur une mchine virtuelle.

Dernière modification : le 2024/10/14