Recreate bootable hard drive from backup image
Table of Contents
Situation
I made a mistake and need to fix it by converting the backup image to a fully partitioned hard drive. At the same time I will apply encryption.
Mount qcow2 image
As root:
- Install qemu-base (ArchLinux):
pacman -S qemu-base
- Make sure the
nbd
module is loaded:modprobe nbd max_part=8
- Connect the image as a network block device:
qemu-nbd --connect=/dev/nbd0 /path/to/image.qcow2
- Check:
fdisk -l /dev/nbd0
- Mount it:
mount /dev/nbd0 /some/mount/point
nota bene: since I messed up, I need to mount the whole disk. Normally one would mount a partition at this point, something like/dev/nbd0p1
. cd /some/mount/point
(source)
Prepare the (remote) target drive
Now boot the system that allows you to format the remote machine's drive
Optional for servers
At this point you might want to read the rest of this article before taking your server offline.
My ISP offers a rescue system that can be live-booted through their web interface and runs as root. It also allows root login via ssh.
- Make sure only one user can ssh in (
nano /etc/ssh/sshd_config
), then change the password for that user to something really long withpasswd user
. Or set up an ssh key pair, even better. - Enable the
ssh
daemon on the live boot - in my case it was enough tosystemctl start ssh
Partition the disk
I created a 500MB ext2 /boot/
partition, the whole rest goes into one big partition. I used Gparted to create the big partition as ext4. Let's say we now have /dev/sda1
with 500MB and /dev/sda2
, our encryption target.
Encrypt
Mostly following this page; the local system is Arch, but the target is Debian stable.
- Format the partition (again):
cryptsetup luksFormat /dev/sda2
- Open it:
cryptsetup open /dev/sda2 system
Since I won't be needing several partitions inside this (I plan to use a swap file later), I'm not going to create a volume group (LVM, the usual recommendation in most tutorials) but instead just make one big filesystem: mkfs.ext4 /dev/mapper/system
Finally, mount both partitions to some temporary mountpoints on the live system:
mount /dev/mapper/system /media/system
mount /dev/sda1 /media/boot
Copy the system over
We will use rsync
for this. Remember the mounted qcow2 image, which contains a (theoretically) working OS.
Populate the /boot
partition:
rsync -arvPAXH -e ssh /some/mount/point/boot/ root@serverIP:/media/boot
Then the rest, excluding volatile system directories (these shouldn't be present on an offline backup anyhow):
rsync -arvPAXH --exclude={/tmp,/run,/srv,/media,/dev,/boot} -e ssh /some/mount/point/ root@serverIP:/media/system
You should do this as root (I have since learned that rsync can be told to run the ssh process as another user, while still doing things with root privileges on both sides).
Finalize
To install and update GRUB we need to chroot into the mounted partition (source):
cd /media/system
mkdir -p dev/pts proc sys boot run tmp
mount --bind /dev dev && mount --bind /dev/pts dev/pts && \
mount --bind /proc proc && mount --bind /sys sys && \
mount --bind ../boot boot
chroot . /bin/bash # The /bin/bash is not always required
Configure GRUB and InitramFS
- Find out the cryptdevice's UUID with
blkid
- Edit
/etc/default/grub
and add or edit this line:
GRUB_CMDLINE_LINUX_DEFAULT="cryptdevice=UUID=XXXXXXXXXXXXXXXXXX:system root=/dev/mapper/system rw"
- edit
/etc/crypttab
to add this line: `system UUID=XXXXXXXXXXXXXXXXX - Install and update GRUB:
grub-install /dev/sda && update-grub
- Check the configuration:
less /boot/grub/grub.cfg
- update the intrd image:
update-initramfs -uv -k all | grep cryptsetup
- this should mentioncryptsetup
- if not, try this:echo "CRYPTSETUP=y" >> /etc/cryptsetup-initramfs/conf-hook
and/or see here.
Exit the chroot and Unmount
exit
cd ..
umount system/dev/pts system/dev system/proc system/boot system/sys system
Reboot...
Minor hiccups - two services failed:
- atd: "Cannot change to /var/spool/cron/atjobs: Permission denied" - the man page has the answer:
/var/spool/cron/atjobs The directory for storing jobs; this should be mode 700, owner daemon. /var/spool/cron/atspool The directory for storing output; this should be mode 700, owner daemon.
- logrotate: apparently just needed a restart. Race condition during boot?