Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save adns44/1ed782670fa4682bc5f2da8bb415299b to your computer and use it in GitHub Desktop.
Save adns44/1ed782670fa4682bc5f2da8bb415299b to your computer and use it in GitHub Desktop.
Install luks encrypted, two-disks array, EXT4 Debian system with remote unlock without IPMI
#!/bin/bash
# READ BEFORE RUNNING!
# This script can install a luks encrypted, two-disks array EXT4 Debian system.
# Very beta stage, tested only on Kimsufi KS-LE and KS-LE-1. Two SSDs.
# On OVH, the new Rescue not working. Use the old, rescue pro!
# Use this script only on your own risk. By default every data lost on disks!
# init vars
# You need to init variables in the first stage and after deep into the chroot
primary_disk="/dev/sda"
secondary_disk="/dev/sdb"
disk_password='secret' #used to unlock the disk on remote SSH session
rootfs_name='rootfs' # Display and device name for unlocked rootfs. Not required to change, not sensitive
os_variant='bookworm' # debian version. Bookworm is the latest stable now
os_mirror='https://deb.debian.org/debian' # mirror
device_hostname='kimsufi' # give a hostname
device_timezone='Europe/Budapest' # TZ
# Retrieve network information from the control panel or rescue system
device_ipv4_address='' # IPv4 address of the machine
device_ipv4_gateway='' # IPv4 gw
device_ipv4_ciddr='24' # IPv4 ciddr
device_ipv4_mask='255.255.255.0' # IPv4 mask, can be calculated from ciddr and reverse
device_ipv6_address='' # IPv6 address of the machine
device_ipv6_gateway='' # IPv6 gw
device_ipv6_ciddr='128'
device_nameserver_address='1.1.1.1' # default DNS server
unlock_ssh_port='2222' # initramfs SSH port. Used only at unlocking stage
user_ssh_pubkey='' # Your OpenSSH-compatible public key. PW auth not allowed at unlock stage
user_name='user' # username
user_password='secret' # user pw
openssh_config_file='customssh.conf' # custom OpenSSH file used by script
openssh_config_port='22' # SSH port on the running system (after unlock)
openssh_config_plain_password_authentication='no' # allow plain PW auth on running sys?
echo "Install a Debian on two disks in RAID1 with luks encryption."
echo "adns44 2023 | github.com/adns44"
#wipe disks
wipefs -a ${primary_disk}
wipefs -a ${secondary_disk}
# Prepare the first disk
echo "unit: sectors
${primary_disk}1 : start= 4196352, Id=fd
${primary_disk}3 : start= 2048, size= 4194304, Id=fd, bootable" | sfdisk ${primary_disk}
echo "unit: sectors
${secondary_disk}1 : start= 4196352, Id=fd
${secondary_disk}3 : start= 2048, size= 4194304, Id=fd, bootable" | sfdisk ${secondary_disk}
# create the RAID array
echo "yes" | mdadm --create --name=initramfsarr --verbose /dev/md5 --level=1 --raid-devices=2 ${primary_disk}2 ${secondary_disk}2
echo "yes" | mdadm --create --name=rootarr --verbose /dev/md0 --level=1 --raid-devices=2 ${primary_disk}1 ${secondary_disk}1
#cryptsetup setup
echo "${disk_password}" | cryptsetup -y -v --type luks2 luksFormat /dev/md0
# unlock it
echo "${disk_password}" | cryptsetup luksOpen /dev/md0 ${rootfs_name}
#create the EXT4 partitions
mkfs.ext4 -F /dev/mapper/${rootfs_name}
mkfs.ext4 -F /dev/md5
# get the UUIDs
# This will need again - as the first variable init state - in the chroot
uuid_rootfs_decrypted=`blkid -o value /dev/mapper/${rootfs_name} | head -n 1`
uuid_rootfs=`blkid -o value /dev/md0 | head -n 1`
uuid_boot=`blkid -o value /dev/md5 | head -n 1`
#mount the rootfs
mount /dev/mapper/${rootfs_name} /mnt
# install base debian
# If the debootstrap, provided by default not support the desired distro, you need to install an up-to-date version
# Install from https://ftp.debian.org/debian/pool/main/d/debootstrap/
# E.G. wget https://ftp.debian.org/debian/pool/main/d/debootstrap/debootstrap_1.0.114+deb10u1_all.deb and dpkg install.
debootstrap --no-check-gpg --arch amd64 ${os_variant} /mnt ${os_mirror}
# mount system-required temporary files
mount --make-rslave --rbind /proc /mnt/proc
mount --make-rslave --rbind /sys /mnt/sys
mount --make-rslave --rbind /dev /mnt/dev
mount --make-rslave --rbind /run /mnt/run
# mount boot partition
mount /dev/md5 /mnt/boot
# chroot into
chroot /mnt /bin/bash
# This is the part where variables reinitialization required
#repos
cat > /etc/apt/sources.list <<- EOF
#HTTPS on Debian worldwide CDN
deb https://deb.debian.org/debian/ bookworm main non-free non-free-firmware contrib
deb-src https://deb.debian.org/debian/ bookworm main non-free non-free-firmware contrib
deb https://deb.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
deb-src https://deb.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
# bookworm-updates, to get updates before a point release is made;
# see https://www.debian.org/doc/manuals/debian-reference/ch02.en.html#_updates_and_backports
deb https://deb.debian.org/debian/ bookworm-updates main contrib non-free non-free-firmware
deb-src https://deb.debian.org/debian/ bookworm-updates main contrib non-free non-free-firmware
# bookworm-backports, previously on backports.debian.org
deb https://deb.debian.org/debian/ bookworm-backports main contrib non-free non-free-firmware
deb-src https://deb.debian.org/debian/ bookworm-backports main contrib non-free non-free-firmware
EOF
#install a few base package
apt-get update
apt-get install linux-image-amd64 firmware-linux cryptsetup mdadm grub2 sudo openssh-server dropbear-initramfs locales -y
#build the fstab file
echo "UUID=${uuid_rootfs_decrypted} / ext4 errors=remount-ro 0 1" >> /etc/fstab
echo "UUID=${uuid_boot} /boot ext4 errors=remount-ro 0 1" >> /etc/fstab
#write mdadm configuration
mdadm --detail --scan | tee -a /etc/mdadm.conf
#fill the crypttab (helps to unlock the system over SSH)
echo "${rootfs_name} UUID=${uuid_rootfs} none luks,discard" >> /etc/crypttab
#set the hostname
echo "${device_hostname}" > /etc/hostname
echo "${device_hostname}" > /etc/mailname
echo "127.0.1.1 ${device_hostname}" >> /etc/hosts
hostname ${device_hostname}
#set tz
echo "${device_timezone}" > /etc/timezone
# set up dropbear-initramfs
echo "DROPBEAR_OPTIONS=\"-I 180 -j -k -p ${unlock_ssh_port} -s\"" >> /etc/dropbear/initramfs/dropbear.conf
# set up initramfs network
echo 'DEVICE="eth0"' >> /etc/initramfs-tools/initramfs.conf
echo "IP=${device_ipv4_address}::${device_ipv4_gateway}:${device_ipv4_mask}:${device_hostname}" >> /etc/initramfs-tools/initramfs.conf
# GRUB network
echo "GRUB_CMDLINE_LINUX=\"net.ifnames=0 biosdevname=0 IP=${device_ipv4_address}::${device_ipv4_gateway}:${device_ipv4_mask}:${device_hostname}\"" >> /etc/default/grub
# provide a pubkey to SSH to unlock the device
echo "${user_ssh_pubkey}" >> /etc/dropbear/initramfs/authorized_keys
#install grub
grub-install --target=i386-pc --force ${primary_disk}
grub-install --target=i386-pc --force ${secondary_disk}
#update initramfs
update-initramfs -u
#update GRUB
update-grub
# set up DNS resolv
echo "nameserver ${device_nameserver_address}" > /etc/resolv.conf
# set up eth0 if
cat >> /etc/network/interfaces <<- EOF
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address ${device_ipv4_address}/${device_ipv4_ciddr}
gateway ${device_ipv4_gateway}
iface eth0 inet6 static
address ${device_ipv6_address}/${device_ipv6_ciddr}
gateway ${device_ipv6_gateway}
EOF
# set locale
echo "LANG=C.UTF-8" > /etc/default/locale
#enable ssh
systemctl enable --now ssh
#create first unprivileged user with sudo
useradd -m -s /bin/bash ${user_name}
adduser ${user_name} sudo
echo -e "${user_password}\n${user_password}" | passwd ${user_name}
# set up SSH acces with pubkey
mkdir -p /home/${user_name}/.ssh
echo "${user_ssh_pubkey}" > /home/${user_name}/.ssh/authorized_keys
chmod -R 755 /home/${user_name}/.ssh
chown -R ${user_name}:${user_name} /home/${user_name}/.ssh
#Set up SSH server
touch /etc/ssh/sshd_config.d/${openssh_config_file}
echo "Port ${openssh_config_port}" >> /etc/ssh/sshd_config.d/${openssh_config_file}
echo "PasswordAuthentication ${openssh_config_plain_password_authentication}" >> /etc/ssh/sshd_config.d/${openssh_config_file}
echo "Installation finished on ${device_hostname}!"
echo "The server is available on ${device_ipv4_address} and/or ${device_ipv6_address}"
echo "You can access the server VIA SSH"
echo "Firstly login with root on SSH port ${unlock_ssh_port} and issue crypt-root-unlock, provide the pw and hit enter."
echo "After this you can access the SSH on port ${openssh_config_port} with your user ${user_name}"
echo "Use your key or PW to login"
echo "Password auth allowed: ${openssh_config_plain_password_authentication}"
echo "Thank you for choose my script! - TheAdam | theadam.eu"
echo "adns44 2023 | github.com/adns44"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment