Nachdem einem Update der NAS-Hardware wird es nun Zeit für eine Neuinstallation und ein paar kleine Änderungen. Fehler, Verbesserungen oder Anmerkungen können mir gern per Email geschickt werden.

Fähigkeiten

  • Halbwegs sicherer Umgang mit einer Linux Konsole / Terminal.
  • USB-Stick mit Debian Live
  • Kenntnisse über Partitionierung und Formatierung (siehe auch meine Blog-Einträge: Partitionieren & Formatieren dazu).

Anforderungen

  1. Stabil und sicher
  2. Verschlüsselung der OS-Festplatte
  3. Software-Raid-Funktionalität
  4. Deterministische Installation
  5. Individuelle Installation

Damit kommt für mich, fast schon automatisch, ein Debian Stable in Frage. Oft wird ext4 und LVM dazu verwendet. Hier wird btrfs eingesetzt. Swap wird in Form einer Swapfile genutzt, damit wird eine verschlüsselte Partition gespart. … Damit liegt einzig die Boot-Partition unverschlüsselt auf der Platte.

In einer späteren Anleitung wird Secure Boot, Measured Boot und Trustet Boot ergänzt.

Limitationen

Vergangene Limitationen:

  • btrfs mit swap … erst ab Linux-Kernel-Version 5.6.
  • btrfs mounten mit … -o discard=async … … erst ab Linux-Kernel-Version 5.6.
  • luks2 statt luks1 für die Partition mit /boot … erst ab Grub-Version 2.04.

Da ein aktueller Kernel ab Version 6 mit Debian Stable kommt, gibt es diese Einschränkungen nicht mehr. Allerdings konnte ich bisher keine luks2-Partition mit enthaltenem btrfs von GRUB aus booten. Hinwesie nehme ich sehr gern per Email an.

Partition Layout

Wir werden auf einem PC GNU/Linux Debian Stable (Codename Bookworm / Version 12) installieren. Das Partitions-Layout wird wie folgt sein:

DEVICE                TYPE                            SIZE    MOUNTPOINT
nvme0n1               gpt                             
├─nvme0n1p1             part, vfat (F32)              512M    /efi
├─nvme0n1p2             part, ext4                   4096M    /boot
└─nvme0n1p3             part, crypt                   421G
  ├─nvme0n1p3_crypt       btrfs @snapshot
  ├─nvme0n1p3_crypt       btrfs @sys-home                     /home
  ├─nvme0n1p3_crypt       btrfs @sys-debian-root              /
  ├─nvme0n1p3_crypt       btrfs @sys-debian-var               /var
  ├─nvme0n1p3_crypt       btrfs @sys-debian-var-log           /var/log
  └─nvme0n1p3_crypt       btrfs @sys-debian-swap              /swap

ISO-Abbild

DEBVER="12.4.0"
DEBARCH="amd64"
DEBDESKTOP="gnome"
    # cinnamon,gnome,kde,lxde,lxqe,mate,standard,xfce
wget https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/debian-live-${DEBVER}-${DEBARCH}-${DEBDESKTOP}.iso
    # Download eines ISO-Abbildes.
    # Siehe auch: [Debian - Live Install Images](https://www.debian.org/CD/live/)
wget -O debian-live-${DEBVER}-${DEBARCH}-SHA512SUMS https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/SHA512SUMS
wget -O debian-live-${DEBVER}-${DEBARCH}-SHA512SUMS.sign https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/SHA512SUMS.sign
gpg2 --recv-keys DF9B9C49EAA9298432589D76DA87E80D6294BE9B
    # Debian CD signing key <debian-cd@lists.debian.org> (2011-01-05)
gpg2 --recv-keys F41D30342F3546695F65C66942468F4009EA8AC3
    # Debian Testing CDs Automatic Signing Key <debian-cd@lists.debian.org> (2014-04-15)
gpg2 --verify debian-live-${DEBVER}-${DEBARCH}-SHA512SUMS.sign
    # Die Checksummen-Datei verifizieren
sha512sum --ignore-missing -c debian-live-${DEBVER}-${DEBARCH}-SHA512SUMS
dd if=debian-live-${DEBVER}-${DEBARCH}-${DEBDESKTOP}.iso of=/dev/sdX
    # Kopieren des Abbildes auf einen USB-Stick.
    # Mittels 'lsblk' oder 'parted -l' können alle angeschlossenen Blockgeräte angezeigt werden.

Schritt für Schritt

Start

  • Booten vom USB-Stick.
  • Live-System starten.
  • In den Einstellungen
    • die Sprache des Keyboard anpassen und
    • ggf. die Bildschirmauflösung ändern.

SODO / ROOT

  • Terminal öffnen:
sudo -s

# Color prompt.
PS1='\[\033[00;31m\]\u\[\033[00m\]@\[\033[00;32m\]\h\[\033[00m\]:\[\033[01;34m\]\w \[\033[00m\]#\[\033[00m\]'

loadkeys de
  • loadkeys de oder loadkeys de-latin1
    • Ändern des Tastaturlayouts (Standard ist us), falls es mit obiger Variante nicht funktioniert.
    • Man tippt also loadkezs deßlatin1 mit einer deutschen Tastatur auf englischem Layout.

