mirror of
https://git.myvelabs.com/lab/archlinux.git
synced 2025-12-17 21:26:25 +00:00
First commit
This commit is contained in:
commit
36ad41a2fc
18 changed files with 10005 additions and 0 deletions
347
recover.sh
Executable file
347
recover.sh
Executable file
|
|
@ -0,0 +1,347 @@
|
|||
#!/usr/bin/env bash
|
||||
set -a -E
|
||||
|
||||
# Exit function
|
||||
trap '[ "${?}" -ne 77 ] || exit 77' ERR
|
||||
function die
|
||||
{
|
||||
echo -e '\n\e[1;31mError encountered, script aborted...\e[0m\n'
|
||||
exit 77
|
||||
}
|
||||
|
||||
# Internet connection check
|
||||
if ! nc -z -w 1 archlinux.org 443 >/dev/null 2>&1 || ! nc -z -w 1 google.com 443 >/dev/null 2>&1
|
||||
then
|
||||
die 'No internet connectivity detected, plug in an ethernet cable or run \e[32miwd-connect\e[33m if using wifi and try again'
|
||||
fi
|
||||
|
||||
clear
|
||||
|
||||
echo -e '\e[3m## rev '${revision}'\e[0m\n'
|
||||
echo -e '\t\e[1;4;34mArch Linux Recovery\e[0m\n\n'
|
||||
echo -e '\e[1mSelect a system configuration from the options below\e[0m\n'
|
||||
echo -e '\t1) Basic'
|
||||
echo -e '\t2) Full Disk LUKS Encryption with EFISTUB'
|
||||
echo -e '\t3) Full Disk LUKS Encryption with Secured GRUB'
|
||||
echo -e '\t4) Yubikey Full Disk Encryption with EFISTUB'
|
||||
echo -e '\t5) Yubikey Full Disk Encryption with Secured GRUB'
|
||||
|
||||
if ls -l /dev/disk/* | grep -q 'virtio\|QEMU'
|
||||
then
|
||||
echo
|
||||
until [[ ${arch} = [1-5] ]]
|
||||
do
|
||||
read -n 1 -p '> ' arch
|
||||
[[ ${arch} = [1-5] ]] || echo -e '\n\n\e[1;31mInvalid selection, type an option from 1 to 5\e[0m'
|
||||
done
|
||||
else
|
||||
echo -e '\t6) Full Disk Encryption with Detached LUKS Header and Secured GRUB'
|
||||
echo -e '\t7) Yubikey Encrypted Detached LUKS Header with Secured GRUB\n'
|
||||
until [[ ${arch} = [1-7] ]]
|
||||
do
|
||||
read -n 1 -p '> ' arch
|
||||
[[ ${arch} = [1-7] ]] || echo -e '\n\n\e[1;31mInvalid selection, type an option from 1 to 7\e[0m'
|
||||
done
|
||||
fi
|
||||
|
||||
# Prevent continuing unless yubikey is detected, only applies to yubikey setups
|
||||
if [[ ${arch} = [457] ]] && ! dmesg | grep -q -i YubiKey
|
||||
then
|
||||
echo -e '\n\n\e[1mYubikey not detected'
|
||||
echo -e 'Insert one to continue\e[5m...\e[0m'
|
||||
until dmesg | grep -q -i YubiKey
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
|
||||
# Installation drive
|
||||
echo -e '\n\n\e[1;36mIdentify the system drive from the list of available devices below\e[0m'
|
||||
lsblk -d -o name,model,size,mountpoint | grep -v 'archiso'
|
||||
echo -e '\e[3m## SSD and HDD device format begins with "sd" or "hd" (sda, sdb, sd[*])'
|
||||
echo -e '## NVME and PCI device format is "nvme[*]n1" (nvme0n1, nvme1n1, nvme[*]n1)\e[0m'
|
||||
while true
|
||||
do
|
||||
read -r -p 'Installation device: ' installation_disk
|
||||
lsblk -o name | grep -q -w ${installation_disk} && [ ${installation_disk} ] && break
|
||||
lsblk -d -o name,model,size,mountpoint | grep -v 'archiso'
|
||||
[ -z ${installation_disk} ] && echo -e '\e[1;31mField cannot be empty, try again\e[0m' ||
|
||||
echo -e '\e[1;31mInvalid selection or drive not available, try again\e[0m'
|
||||
done
|
||||
echo -e '\n\e[1mInstallation drive set as \e[32m/dev/'${installation_disk}'\e[0m'
|
||||
echo
|
||||
|
||||
# Detached boot drive
|
||||
if [[ ${arch} = [67] ]]
|
||||
then
|
||||
echo -e '\e[1;34mIdentify the removable boot drive from the list of available devices below\e[0m'
|
||||
lsblk -d -o name,model,size,mountpoint | grep -v "archiso\|${installation_disk}"
|
||||
echo -e '\e[3m## Removable drives usually begin with "sd" (sda, sdb, sd[*])\e[0m'
|
||||
while true
|
||||
do
|
||||
read -r -p 'Removable boot device: ' external_boot_disk
|
||||
lsblk -o name | grep -v ${installation_disk} | grep -q -w ${external_boot_disk} && [ ${external_boot_disk} ] && break
|
||||
lsblk -d -o name,model,size,mountpoint | grep -v "archiso\|${installation_disk}"
|
||||
if [ -z ${external_boot_disk} ]
|
||||
then
|
||||
echo -e '\e[1;31mField cannot be empty, try again\e[0m'
|
||||
elif [ ${external_boot_disk} = ${installation_disk} ]
|
||||
then
|
||||
echo -e '\e[1;31mBoot drive cannot be the same as the system drive, try again\e[0m'
|
||||
else
|
||||
echo -e '\e[1;31mInvalid selection or drive not available, try again\e[0m'
|
||||
fi
|
||||
done
|
||||
echo -e '\n\e[1mDetached boot drive set as \e[32m/dev/'${external_boot_disk}'\e[0m'
|
||||
echo
|
||||
fi
|
||||
|
||||
if [[ ${arch} = [457] ]]
|
||||
then
|
||||
until [[ ${decrypt_root} = [yYnN] ]]
|
||||
do
|
||||
read -n 1 -p $'\n\e[1mDoes the yubikey automatically decrypt root upon boot (1FA)? (y/n): \e[0m' decrypt_root
|
||||
[[ ${decrypt_root} = [yYnN] ]] || echo -e -n '\n\n\e[1;31mNot a valid answer, type "y" or "n"\e[0m'
|
||||
done
|
||||
echo
|
||||
fi
|
||||
|
||||
# Functions
|
||||
function decryptRootLuks
|
||||
{
|
||||
while true
|
||||
do
|
||||
unset lukspass
|
||||
|
||||
echo -e '\e[1;36mEnter the encryption passphrase for the system drive\e[0m'
|
||||
until [ ${lukspass} ]
|
||||
do
|
||||
read -s -r -p 'Encryption password: ' lukspass
|
||||
[ ${lukspass} ] || echo -e '\n\n\e[1;31mPassphrase field cannot be empty, try again\e[0m'
|
||||
done
|
||||
|
||||
echo -e '\n\n\e[1;36mAttempting to decrypt '${rootpart}'\e[0m'
|
||||
if printf '%s' "${lukspass}" | cryptsetup open -v ${rootpart} cryptroot ${luks_header}
|
||||
then
|
||||
unset lukspass
|
||||
echo -e '\e[1;92mDecryption successful\e[0m'
|
||||
break
|
||||
else
|
||||
echo -e '\e[1;31mPassphrase failed, try again\e[0m\n'
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function decryptRootYubikey
|
||||
{
|
||||
echo
|
||||
yes | pacman -Sy &>/dev/null
|
||||
|
||||
for package in yubikey-personalization yubikey-full-disk-encryption
|
||||
do
|
||||
if ! pacman -Q | grep -q -w ${package}
|
||||
then
|
||||
missing_yubikey_req+=(${package})
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${missing_yubikey_req} ]
|
||||
then
|
||||
yes | pacman -Sy ${missing_yubikey_req[@]}
|
||||
unset missing_yubikey_req
|
||||
echo
|
||||
fi
|
||||
|
||||
# # Custom challenge slot
|
||||
# sed -i '/YKFDE_CHALLENGE_SLOT/c\YKFDE_CHALLENGE_SLOT="1"' /etc/ykfde.conf
|
||||
|
||||
while true
|
||||
do
|
||||
unset lukspass
|
||||
|
||||
echo -e '\e[1;36mEnter the encryption passphrase for the system drive\e[0m'
|
||||
until [ ${lukspass} ]
|
||||
do
|
||||
read -s -r -p 'Encryption password: ' lukspass
|
||||
[ ${lukspass} ] || echo -e '\n\n\e[1;31mPassphrase field cannot be empty, try again\e[0m'
|
||||
done
|
||||
|
||||
if [[ ${decrypt_root} = [yY] ]]
|
||||
then
|
||||
sed -i '/YKFDE_CHALLENGE=/c\YKFDE_CHALLENGE="'"$(printf '%q' ${lukspass})"'"' /etc/ykfde.conf
|
||||
fi
|
||||
|
||||
echo -e '\n\n\e[1;36mAttempting to decrypt '${rootpart}' with yubikey HMAC encryption\e[0m'
|
||||
if printf '%s\n' "${lukspass}" | ykfde-open -d ${rootpart} -n cryptroot -- ${luks_header}
|
||||
then
|
||||
unset lukspass
|
||||
echo -e '\e[1;92mDecryption successful\e[0m'
|
||||
break
|
||||
else
|
||||
echo -e '\e[1;31mPassphrase failed, try again\e[0m\n'
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function decryptBootLuks
|
||||
{
|
||||
while true
|
||||
do
|
||||
unset grubpass
|
||||
|
||||
echo -e '\e[1;36mEnter the encryption passphrase for the bootloader\e[0m'
|
||||
until [ ${grubpass} ]
|
||||
do
|
||||
read -s -r -p 'Bootloader password: ' grubpass
|
||||
[ ${grubpass} ] || echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m'
|
||||
done
|
||||
|
||||
echo -e '\n\n\e[1;36mAttempting to decrypt bootloader...\e[0m'
|
||||
if printf '%s' "${grubpass}" | cryptsetup open ${bootpart} cryptboot
|
||||
then
|
||||
unset grubpass
|
||||
echo -e '\e[1;92mDecryption successful\e[0m'
|
||||
break
|
||||
else
|
||||
echo -e '\e[1;31mPassphrase failed, try again\e[0m\n'
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function configureVolumes
|
||||
{
|
||||
echo -e '\n\e[1;36mMounting volumes\e[0m'
|
||||
|
||||
case $(blkid -s TYPE -o value ${rootvol}) in
|
||||
zfs_member)
|
||||
if ! zpool list | grep -q zroot
|
||||
then
|
||||
zpool import -R /mnt zroot -N -d ${rootvol}
|
||||
fi
|
||||
zfs mount zroot/ROOT
|
||||
zfs mount -a
|
||||
;;
|
||||
btrfs)
|
||||
mount ${rootvol} /mnt
|
||||
;;
|
||||
ext4)
|
||||
mount ${rootvol} /mnt
|
||||
mount ${bootvol} /mnt/boot
|
||||
if [[ ${arch} = [3567] ]]
|
||||
then
|
||||
mount ${efivol} /mnt/boot/efi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Grab disk-id of ${drive}
|
||||
installation_disk_id=$(ls -l /dev/disk/by-id/* | grep "${installation_disk}$" | grep 'wwn\|nvme-uuid\|nvme-nvme\|nvme-eui\|QEMU\|virtio\|VBOX' | awk '{print $9}' | head -1)
|
||||
external_boot_disk_id=$(ls -l /dev/disk/by-id/* | grep "${external_boot_disk}$" | grep 'wwn\|nvme-uuid\|nvme-nvme\|nvme-eui\|QEMU\|virtio\|VBOX\|usb' | awk '{print $9}' | head -1)
|
||||
|
||||
# System configurations
|
||||
case ${arch} in
|
||||
1) # Basic
|
||||
export {efivol,bootvol}=${installation_disk_id}-part1
|
||||
export {rootpart,rootvol}=${installation_disk_id}-part2
|
||||
configureVolumes
|
||||
;;
|
||||
|
||||
2|4) # FDE with EFISTUB
|
||||
export {efivol,bootvol}=${installation_disk_id}-part1
|
||||
rootpart=${installation_disk_id}-part2
|
||||
rootvol=/dev/mapper/cryptroot
|
||||
|
||||
case ${arch} in
|
||||
2)
|
||||
if [[ $(blkid -s TYPE -o value ${rootpart}) = "zfs_member" ]]
|
||||
then
|
||||
zpool import -R /mnt zroot -N -d ${rootpart}
|
||||
printf '%s' "${lukspass}" | zfs load-key zroot
|
||||
else
|
||||
decryptRootLuks
|
||||
fi
|
||||
;;
|
||||
4) decryptRootYubikey;;
|
||||
esac
|
||||
configureVolumes
|
||||
;;
|
||||
|
||||
3|5) # FDE with Secured GRUB
|
||||
efivol=${installation_disk_id}-part1
|
||||
bootpart=${installation_disk_id}-part2
|
||||
rootpart=${installation_disk_id}-part3
|
||||
rootvol=/dev/mapper/cryptroot
|
||||
bootvol=/dev/mapper/cryptboot
|
||||
|
||||
case ${arch} in
|
||||
3) decryptRootLuks;;
|
||||
5) decryptRootYubikey;;
|
||||
esac
|
||||
|
||||
decryptBootLuks
|
||||
configureVolumes
|
||||
;;
|
||||
|
||||
6|7) # FDE with detached luks header
|
||||
efivol=${external_boot_disk_id}-part1
|
||||
bootpart=${external_boot_disk_id}-part2
|
||||
rootpart=${installation_disk_id}
|
||||
rootvol=/dev/mapper/cryptroot
|
||||
bootvol=/dev/mapper/cryptboot
|
||||
luks_header='--header /mnt/header.img'
|
||||
|
||||
decryptBootLuks
|
||||
mount /dev/mapper/cryptboot /mnt
|
||||
case ${arch} in
|
||||
6) decryptRootLuks;;
|
||||
7) decryptRootYubikey;;
|
||||
esac
|
||||
umount /mnt
|
||||
configureVolumes
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
echo -e '\e[1;92mSystem successfully mounted...\e[0m\n'
|
||||
|
||||
if [[ $(blkid -s TYPE -o value ${rootvol}) = "btrfs" ]]
|
||||
then
|
||||
install /dev/stdin /usr/local/bin/btrfs-mount <<- BTRFSSU
|
||||
#!/usr/bin/env bash
|
||||
btrfsopts=$(awk '$2=="/"' /mnt/etc/fstab | awk '{print $4}' | sed 's/,subvol=.*//')
|
||||
umount -R /mnt
|
||||
echo
|
||||
|
||||
# Mount @root subvolume
|
||||
mount -o ${btrfsopts},subvol=@ ${rootvol} /mnt
|
||||
|
||||
# Mount all subvolumes
|
||||
arch-chroot /mnt mount --all
|
||||
lsblk
|
||||
echo -e '\n\t\e[1;92mBtrfs subvolumes successful mounted!\e[0m\n'
|
||||
BTRFSSU
|
||||
|
||||
echo -e '\e[1mRun \e[92mbtrfs-mount\e[0m\e[1m to mount all the btrfs subvolumes\e[0m\n'
|
||||
fi
|
||||
|
||||
if [[ ${arch} = [3567] ]]
|
||||
then
|
||||
install /dev/stdin /usr/local/bin/re-grub <<REGRUB
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
if findmnt '/mnt/boot/efi' | grep -q "${efivol}" && findmnt '/mnt/boot' | grep -q "${bootvol}"
|
||||
then
|
||||
arch-chroot /mnt /bin/bash <<'GRUB'
|
||||
grub-install --target=x86_64-efi --bootloader-id=GRUB --efi-directory=/boot/efi --recheck
|
||||
grub-mkconfig -o /boot/grub/grub.cfg
|
||||
echo -e '\n\t\e[1;92mGrub successfuly re-installed!\e[0m\n'
|
||||
GRUB
|
||||
else
|
||||
echo -e '\n\t\e[1;31mEFI partition not mounted, try again\e[0m\n'
|
||||
fi
|
||||
REGRUB
|
||||
|
||||
echo -e '\e[1mRun \e[92mre-grub\e[0m\e[1m to regenerate grub\e[0m\n'
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue