Skip to content

Instantly share code, notes, and snippets.

@raphendyr
Last active February 26, 2023 03:16
Show Gist options
  • Save raphendyr/0e96f9b4f1d675be30715e9eb6bbb6b1 to your computer and use it in GitHub Desktop.
Save raphendyr/0e96f9b4f1d675be30715e9eb6bbb6b1 to your computer and use it in GitHub Desktop.
Instructions on installing Debian manually with full control. Desktop, laptop or VM.

Installing Debian

prepare storage

  1. prepare

create a memory storage for secure files

mkdir -p /prepare
mount -t tmpfs none /prepare

install packages

apt update
apt install cryptsetup
apt install mdadm # if you are going to use raid
  1. ensure you have correct devices
fdisk -l /dev/sd? /dev/nvme?n?
  1. partition disks (use GPT)

For EFI systems:

You may use purpose as the partition name

cgdisk /dev/correct-disk
# purpose size  GUID name       gdisk GUID
# efi     512M  EFI System      EF00  C12A7328-F81F-11D2-BA4B-00A0C93EC93B
# boot    512M  Linux ext. boot EA00  BC13C2FF-59E6-4262-A352-B275FD6F7172
# root    >30G  Linux LUKS      8309  CA7D7CCB-63ED-4C53-861C-1742536059CC
# home      nG  Linux LUKS      8309  CA7D7CCB-63ED-4C53-861C-1742536059CC
# swap   8-64G  Linux dm-crypt  8308  7FFEC5C9-2D00-49B7-8941-3EA10A5586B7

The root partition is for OS and the home is for user files, but you may use a single partition instead (i.e., root).

If you setup RAID, then use gdisk code fd00 (GUID A19D880F-05FC-4D3B-A006-743F0F84911E) for root and home partitions.

If you need hibernation, then this setup doesn't work for you (you need LVM). For hibernation the swap size would be about as much as you have RAM, which is a good default always.

For non-EFI systems (e.g., cloud VMs):

cgdisk /dev/correct-disk
# purpose size  GUID name       gdisk GUID
# grub    2M                    EF02  21686148-6449-6E6F-744E-656564454649
# boot    256M  Linux ext. boot EA00  BC13C2FF-59E6-4262-A352-B275FD6F7172
# luks    >10G  Linux LUKS      8309  CA7D7CCB-63ED-4C53-861C-1742536059CC
# swap    1-4G  Linux dm-crypt  8308  7FFEC5C9-2D00-49B7-8941-3EA10A5586B7

You can start with following command, which will set the first 2 partitions nicely.

sfdisk /dev/correct-disk <<EOF
label: gpt
device: /d
unit: sectors
first-lba: 34

/d1 : start= 6144, size= 487424, type=BC13C2FF-59E6-4262-A352-B275FD6F7172, name="boot"
/d9 : start= 2048, size=   4096, type=21686148-6449-6E6F-744E-656564454649, name="grub"
EOF
  1. (optional) copy partition table to second RAID disk
sgdisk --replicate=/dev/second-disk /dev/first-disk
sgdisk -G /dev/second-disk

Notice the order of arguments!

  1. (optional) create RAID
mdadm -v -C /dev/md/boot -e 1.0 -l 1 -n 2 /dev/first-device2 /dev/second-device2
mdadm -v -C /dev/md/root -e 1.2 -l 1 -n 2 /dev/first-device3 /dev/second-device3
# only if this is home and not swap
mdadm -v -C /dev/md/home -e 1.2 -l 1 -n 2 /dev/first-device4 /dev/second-device4

Note that we use version 1.0 for efi and boot, so they can be read without using RAID, but we mount them with raid, so both disk have the same data when updated.

If you anticipate to add second disk later, you may create a single disk arrow now. To do that, replace -n 2 with --force -n 1. Converting plain disk to RAID later is quite hard. Later, you can add new disk with mdadm -a /dev/md/name /dev/second-deviceN and mdadm --frow -n 2 /dev/md/name.

Verify result with

cat /proc/mdstat

Prepare config

mkdir -p /prepare/mdadm
mdadm --detail --scan | tee /prepare/mdadm/mdadm.conf

Edit /prepare/mdadm.conf and replace installer hostname with the target hostname in name field.

  1. setup crypto

Partitions efi and boot won't be encrypted. Run the following command for data partitions root and home only. Use RAID devices /dev/md1[34], if you created those.

Create a nice password with pwqgen or come up with one. I recommend to use multiple words and less special characters. Consider that you should be able to write the password when the keyboard layout is not correct (i.e., just letters, numbers, comma, dot and space).

cryptsetup --type luks2 --label "luks:root" luksFormat <root partition>
cryptsetup --type luks2 --label "luks:home" luksFormat <home partition>

Create keyfiles

for n in home swap; do
  dd bs=1024 count=8 if=/dev/random iflag=fullblock of=/prepare/crypttab_$n.key
  chmod 0400 /prepare/crypttab_$n.key
  ln -s /prepare/crypttab_$n.key /etc/crypttab_$n.key
done

Add keyfiles to the cryptdisk, if you have home partition

cryptsetup luksAddKey <home partition> /prepare/crypttab_home.key

Add cryptdisks to crypttab

lsblk -o label,uuid,fstype | awk '/crypto_LUKS$/ { print $1, "UUID=" $2 }' | tee /prepare/crypttab
# repeat for every disk with swap
blkid /dev/correct-diskN | tee -a /prepare/crypttab

Edit the /prepare/crypttab file to look like:

root UUID=cryptdev-0000-0000-0000-aaaaaaaaaaaa none luks,discard
home UUID=cryptdev-0000-0000-0000-bbbbbbbbbbbb /etc/crypttab_home.key luks,discard
# repeat for every disk with swap
swap0 PARTUUID=blockdev-0000-0000-0000-eeeeeeeeeeee /etc/crypttab_swap.key plain,cipher=aes-xts-plain64,size=512,discard,swap

Open created devices

TABFILE=/prepare/crypttab cryptdisks_start root # requires password
TABFILE=/prepare/crypttab cryptdisks_start home # unlocks with key
# repeat for every swap
TABFILE=/prepare/crypttab cryptdisks_start swap0 # unlocks with key
  1. Create filesystems and fstab

Create swaps

# repeat for every swap
mkswap -L swap0 /dev/mapper/swap0

Create actual filesystems

mkfs.ext4 -L boot </dev/correct-disk2 or /dev/md/boot>
mkfs.ext4 -L root /dev/mapper/root
mkfs.ext4 -L home -m 0 /dev/mapper/home
# repeat for every disk in root array
mkfs.vfat -n EFI0 /dev/correct-disk1

Add all mounted filesystems to fstab

lsblk -o name,path,uuid,fstype,label | tee /prepare/fstab

Edit the /prepare/fstab file to look like:

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>

# LABEL=root
UUID=filesyst-em00-0000-0000-aaaaaaaaaaaa / ext4 defaults,user_xattr,lazytime,commit=30,errors=remount-ro 0 1
# LABEL=boot
UUID=filesyst-em00-0000-0000-bbbbbbbbbbbb /boot ext4 defaults,lazytime,nodev,nosuid,noexec,commit=60 0 2
# LABEL=home
UUID=filesyst-em00-0000-0000-dddddddddddd /home ext4 defaults,user_xattr,lazytime,nodev,nosuid,commit=30 0 2

# repeat for every efi device
# LABEL=EFI0
UUID=DEAD-BEEF /boot/efi0 vfat defaults,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed 0 2

# repeat for every swap device (boot/swapon generates a new uuid every time)
# LABEL=swap0
/dev/mapper/swap0 none swap sw 0 0
  1. Prepare filesystems for chroot

Copy it for chroot mounting

cp /prepare/fstab /target.fstab

Edit /target.fstab to look like, i.e., prefix paths, drop swaps and add system mounts.

UUID=filesyst-em00-0000-0000-aaaaaaaaaaaa /target ext4 defaults,user_xattr,lazytime,commit=30,errors=remount-ro 0 1
UUID=filesyst-em00-0000-0000-bbbbbbbbbbbb /target/boot ext4 defaults,lazytime,nodev,nosuid,noexec,commit=60 0 2
UUID=filesyst-em00-0000-0000-dddddddddddd /target/home ext4 defaults,user_xattr,lazytime,nodev,nosuid,commit=30 0 2