Check environment

  • mount | grep efivars
    • Überprüfung der EFI-Variablen
    • Ausgabe: → efivars on /sys/firmware/efi/efivars type efivars (rw,nosuid,nodev,noexec,realatime)
  • dmesg | grep TPM
    • Überprüfen, ob ein TPM verfügbar ist.
  • mokutil --sb-state
    • Überprüfen, ob SecureBoot verfügbar ist
  • lsblk oder parted -l
    • Überprüfung der angeschlossenen Laufwerke.
  • Achtung: Da man von USB-Stick gebootet hat, kann es sein, dass dieser unter /dev/sda angesprochen wird und die Zielplatte z. B. unter /dev/sdb zu finden ist.
  • Anhand der dargestellten Eigenschaften sollte man die Zielplatte erkennen.
  • In dieser Anleitung wird das Speichergerät, auf welchem Debian installiert werden soll, mit /dev/nvme0n1 bezeichnet.
    • Hier ist ein NVMe-Laufwerk in Verwendung.

Falls vorher unverschlüsselte Daten auf der Platte gespeichert waren, die auch wirklich verschwinden sollen:

  • shred --verbose --random-source=/dev/urandom --iterations=3 /dev/sdX
    • oder dd if=/dev/urandom of=/dev/sdX
    • Dieser Schritt ist nur notwendig, falls vorher unverschlüsselte Daten auf der Festplatte waren.
    • Das überschreiben mit Zufallszahlen kann sehr lang dauern.
    • ACHTUNG: SSDs mögen es gar nicht, wenn sie komplett neu beschrieben werden. Es ist aber notwendig, da in irgend einem Speicherbereich noch alte Reste gefunden werden könnten. Wenn man gleich von Anfang an verschlüsselt, muss man diesen Schritt hier nicht machen.

Damit man im Live-System gut mit Copy-Paste durch kommt ein paar Variablen. (Fedora nutzt für die Cryptnamen statt sda1_crypt die UUID a la luks-2a4b8c2d4e-a1b2-4711-0815-f1e3g5i7k9m0.)

Check network

ping -c 3 duckduckgo.com
  • If not working, you may activate dhcpd.
    • dhcpcd

Variables

DEV1="/dev/nvme0n1"
DEV1PART="nvme0n1p"

DEV1PART1NAME="${DEV1PART}1"
DEV1PART2NAME="${DEV1PART}2"
DEV1PART3NAME="${DEV1PART}3"

DEV1PART1="/dev/${DEV1PART1NAME}"
DEV1PART2="/dev/${DEV1PART2NAME}"
DEV1PART3="/dev/${DEV1PART3NAME}"

DEV1PART1CRYPTNAME="Not_in_use_as_crypt_ESP_EF00"
DEV1PART2CRYPTNAME="Not_in_use_as_crypt_BOOT"
DEV1PART3CRYPTNAME="${DEV1PART3NAME}_crypt"

DEV1PART1CRYPT="Not_in_use_as_crypt"
DEV1PART2CRYPT="Not_in_use_as_crypt"
DEV1PART3CRYPT="/dev/mapper/${DEV1PART3CRYPTNAME}"

DEV1PART könnte sein: sda, hdb oder nvme0n1p.

Partitioning

# Precheck.
echo ${DEV1}

# Check.
sgdisk -p ${DEV1}
# Output → 
#Number  Start (sector)    End (sector)  Size       Code  Name
#   1            2048            4095   1024.0 KiB  EF02  BBP
#   2            4096         1052671   512.0 MiB   EF00  ESP
#   3         1052672         9441279   4.0 GiB     8300  BOOT
#   4         9441280      1000215182   421.0 GiB   8300  SYSTEM

# Create new GPT.
sgdisk -o ${DEV1}

# [1] - ESP ... EFI System Partition.
# Flagged 'EFI System' (fdisk) or 'boot, esp' (parted). (200MiB+, FAT32).
sgdisk -n 0:0:+512MiB ${DEV1} --typecode=1:EF00 --change-name=1:ESP ${DEV1}

# [2] - Boot
sgdisk -n 0:0:+4096MiB ${DEV1} --typecode=2:8300 --change-name=2:BOOT ${DEV1}


# [3] - System.
sgdisk -n 0:0:0 ${DEV1} --typecode=3:8300 --change-name=3:SYSTEM ${DEV1}  

# Naming partitions.
sgdisk --change-name=1:ESP ${DEV1}
sgdisk --change-name=2:BOOT ${DEV1}
sgdisk --change-name=3:SYSTEM ${DEV1}  

# Check.
sgdisk -p ${DEV1}
# Output →
#Number  Start (sector)    End (sector)  Size       Code  Name
#  1            2048         1050623   512.0 MiB   EF00  ESP
#  2         1050624         9439231   4.0 GiB     8300  BOOT
#  3         9439232       488397134   421.0 GiB   8300  SYSTEM

Über den Typecode, wurde die ESP schon markiert. Manueller

In manchen Versionen von Linux fdisk werden Partitionstypen durch ihre Nummer gesetzt (1 für “EFI System” auf GPT-Platten oder 0xEF auf MBR-Platten) oder durch die Eingabe des ganzen Typecodes auf einer GPT-Festplatte.

