- 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
- ensure you have correct devices
fdisk -l /dev/sd? /dev/nvme?n?
- 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
- (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!
- (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.
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.
- 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,hash=sha512,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
- 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,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
# LABEL=swap0
UUID=filesyst-em00-0000-0000-eeeeeeeeeeee none swap sw 0 0
- 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
- download tools
apt update
apt install debootstrap
- setup apt info
release=bullseye
case "$(hostname -f)" in
*ovh.net) mirror=debian.mirrors.ovh.net ;;
*) mirror=ftp.debian.org ;;
esac
- install with debootstrap
debootstrap \
--components=main,contrib,non-free \
--include=curl \
$release /target https://$mirror/debian \
|| echo "Installation failed: exit=$?"
- 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/
- 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
- enter chroot
cp /etc/resolv.conf /target/etc/resolv.conf
LANG=C.UTF-8 chroot /target /bin/bash
- (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
- (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
- install more packages
# if you used RAID
apt install mdadm
# TODO
apt install
- Configure an user
adduser user
adduser user ssh
adduser user sudo
- Final configurations
# name your system
echo myhostname > /target/etc/hostname
# configure locales
dpkg-reconfigure locales
- Update initramfs and grub
update-initramfs -u -k all
update-grub
- Install grub
EFI:
for d in /boot/efi*; do
grub-install --efi-dorectory=$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
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...