# repeat for every efi device
UUID=DEAD-BEEF /target/boot/efi0 vfat defaults,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed 0 2

run /target/run tmpfs defaults 0 0
sys /target/sys sysfs defaults 0 0
udev /target/dev devtmpfs defaults 0 0
dpts /target/dev/pts devpts defaults 0 0
proc /target/proc proc defaults 0 0
efivars /target/sys/firmware/efi/efivars efivarfs defaults

Mount root filesystem

mkdir -p /target
mount -T /target.fstab /target

Install base system

  1. download tools
apt update
apt install debootstrap
  1. setup apt info
release=bullseye
case "$(hostname -f)" in
    *ovh.net) mirror=debian.mirrors.ovh.net ;;
    *) mirror=ftp.debian.org ;;
esac
  1. install with debootstrap
debootstrap \
  --components=main,contrib,non-free \
  --include=curl \
  $release /target https://$mirror/debian \
  || echo "Installation failed: exit=$?"
  1. setup a minimal level of the base system
cat > /target/etc/apt/sources.list <<EOF
deb http://$mirror/debian $release main contrib non-free
deb http://$mirror/debian $release-updates main contrib non-free
deb http://$mirror/debian $release-backports main contrib non-free
deb http://security.debian.org/ $release-security main contrib non-free
EOF

cp -a /prepare/* /target/etc/
  1. mount rest of the filesystem
awk '/#/ {next}; $2 ~ /\/target\// {print length($2), $2}' /target.fstab | sort -n | while read l p; do
  mkdir -p $p && mount -T /target.fstab $p
done

NOTE: above is required only for the first time. If you need to remount disks, following is enough. However remember that /target.fstab doesn't persist over reboots on live installers and rescue systems.

mount -T /target.fstab -a
  1. enter chroot
cp /etc/resolv.conf /target/etc/resolv.conf
LANG=C.UTF-8 chroot /target /bin/bash
  1. (optional) install deb.n-1.fi private repo and install base system packages
# in chroot
curl -sSLo /run/nm1.deb https://deb.n-1.fi/archive-keyring.deb
dpkg -E -i /run/nm1.deb
rm /run/nm1.deb

apt update
# basic desktop:
apt install blend-n-1.fi-desktop blend-n-1.fi-efi-amd64
# basic VPS:
apt install blend-n-1.fi-shell blend-n-1.fi-vps-amd64
  1. (alternative) install required packages manually

Check content of above packages from the web site to get up-to-date idea what to install.

# in chroot
apt update
# blend-n-1.fi-efi-amd64
apt install console-setup grub-efi grub-theme-breeze linux-image-amd64
# blend-n-1.fi-basesystem
apt install apt-listchanges apt-utils aptitude base-passwd bsdutils bzip2 diffutils e2fsprogs findutils gawk grep gzip hostname less locales lz4 ncurses-base ncurses-bin p7zip pv reportbug sed systemd systemd-cron systemd-sysv unar util-linux xmlstarlet cryptsetup
# consider these
apt install burp ipset lm-sensors openssh-client passwdqc rsync unattended-upgrades vlan
  1. install more packages
# if you used RAID
apt install mdadm
# TODO
apt install
  1. Configure an user
adduser user
adduser user ssh
adduser user sudo
  1. Final configurations
# name your system
echo myhostname > /target/etc/hostname
# configure locales
dpkg-reconfigure locales
  1. Update initramfs and grub
update-initramfs -u -k all
update-grub
  1. Install grub

EFI:

for d in /boot/efi*; do
  grub-install --efi-directory=$d --bootloader-id=debian${d#/boot/efi}
done

Verify that boot entry was added correctly

efibootmgr

NOTE: if above fails, then add boot entry manually

 efibootmgr -c -d /dev/disk-with-boot -L Debian -l \\EFI\\debian\\grubx64.efi

Non-EFI:

grub-install /dev/correct-device

Clean and reboot

Exit the chroot

exit

Umount target

umount -R /target

Stop cryptdisks

cryptdisks_stop root
cryptdisks_stop home
# repeat for every swap
cryptdisks_stop swap0

Reboot...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment