Created
June 26, 2023 06:41
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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