## BIOS Flag (for partition no. 1)
sgdisk ${DEV1} -typecode=1:EF02

# UEFI FLag (for partition no. 2)
sgdisk ${DEV1} -typecode=2:EF00

# Or use parted to set partition 1:
parted ${DEV1PART1} set 1 esp on
parted ${DEV1PART1} set 1 boot on

Beispiele zur Nutzung von sgdisk:

  • sgdisk -n 0:0:+2048MiB /dev/ice}
    • Erstellt eine neue Partition, die 2048 MiB groß ist.
  • sgdisk -n 0:0:-16GiB /dev/ice
    • Erstellt eine neue Partition, die 16 GiB freien Platz dahinter übrig lässt.
  • sgdisk -n 0:0:0 /dev/ice
    • Erstellt eine neue Partition, die den gesamten freien Platz umfasst.
  • sgdisk --zap-all /dev/ice
    • Komplett löschen und neu machen.
  • sgdisk -n a:b:c /dev/ice
    • a … number, 0 … next available number, also 1 or n is possible
    • b … start, 0 … next available start block
    • c … end, 0 … end of the largest available block
        • … relative from current start
        • … releative from end
  • sgdisk -d 1 /dev/ice
    • Löschen von Partition 1.
  • Eine Alternative ist das interaktive Programm: cgdisk /dev/ice

Cryptsetup

ACHTUNG: Falls es später Probleme mit der Eingabe des Passwortes gibt, kann das Layout noch ein US-Tastatur-Layout ist. Man sollte die US-Position verwendeter Sonderzeichen kennen.

#modprobe dm-crypt

cryptsetup benchmark

# Encrypt the system partition
cryptsetup luksFormat -y --type luks2 --cipher=aes-xts-plain --key-size=512 --hash=sha512 --pbkdf=argon2id --use-random ${DEV1PART3}

# Open luks container.
cryptsetup luksOpen --allow-discards ${DEV1PART3} ${DEV1PART3CRYPTNAME}

# Check cryptsetup.
cryptsetup luksDump ${DEV1PART3}
  • Optionen für Verschlüsselung:
  • Optionen für Mode:
    • cbc (unsicher)
    • xts (empfohlen)
    • essiv (unsicher)
    • plain
    • plain64 (für >= 2TB-Platten)
  • --allow-discards für SSDs
  • Einen Schlüssel einem bestimmten Slot hinzufügen:
    • cryptsetup luksAddKey --key-slot=1 ${DEV1PART2}
  • Einen Schlüssel in einem bestimten Slot löschen:
    • cryptsetup luksKillSlot ${DEV1PART2} 1

Format

Goal:

DEVICE                TYPE                            SIZE    MOUNTPOINT
nvme0n1               gpt                             
├─nvme0n1p1             part, vfat (F32)              512M    /efi
├─nvme0n1p2             part, ext4                   4096M    /boot
└─nvme0n1p3             part, crypt                   421G
  ├─nvme0n1p3_crypt       btrfs @snapshot
  ├─nvme0n1p3_crypt       btrfs @sys-home                     /home
  ├─nvme0n1p3_crypt       btrfs @sys-debian-root              /
  ├─nvme0n1p3_crypt       btrfs @sys-debian-var               /var
  ├─nvme0n1p3_crypt       btrfs @sys-debian-var-log           /var/log
  └─nvme0n1p3_crypt       btrfs @sys-debian-swap              /swap
# [1] - Format EFI system partition (ESP).
mkfs.fat -F32 -n ESP ${DEV1PART1}

# [2] - Format boot. ext4 Block device is more likely for GRUB.
mkfs.ext4 -L boot ${DEV1PART2}

# [3] - Format system.
mkfs.btrfs -d single -m single -L system ${DEV1PART3CRYPT} 

# List available btrfs filesystems.
btrfs filesystem show

# Mount pure btrfs … (without defining a subvolume via … -o …,subvol= …)
mount -t btrfs -o noatime,discard=async,ssd,space_cache=v2,commit=120,compress=zstd,autodefrag,defaults ${DEV1PART3CRYPT} /mnt

#Check.
btrfs subvolume list /mnt

# Create subvolumes …

# Create general snapshot subvolume.
btrfs subvolume create /mnt/@snapshot

# Create general home subvolume.
btrfs subvolume create /mnt/@sys-home

THISDISTRO="debian"
btrfs subvolume create /mnt/@sys-${THISDISTRO}-root
btrfs subvolume create /mnt/@sys-${THISDISTRO}-var
btrfs subvolume create /mnt/@sys-${THISDISTRO}-var-log
btrfs subvolume create /mnt/@sys-${THISDISTRO}-swap

# Check.
# how the structure of a filesystem.
btrfs filesystem show
# Show space usage information for a mount point.
btrfs filesystem df /mnt
# List subvolumes and snapshots in the filesystem.
btrfs subvolume list /mnt

# Umount.
cd /
umount /mnt

Btrfs erlaubt es durch Subvolumes sehr einfach mehrere Betriebssysteme parallel nebeneinander zu installieren, z.B.:

