mirror of
https://github.com/ovh/the-bastion.git
synced 2024-11-14 12:17:32 +08:00
e865964dd2
As seen in #181
213 lines
6.1 KiB
Bash
Executable file
213 lines
6.1 KiB
Bash
Executable file
#! /usr/bin/env bash
|
|
# vim: set filetype=sh ts=4 sw=4 sts=4 et:
|
|
set -e
|
|
umask 077
|
|
|
|
basedir=$(readlink -f "$(dirname "$0")"/../..)
|
|
# shellcheck source=lib/shell/functions.inc
|
|
. "$basedir"/lib/shell/functions.inc
|
|
|
|
action_doing "Checking whether the proper tools are installed"
|
|
if ! command -v rsync >/dev/null || ! command -v cryptsetup >/dev/null; then
|
|
action_error "Missing rsync or cryptsetup, aborting"
|
|
exit 1
|
|
else
|
|
action_done
|
|
fi
|
|
|
|
action_doing "Checking whether the install script has run"
|
|
if ! [ -f "/etc/bastion/luks-config.sh" ]; then
|
|
action_error "The '/etc/bastion/luks-config.sh' file doesn't exist, did you run the '$basedir/bin/admin/install' script before?"
|
|
exit 1
|
|
else
|
|
action_done
|
|
fi
|
|
|
|
action_doing "Checking whether /home is a separate partition"
|
|
home_block_device=$(awk '/ \/home / {print $1}' /proc/mounts)
|
|
if [ -n "$home_block_device" ] && [ -e "$home_block_device" ]; then
|
|
action_done "found $home_block_device"
|
|
else
|
|
action_error "No, aborting"
|
|
exit 1
|
|
fi
|
|
|
|
action_doing "Checking whether /home is in /etc/fstab"
|
|
if grep -qE '[[:space:]]/home[[:space:]]' /etc/fstab; then
|
|
action_done "$(grep '[[:space:]]/home[[:space:]]' /etc/fstab)"
|
|
else
|
|
action_error "No, aborting"
|
|
exit 1
|
|
fi
|
|
|
|
action_doing "Checking whether we can umount /home"
|
|
if umount /home; then
|
|
action_done
|
|
else
|
|
action_error "No, aborting"
|
|
exit 1
|
|
fi
|
|
|
|
action_doing "Checking whether we can remount /home"
|
|
if mount /home; then
|
|
action_done
|
|
else
|
|
action_error "No, aborting"
|
|
exit 1
|
|
fi
|
|
|
|
action_doing "Checking used space in /home"
|
|
home_used_mb=$(df -m /home | awk '{ print $3 }' | tail -n1)
|
|
if [ -n "$home_used_mb" ]; then
|
|
action_done "$home_used_mb MiB"
|
|
else
|
|
action_error "Couldn't get the /home used space"
|
|
exit 1
|
|
fi
|
|
|
|
action_doing "Checking available space in /"
|
|
slash_available_mb=$(df -m / | awk '{ print $4 }' | tail -n1)
|
|
if [ -n "$slash_available_mb" ]; then
|
|
action_done "$slash_available_mb MiB"
|
|
else
|
|
action_error "Couldn't get the / available space"
|
|
exit 1
|
|
fi
|
|
|
|
action_doing "Checking whether there is enough available space in / to hold /home contents temporarily"
|
|
if [ "$slash_available_mb" -gt "$home_used_mb" ]; then
|
|
action_done
|
|
else
|
|
action_error "Not enough free space in /"
|
|
exit 1
|
|
fi
|
|
|
|
action_doing "Creating temporary /tmphome"
|
|
# silently try to delete it just in case it exists but is empty
|
|
if [ -d /tmphome ]; then
|
|
rmdir /tmphome 2>/dev/null || true
|
|
fi
|
|
if [ -e /tmphome ]; then
|
|
action_error "/tmphome already exists! Aborting"
|
|
exit 1
|
|
else
|
|
mkdir /tmphome
|
|
if [ ! -d /tmphome ]; then
|
|
action_error "Couldn't create /tmphome!"
|
|
exit 1
|
|
else
|
|
action_done
|
|
fi
|
|
fi
|
|
|
|
action_doing "Rsyncing /home to /tmphome"
|
|
if rsync -vaPHAX --exclude='lost+found' /home/ /tmphome/; then
|
|
action_done
|
|
else
|
|
action_error "Rsync failed, aborting!"
|
|
rm -Rf /tmphome
|
|
exit 1
|
|
fi
|
|
|
|
action_doing "Rsync done, here are some details:"
|
|
action_detail "ls /home : $(cd /home ; find . | tr '\n' ' ')"
|
|
action_detail "ls /tmphome: $(cd /tmphome ; find . | tr '\n' ' ')"
|
|
action_detail "du -shc /home : $(du -shc /home | grep total)"
|
|
action_detail "du -shc /tmphome: $(du -shc /tmphome | grep total)"
|
|
action_detail ""
|
|
action_detail "Does this look reasonable? [CTRL+C if not]"
|
|
|
|
# shellcheck disable=SC2034
|
|
read -r _dummy
|
|
|
|
action_doing "Umounting /home"
|
|
if umount /home; then
|
|
action_done
|
|
else
|
|
action_error "Couldn't umount /home, aborting"
|
|
rm -Rf /tmphome
|
|
exit 1
|
|
fi
|
|
|
|
action_doing "Erasing /home block device and encrypting it (last chance to cancel!)"
|
|
action_detail "You should generate a strong password on your desk, with e.g. \`pwgen -s 10\`"
|
|
if cryptsetup luksFormat "$home_block_device"; then
|
|
action_done
|
|
else
|
|
action_error "Cryptsetup failed, aborting"
|
|
mount /home && rm -Rf /tmphome
|
|
exit 1
|
|
fi
|
|
|
|
action_doing "Opening newly encrypted block device"
|
|
if cryptsetup luksOpen "$home_block_device" home; then
|
|
action_done
|
|
else
|
|
action_error "Opening failed, aborting! Your /home partition is no longer valid, fix it manually! ($home_block_device)"
|
|
exit 1
|
|
fi
|
|
|
|
action_doing "Creating a new filesystem on top of the encrypted block device"
|
|
if mkfs.ext4 -T news -L home -M /home /dev/disk/by-id/dm-name-home; then
|
|
action_done
|
|
else
|
|
action_error "Filesystem creation failed, aborting! Your /home partition is no longer valid, fix it manually! ($home_block_device)"
|
|
exit 1
|
|
fi
|
|
|
|
action_doing "Setting up /etc/bastion/luks-config.sh with encrypted block device"
|
|
if sed -i -re "s;^DEV_ENCRYPTED=.*;DEV_ENCRYPTED=$home_block_device;" /etc/bastion/luks-config.sh; then
|
|
action_done
|
|
else
|
|
action_error "Couldn't modify /etc/bastion/luks-config.sh, please do it manually, continuing"
|
|
fi
|
|
|
|
action_doing "Setting up /etc/fstab with encrypted block device"
|
|
newfstab=$(mktemp)
|
|
grep -Ev "[[:space:]]/home[[:space:]]" /etc/fstab > "$newfstab"
|
|
echo "# added by $(basename "$0") on $(date)" >> "$newfstab"
|
|
echo "/dev/disk/by-id/dm-name-home /home ext4 defaults,errors=remount-ro,noauto,nosuid,noexec,nodev 0 0" >> "$newfstab"
|
|
cat "$newfstab" > /etc/fstab
|
|
rm -f "$newfstab"
|
|
action_done
|
|
|
|
action_doing "Remounting /home after encryption"
|
|
if mount /home; then
|
|
action_done
|
|
else
|
|
action_error "Error while remounting home, aborting!"
|
|
exit 1
|
|
fi
|
|
|
|
action_doing "Rsyncing back /home contents"
|
|
if rsync -vaPHAX --remove-source-files --exclude='lost+found' /tmphome/ /home/; then
|
|
action_done
|
|
else
|
|
action_error "Rsync failed, aborting!"
|
|
exit 1
|
|
fi
|
|
|
|
action_doing "Removing /tmphome"
|
|
if find /tmphome -depth -type d -empty -delete; then
|
|
action_done
|
|
else
|
|
action_error "Error while removing /tmphome, continuing anyway"
|
|
fi
|
|
|
|
action_doing "Testing whether we can properly unlock /home after boot"
|
|
if umount /home; then
|
|
if cryptsetup luksClose home; then
|
|
if /opt/bastion/bin/admin/unlock-home.sh; then
|
|
action_done
|
|
else
|
|
action_error "Error with unlock-home.sh, ignoring"
|
|
fi
|
|
else
|
|
action_error "Couldn't luksClose home, ignoring"
|
|
fi
|
|
else
|
|
action_error "Couldn't umount /home to run the test, ignoring"
|
|
fi
|
|
|
|
[ ! -e /root/unlock-home.sh ] && ln -s /opt/bastion/bin/admin/unlock-home.sh /root/
|
|
|