#THISDISTRO="arch"
#btrfs subvolume create /mnt/@sys-${THISDISTRO}-root
#btrfs subvolume create /mnt/@sys-${THISDISTRO}-var
#btrfs subvolume create /mnt/@sys-${THISDISTRO}-var-log
#btrfs subvolume create /mnt/@sys-${THISDISTRO}-swap

Mount

THISDISTRO="debian"

# Mount system root.
mount -t btrfs -o noatime,discard,ssd,space_cache=v2,commit=120,compress=zstd,autodefrag,defaults,subvol=@sys-${THISDISTRO}-root ${DEV1PART3CRYPT} /mnt

# Check.
ls -lisa /mnt/

# Create folders for mount points.
mkdir -p /mnt/{efi,boot,boot-root,home,var,swap,.snapshot}

# Check.
ls -lisa /mnt/

# Mount system efi. (EFI only!)
mount -t vfat -o noatime,discard,defaults ${DEV1PART1} /mnt/efi

# Mount system boot.
mount -t ext4 -o discard,defaults ${DEV1PART2} /mnt/boot

# Mount system home.
mount -t btrfs -o noatime,discard,ssd,space_cache=v2,commit=120,compress=zstd,autodefrag,defaults,subvol=@sys-home ${DEV1PART3CRYPT} /mnt/home

# Mount system var.
mount -t btrfs -o noatime,discard,ssd,space_cache=v2,commit=120,compress=zstd,autodefrag,defaults,subvol=@sys-${THISDISTRO}-var ${DEV1PART3CRYPT} /mnt/var

# Mount system var/log.
mkdir -p /mnt/var/log
mount -t btrfs -o noatime,discard,ssd,space_cache=v2,commit=120,compress=zstd,autodefrag,defaults,subvol=@sys-${THISDISTRO}-var-log ${DEV1PART3CRYPT} /mnt/var/log

# Mount system swap.
mount -t btrfs -o noatime,discard,ssd,space_cache=v2,commit=120,autodefrag,defaults,subvol=@sys-${THISDISTRO}-swap ${DEV1PART3CRYPT} /mnt/swap

# Mount snapshot.
mount -t btrfs -o noatime,discard,ssd,space_cache=v2,commit=120,autodefrag,defaults,subvol=@snapshot ${DEV1PART3CRYPT} /mnt/.snapshot

# Check.
mount | grep /mnt

Wenn man mehrere Betriebssysteme nebeneinander installieren möchte, kann man die Kernel in Unterordner auf der Bootpartition legen. Das ist allerdings bei der Konfiguration des Boot-Loaders besonders zu beachten.

# Mount system boot, if you want to install multiple OS.
mount -t ext4 -o discard,defaults ${DEV1PART2} /mnt/boot-root
mkdir -p /mnt/boot-root/debian
mount --bind /mnt/boot-root/debian /mnt/boot

Swap

# Create swap file.
cd /mnt/swap

# Get btrfs properties
btrfs property get /mnt/swap

# truncate - shrink or extend the size of a file to the specified size
truncate -s 0 swapfile

# chattr … change attribute - Set file attributes to no copy-on-write updates.
# -R … recursively
# +C … Set No Copy-on-Write (CoW)
# -C … Unset/clear No Copy-on-Write (CoW)
chattr +C swapfile

# fallocate … create and allocate files of specific size.
# Allocate swap space as of RAM space.
fallocate -l 8G swapfile

# chmod …  change access permissions and special mode.
chmod 600 swapfile

# Make swapfile
mkswap -L swap swapfile

# Activate swap.
swapon swapfile

# Deactivate compression.
btrfs property set /mnt/swap compression none
btrfs property get /mnt/swap

Für btrfs benötigt man erst eine Zero-Length-Datei mit einigen Attributen. Erst danach kann man die Datei “wachsen” lassen. Alle größen annähernd der RAM-Größe sind eine gute Wahl.

Um eine Swap zu löschen, wird folgendes ausgeführt:

## Example: Delete swap partition.
#cd /
#umount /mnt/swap
#mkdir -p /mnt/tmp
#mount -t btrfs -o noatime,discard=async,ssd,space_cache=v2,commit=120,compress=zstd,autodefrag,defaults ${DEV1PART4CRYPT} /mnt/tmp
## Check.
#btrfs subvolume list /mnt/tmp
## Delete subvolume
#btrfs subvolume delete /mnt/tmp/@sys-debian-swap
## Create subvolume
#btrfs subvolume create /mnt/tmp/@sys-debian-swap
## Unmount
#umount /mnt/tmp

Zwischenstand

mount | grep ${DEV1}
mount | grep /mnt

lsblk

#NAME                MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
#loop0                 7:0    0   2.7G  1 loop  /usr/lib/live/mount/rootfs/filesystem.squashfs
#                                               /run/live/rootfs/filesystem.squashfs
# sda                   8:0    1   239G  0 disk  
# ├─sda1                8:1    1   239G  0 part  
# └─sda2                8:2    1    32M  0 part  
# nvme0n1             259:0    0 425.0G  0 disk  
# ├─nvme0n1p1         259:4    0   512M  0 part  /mnt/efi
# ├─nvme0n1p2         259:5    0     4G  0 part  /mnt/boot
# │                                              /mnt/boot-root
# └─nvme0n1p3         259:6    0 421.0G  0 part  
# └─nvme0n1p3_crypt 253:1    0 421.0G  0 crypt /mnt/.snapshot
#                                               /mnt/swap
#                                               /mnt/var/log
#                                               /mnt/var
#                                               /mnt/home
#                                               /mnt

Base system

apt update
apt install binutils debootstrap arch-install-scripts
debootstrap --arch=amd64 stable /mnt https://ftp.uni-hannover.de/debian/debian/

Alternative Spiegelserver:

  • https://ftp.uni-hannover.de/debian/debian/
  • http://debian.tu-bs.de/debian/
  • http://ftp.tu-chemnitz.de/debian/
  • https://debian.inf.tu-dresden.de/debian/
    • = http://ftp1.de.debian.org/debian/
  • https://ftp.halifax.rwth-aachen.de/debian/
    • = http://ftp2.de.debian.org/debian/

mtab

# Copy the mounted file systems table.
cp /etc/mtab /mnt/etc/mtab

fstab

# Generate filesystem table based on UUIDs and without pseudo filesystems.
genfstab -U -p /mnt >> /mnt/etc/fstab

# Check.
cat /mnt/etc/fstab
  • genfstab:
    • -U … Verwendung von UUIDs.
    • -p … Verhindert die Aufnahme von Pseudodateisystemen in die Liste.

crsypttab

# Get UUIDs.
# PART3UUID=$(blkid ${DEV1PART3} | cut -d "\"" -f2)
DEV1PART3UUID=$(blkid -o value -s UUID ${DEV1PART3})

# Check.
echo ${DEV1PART3UUID}

# Write crypttab.
echo "# <name>              <device>                                  <password>                <options>" > /mnt/etc/crypttab
echo "${DEV1PART3CRYPTNAME}       UUID=${DEV1PART3UUID} none                      luks,discard" >> /mnt/etc/crypttab

# Check crypttab.
cat /mnt/etc/crypttab

chroot

# Check EFI environment.
mount | grep efivars
efibootmgr -v
modprobe efivarfs

# for i in /dev /dev/pts /proc /sys /sys/firmware/efi/efivars /run; do sudo mount --bind $i /mnt${i}; done
CHRDIR=/mnt
mount --bind /dev ${CHRDIR}/dev
mount --bind /dev/pts ${CHRDIR}/dev/pts
mount --bind /proc  ${CHRDIR}/proc
mount --bind /sys  ${CHRDIR}/sys
mount --bind /sys/firmware/efi/efivars ${CHRDIR}/sys/firmware/efi/efivars
mount --bind /run  ${CHRDIR}/run

# CHROOT
LANG=C chroot ${CHRDIR} /bin/bash

# Check EFI.
mount | grep efivars
efibootmgr -v

# Color prompt
PS1='\[\033[00;31m\]\u\[\033[00m\]@\[\033[00;32m\]\h\[\033[00m\]:\[\033[01;34m\]\w \[\033[00m\]#\[\033[00m\] '

Don’t forget to reload variables from above!

Variables reload

DEV1="/dev/nvme0n1"
DEV1PART="nvme0n1p"

DEV1PART1NAME="${DEV1PART}1"
DEV1PART2NAME="${DEV1PART}2"
DEV1PART3NAME="${DEV1PART}3"

DEV1PART1="/dev/${DEV1PART1NAME}"
DEV1PART2="/dev/${DEV1PART2NAME}"
DEV1PART3="/dev/${DEV1PART3NAME}"

DEV1PART1CRYPTNAME="Not_in_use_as_crypt_ESP_EF00"
DEV1PART2CRYPTNAME="Not_in_use_as_crypt_BOOT"
DEV1PART3CRYPTNAME="${DEV1PART3NAME}_crypt"

DEV1PART1CRYPT="Not_in_use_as_crypt"
DEV1PART2CRYPT="Not_in_use_as_crypt"
DEV1PART3CRYPT="/dev/mapper/${DEV1PART3CRYPTNAME}"

Debian installation

cp /etc/apt/sources.list /etc/apt/sources.list.bkp
cat > /etc/apt/sources.list <<__EOF__
# https://wiki.debian.org/SourcesList

# Debian Stable - Official Debian repository for the current release.
deb https://debian.inf.tu-dresden.de/debian/ stable main contrib non-free non-free-firmware

# Debian Stable Security - Official Debian repository for frequent security updates.
deb http://deb.debian.org/debian-security/ stable-security main contrib non-free non-free-firmware

# Debian Stable Updates - Official Debian repository for changes that cannot wait for the next point release, packages are also added to StableProposedUpdates for inclusion in the next point release.
deb http://deb.debian.org/debian stable-updates main contrib non-free non-free-firmware

# Debian Stable Proposed Updates - However, the quality is usually very high (It should still be considered higher quality than Debian Testing, Backports... ) You are welcome to test those updates if you can recover minor problems (but don't test on production servers ;-). 
#deb http://deb.debian.org/debian/ stable-proposed-updates main contrib non-free non-free-firmware

# Dabian Backports - More recent versions of some packages, compatible with DebianStable. 
#deb http://deb.debian.org/debian stable-backports main contrib non-free non-free-firmware

# Alternate mirrors:
# https://ftp.uni-hannover.de/debian/debian/
# https://debian.inf.tu-dresden.de/debian/
#     = http://ftp1.de.debian.org/debian/
# https://ftp.halifax.rwth-aachen.de/debian/
#     = http://ftp2.de.debian.org/debian/
# http://debian.tu-bs.de/debian/
# http://ftp.tu-chemnitz.de/debian/
__EOF__
apt update

apt install arch-install-scripts aptitude linux-image-amd64 linux-headers-amd64 firmware-iwlwifi firmware-linux firmware-linux-nonfree sudo vim bash-completion command-not-found plocate systemd-timesyncd usbutils hwinfo locales v4l-utils gdisk keyutils gnupg openssh-server firewalld fail2ban ca-certificates screen make git timeshift network-manager wget curl btrfs-progs cryptsetup-bin cryptsetup-initramfs cryptsetup-suspend efibootmgr 

# systemd boot.
apt install systemd-boot 

# or
# GRUB boot manager.
apt install grub-efi-amd64 grub-efi-amd64-signed

Weitere Packete …

# For desktop systems:
# apt install gnome-core
# apt install task-cinnamon-desktop
# apt install task-gnome-desktop
# apt install task-kde-desktop
# apt install task-lxde-desktop
# apt install task-lxqt-desktop
# apt install task-mate-desktop
# apt install task-xfce-desktop
# Fo laptop systems:
# apt install task-laptop powertop gnome-power-manager linux-cpupower cpupower-gui
  • Eine Alternative, um gleich eine ganze Umgebung zu installieren ist: tasksel
    • → Z.B. cinnamon und ssh server auswählen.
  • Im Falle von Problemen könnte helfen bei fehlgeschlagenen Konfigurationen:
    • dpkg --configure -a
  • Wenn eine Paketinstallation fehlschlug:
    • apt install -f

firmware

git clone https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git /root/linux-firmware
mkdir -p /lib/firmware/rtl_nic/
cp -r /root/linux-firmware/rtl_nic/* /lib/firmware/rtl_nic/

Dies löst i.d.R. Fehlermeldungen im Zusammenhang mit fehlender Firmware.

  • Wenn das paket firmware-linux-nonfree nicht installiert wurde ggf.:
    • mkdir -p /lib/firmware/i915/
    • cp -r /root/linux-firmware/i915/* /lib/firmware/i915/
  • update-initramfs -u -k all
    • Sollte weiter unten keine Fehlermeldungen bzgl. fehlender Firmware ausgeben.

hostname

THISHOSTNAME=jorina
echo ${THISHOSTNAME} > /etc/hostname 
hostnamectl set-hostname ${THISHOSTNAME}

time

# Setting time zone.
dpkg-reconfigure tzdata

# Time.
timedatectl set-ntp true
ln -sf /usr/share/zoneinfo/Europe/Amsterdam /etc/localtime

# HW time is UTC
hwclock --systohc

locale

sed -i 's|#.*de_DE.UTF-8.*|de_DE.UTF-8 UTF-8|' /etc/locale.gen
sed -i 's|#.*en_DK.UTF-8.*|en_DK.UTF-8 UTF-8|' /etc/locale.gen
sed -i 's|#.*en_US.UTF-8.*|en_US.UTF-8 UTF-8|' /etc/locale.gen

locale-gen

cat > /etc/default/locale <<__EOF__
LANG=en_US.UTF-8
#LANGUAGE=en_US:en_GB:en
LC_COLLATE=C
LC_CTYPE=en_US.UTF-8
LC_DATE=en_DK.UTF-8
LC_TIME=en_DK.UTF-8
LC_ADDRESS=de_DE.UTF-8
LC_IDENTIFICATION=de_DE.UTF-8
LC_MESSAGES=en_US.UTF-8
LC_MEASUREMENT=de_DE.UTF-8
LC_MONETARY=de_DE.UTF-8
LC_NAME=de_DE.UTF-8
LC_NUMERIC=de_DE.UTF-8
LC_PAPER=de_DE.UTF-8
LC_TELEPHONE=de_DE.UTF-8
LC_ALL=
__EOF__

update-locale
  • Alternative: dpkg-reconfigure locales

Keymap

echo "KEYMAP=de-latin1" > /etc/vconsole.conf
echo "FONT=lat9w-16" >> /etc/vconsole.conf

Initramfs

#export LANG=de_DE.UTF-8 

# Re-generate.
update-initramfs -u -k all

cat /etc/crypttab
## <name>              <device>                                  <password>                <options>
#nvme0n1p3_crypt       UUID=abcabc12-cdef-1234-5678-a1b2c3d4e5f6 none                      luks,discard

# Check.
stat -L -c "%A  %n" /boot/initrd.img*
    # → -rw-------  /initrd.img

lsinitramfs /boot/initrd.img* | grep "^cryptroot/"
    # → cryptroot/crypttab
    # Different names are OK, 'cause this is initramfs internal naming.

lsinitramfs /boot/initrd.img* | grep "crypt"

Boot manager

# EFI
blkid -o value -s UUID ${DEV1PART1}
# Example UUID: DEV1-ESP1

# Boot partition
blkid -o value -s UUID ${DEV1PART2}
# Example UUID: deadbeef-dev1part2-pure-ext4-da69363b78ee

# System partition
blkid -o value -s UUID ${DEV1PART3}
# Example UUID: deadbeef-dev1part3-pure-aes1-da69363b78ee

# System crypt device
blkid -o value -s UUID ${DEV1PART3CRYPT}
# Example UUID: deadbeef-dev1part3-crypt-open-da69363b78ee

systemd boot

mkdir -p /boot/efi/loader/entries
bootctl install --path=/efi

grub

Wichtig ist die Aktivierung, so dass verschlüsselte Partitionen gemountet werden können. Beim Überprüfen des Grub-Menus ist es wichtig genau zu schauen, dass die einzelnen Einträge auch insmod cryptodisk und insmod luks enthalten!

# Enable cryptomount.
# To be needed, else grub-mkconfig won't write insmod cryptodisk and insmod luks into every boot entry.
echo "GRUB_ENABLE_CRYPTODISK=y" >> /etc/default/grub
#echo "GRUB_PRELOAD_MODULES=\"part_gpt part_msdos cryptodisk luks\"" >> /etc/default/grub

# Check entry
cat /etc/default/grub

update-grub
# Generating grub configuration file ...
# Found linux image: /boot/vmlinuz-6.1.0-13-amd64
# Found initrd image: /boot/initrd.img-6.1.0-13-amd64
# Warning: os-prober will not be executed to detect other bootable partitions.
# Systems on them will not be added to the GRUB boot configuration.
# Check GRUB_DISABLE_OS_PROBER documentation entry.
# done

# Populate GRUB
grub-install --target=x86_64-efi --recheck --efi-directory=/efi --bootloader-id=grub
# Installing for x86_64-efi platform.
# grub-install: warning: EFI variables cannot be set on this system. --> Exit chroot and mount efi vars.
# grub-install: warning: You will have to complete the GRUB setup manually.
# Installation finished. No error reported.

# Check boot menu entries.

cat /efi/EFI/grub/grub.cfg
# search.fs_uuid deadbeef-dev1part2-pure-ext4-da69363b78ee root 
# set prefix=($root)'/debian/grub'
# configfile $prefix/grub.cfg

cat /boot/grub/grub.cfg
grep 'cryptodisk\|luks' /boot/grub/grub.cfg
# insmod cryptodisk
# insmod luks2

Um die Grub-Einträge zu überprüfen …

# Verify included insmod cryptodisk and insmod luks into every menuentry! This the point of most failure during boot.

cat /boot/grub/grub.cfg
# ...
# insmod part_gpt
# insmod cryptodisk
# insmod luks2
# insmod gcry_rijndael
# insmod gcry_rijndael
# insmod gcry_sha256
# insmod btrfs
# cryptomount -u deadbeefdev1part3pureaes1da69363b78ee
# set root='cryptouuid/deadbeefdev1part3pureaes1da69363b78ee'
# ...
# when kernel is stored in directory /boot/debian/
# when kernel is stored in directory /boot, then cut '/debian/vmlinuz...' to '/vmlinuz...'
# menuentry 'Debian GNU/Linux' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-deadbeef-dev1part3-crypt-open-da69363b78ee' {
#     load_video
#     insmod gzio
#     if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
#     insmod part_gpt
#     insmod ext2
#     search --no-floppy --fs-uuid --set=root deadbeef-dev1part2-pure-ext4-da69363b78ee # set=root … =boot partition
#     echo    'Loading Linux 6.1.0-13-amd64 ...'
#     linux    /debian/vmlinuz-6.1.0-13-amd64 root=UUID=deadbeef-dev1part3-crypt-open-da69363b78ee ro rootflags=subvol=@sys-debian-root  quiet # root=UUID=system_crypt partition
#     echo    'Loading initial ramdisk ...'
#     initrd    /debian/initrd.img-6.1.0-13-amd64
# }
# ...
  • nano /etc/default/grub
  • grub-install ${DEV1}
  • grub-mkconfig -o /boot/grub/grub.cfg
  • update-grub
  • update-initramfs -u -k all

logins

# Change root password. 
# (root home folder is automatically OS depended. → /root)
passwd root

# Create a user.
THISUSER="frank"
groupadd ${THISUSER}
useradd --create-home --gid ${THISUSER} --groups users --shell /bin/bash ${THISUSER}
passwd ${THISUSER}

# Mutlimedia user
groupadd multimedia
useradd --create-home --home /home/multimedia --gid multimedia --shell /bin/bash "multimedia"
passwd multimedia

# List users.
cat /etc/passwd
getent passwd

# List usernames only.
cat /etc/passwd | awk -F: '{print $1}'
getent passwd ${THISUSER}

# List groups
cat /etc/group
cat /etc/group | grep ${THISUSER}

Falls ein Sudo-/Wheel-Nutzer benötigt wird …

# Create user.
useradd --create-home --home /home/${THISUSER}-wheel --gid ${THISUSER} --groups wheel --shell /bin/bash "${THISUSER}-wheel"
usermod --append --groups users,network,power ${THISUSER}-wheel

Dies erzeugt einen Wheel-User, welcher sich die gleiche Gruppe wie der zugehörige Nutzer teilt.

Wird eine System-Nutzer benötigt, welcher im Login-Screen nicht sichtbar ist, kann dieser wie folgt angelegt werden:

# Set as system account. It won't be displayed at login screen.
# Old method is to choose an user id below 1000
#usermod --uid 800 ${THISUSERNAME}-wheel
sed -i 's|^SystemAccount=false|SystemAccount=true|' /var/lib/AccountsService/users/${THISUSER}-wheel
mkdir -m 0755 /var/lib/AccountsService
mkdir -m 0700 /var/lib/AccountsService/users

cat > /var/lib/AccountsService/users/${THISUSER}-wheel <<__EOF__
[User]
SystemAccount=true

[InputSource0]
xkb=de
__EOF__

chmod 0600 /var/lib/AccountsService/users/${THISUSER}-wheel
# Check
ls -lisa /var/lib/AccountsService/users/

Nun noch das Passwort setzten und die Wheel-Gruppe aktivieren …

# Set users password.
passwd ${THISUSER}-wheel

# Activate wheels.
# Allow users in wheel group to use sudo.
sed -i 's/^# %wheel ALL=(ALL:ALL) ALL/%wheel ALL=(ALL:ALL) ALL/' /etc/sudoers
#sed -i 's/^# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/' /etc/sudoers
  • Wenn ein Nutzer in die Wheels-Gruppe aufgenommen wird, kann er hiermit auch sudo nutzen.

Überprüfen der Nutzer …

# Check.
cat /etc/sudoers
cat /etc/shadow
cat /etc/group
cat /etc/group | grep ${THISUSER}

bash -l
PS1='\[\033[00;31m\]\u\[\033[00m\]@\[\033[00;32m\]\h\[\033[00m\]:\[\033[01;34m\]\w \[\033[00m\]#\[\033[00m\]'

# Check.
su - ${THISUSER}-wheel
sudo cat /etc/sudoers

exit

Fertig

Ab diesen Moment sind wir fertig mit der installation. Wir können ins System booten und uns anmelden. Doch wo wir gerade mit einer bequemen Methode im System sind, können wir es auch ein wenig weiter machen und an dieser Stelle die Konfigurationen für Bash und SSH tätigen.

exit

# Exit chroot.
exit

# Unmount.
cd /
[ ! -z ${CHRDIR} ] && echo "chroot directory: ${CHRDIR}"
[ ! -z ${CHRDIR} ] && umount ${CHRDIR}/run
[ ! -z ${CHRDIR} ] && umount ${CHRDIR}/sys/firmware/efi/efivars
[ ! -z ${CHRDIR} ] && umount ${CHRDIR}/sys
[ ! -z ${CHRDIR} ] && umount ${CHRDIR}/proc
[ ! -z ${CHRDIR} ] && umount ${CHRDIR}/dev/pts
[ ! -z ${CHRDIR} ] && umount ${CHRDIR}/dev

# Turn swap off.
swapoff /mnt/swap/swapfile

# Umount
umount /mnt/swap
umount /mnt/var/log
umount /mnt/var
umount /mnt/home
umount /mnt/efi
umount /mnt/boot
#umount /mnt/boot-root
umount /mnt/.snapshot
umount /mnt

cryptsetup luksClose ${DEV1PART3CRYPTNAME}
sync
reboot

Cheatsheet

Grub Rescue

ls
cryptomount (hd3,gpt2)
cryptomount hd3,gpt2
set prefix=(crypto0)/grub
insmod normal
normal

Network

nmcli dev
nmcli r wifi on
nmcli r wifi off

dhclient

ip a
ip addr
ip link show

luks

cryptsetup luksDump /dev/nvme0n1p2
cryptsetup luksAddKey --key-slot=5 /dev/nvme0n1p2
cryptsetup luksKillSlot /dev/nvme0n1p2 5

Bash

# Color prompt
PS1='\[\033[00;31m\]\u\[\033[00m\]@\[\033[00;32m\]\h\[\033[00m\]:\[\033[01;34m\]\w \[\033[00m\]#\[\033[00m\] '

Quellen

  • https://cryptsetup-team.pages.debian.net/cryptsetup/encrypted-boot.html
  • https://wiki.debian.org/Btrfs
  • https://www.paritybit.ca/blog/debian-with-btrfs
  • https://www.dwarmstrong.org/fde-debian/
  • https://mutschler.eu/linux/install-guides/ubuntu-btrfs-20-04/
  • https://mutschler.eu/linux/install-guides/pop-os-btrfs-20-04/
  • https://unix.stackexchange.com/questions/753886/how-to-install-debian-12-with-full-disk-boot-too-luks2-encryption-grub2-lvm-u
  • https://wiki.archlinux.org/title/GRUB#LUKS2
  • https://blackpine.io/posts/2022.04.14-installing-debian-11-with-btrfs-subvolumes-on-luks/
  • https://pad.stratum0.org/p/debianinstall2023

  • https://austinmorlan.com/posts/arch_linux_install/
  • https://kofler.info/arch-linux-mit-lvm-und-verschluesselung-luks-installieren/

Secure Boot

  • https://blastrock.github.io/fde-tpm-sb.html
  • https://www.rodsbooks.com/efi-bootloaders/controlling-sb.html#creatingkeys
  • https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot