MMGen
-
Posts
40 -
Joined
-
Last visited
Reputation Activity
-
MMGen reacted to Igor in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
Great job!
Interested for integration into main config tool? https://github.com/armbian/configng Now this tools is properly made.
https://docs.armbian.com/User-Guide_Armbian-Software/#adding-example
-
MMGen got a reaction from Igor in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
The tutorial and automated script have been updated for images that use extlinux.conf to configure the bootloader.
In addition, some logic has been added to select the correct network device name (eth0 on some systems, end0 on others).
The script has been successfully tested on the Banana Pi F3 with the Ubuntu Noble legacy minimal image.
-
MMGen reacted to DIYprojectz in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
@MMGen
Got Rock 5B working by following the guide (keyboard unlock only, without SSH - as desired). Thank you very much!
However, at least with the following images:
* Armbian_24.8.1_Rock-5b_bookworm_current_6.10.6_cinnamon-backported-mesa_desktop.img.xz
* Armbian_24.8.1_Rock-5b_jammy_current_6.10.6_kde-neon-kisak_desktop.img.xz
# cat /etc/resolv.conf > etc/resolv.conf
does absolutely nothing, have to create the file manually and set desired DNS server there.
-
MMGen got a reaction from DIYprojectz in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
The tutorial and automated script have been updated for Debian bookworm and Ubuntu noble images. Here's a summary of the changes required to make everything work:
replace eth0 with end0 replace cryptsetup-bin with cryptsetup replace lsinitramfs /boot/initrd.img* with lsinitramfs /boot/initrd.img-* replace etc/dropbear-initramfs with etc/dropbear/initramfs replace etc/dropbear-initramfs/config with etc/dropbear/initramfs/dropbear.conf before exiting the chroot, execute ssh-keygen -A -
MMGen reacted to Vasir in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
Orangepi5 installed successfully using this process. Did not work on bookworm but worked on Orangepi5_1.1.6_debian_bullseye_server_linux5.10.110 with small modifications.
-
MMGen reacted to Tim Makarios in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
I used this tutorial as the basis of my own script, which is heavily adapted for my own needs. It worked for me, getting a bookworm CLI image to run on a Libre Computer Renegade.
Although I made lots of changes, I think the only ones necessary for getting it to work on a bookworm image were replacing "etc/dropbear-initramfs" with "etc/dropbear/initramfs" twice in step 9.4, and replacing "etc/dropbear-initramfs/config" with "etc/dropbear/initramfs/dropbear.conf" twice in step 9.7. Perhaps this was the problem @Vasir encountered?
-
MMGen got a reaction from Tim Makarios in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
Full root filesystem encryption on an Armbian system
(new, fully rewritten, replaces my earlier tutorial on this topic)
MMGen (https://github.com/mmgen)
This tutorial provides detailed, step-by-step instructions for setting up full root filesystem encryption on an Armbian system. The disk can be unlocked remotely via SSH or the serial console, permitting unattended bootup.
An automated script that performs the same steps, saving you much time and effort, can be found at https://github.com/mmgen/mmgen-geek-tools
Note that unlike my earlier tutorial all steps are performed within a running Armbian system.
The tutorial is known to work with the following board/image combinations:
Orange Pi PC2 Debian Buster mainline / Ubuntu Bionic and Focal legacy RockPi 4 Debian Buster mainline / Ubuntu Bionic and Focal legacy RockPro 64 Ubuntu Focal mainline Odroid HC4 Debian Buster mainline / Ubuntu Focal mainline
You may have success with other boards/images too. If so, please post the details below (or open an issue in the mmgen-geek-tools Github repository), and I’ll add your board to the list.
Requirements:
A SoC with a running, upgradeable and Internet-connected Armbian system A blank Micro-SD card and USB card reader, or, alternatively, an eMMC installed on the board The ability to edit text files and do simple administrative tasks on the Linux command line
Step 1 - Preliminaries
All steps in this tutorial are performed as root user on a running Armbian system (the “host”).
The encrypted system (the “target”) will be created on a blank micro-SD card (the “target device”).
If the board has an eMMC, it may be used as the target device instead of an SD card. Depending on your platform, you may need to run “armbian-config” and select “Install to internal storage” -> “Install/Update the bootloader on eMMC” to enable booting from the eMMC.
Architecture of host and target (e.g. 64-bit or 32-bit ARM) must be the same.
For best results, the host and target hardware should also be identical or similar. Building on a host with more memory than the target, for example, may lead to disk unlocking failure on the target.
If you’re building the target system for the currently running board and with the currently running image, which is the recommended approach, the two preceding points will be a non-issue.
Packages will be installed using APT, so the host machine must be Internet-connected and its clock correctly set.
Step 2 - Upgrade your system and install the cryptsetup package
# apt update && apt upgrade # apt install cryptsetup
Step 3 - Get and unpack the latest Armbian image for your board
Create your build directory:
# mkdir armbenc-build && cd armbenc-build
Download the Armbian image of your choice for your board, place it in this directory and unpack:
# xz -dv *.img.xz
Step 4 - Create mount directories and set up the loop mount
Create the mount directories:
# mkdir -p mnt boot root
Determine your first free loop device:
# losetup -f
Associate the image file with the loop device name displayed by the previous command. This will be '/dev/loop0' in most cases, but if your output was different, substitute that for '/dev/loop0' in the following steps.
# losetup -P /dev/loop0 *.img
Examine the disk image using fdisk on the loop device:
# fdisk -l /dev/loop0
The output should look something like this:
Device Boot Start End Sectors Size Id Type /dev/loop0p1 32768 3489791 3457024 1.7G 83 Linux
Make a note of the start sector (32768 in this case). You’ll need this value in the steps below.
Now mount the loop device:
# mount /dev/loop0p1 mnt
Step 5 - Copy the boot loader to the target device
If applicable, insert a blank micro-SD card and card reader into a USB port.
Determine the target device name using 'dmesg' or 'lsblk'. We’ll assume it to be '/dev/sda', since that’s the most likely case. If your device name is different, substitute it for '/dev/sda' in the the following steps. For an eMMC, the device name will be something like '/dev/mmcblk1'.
WARNING: if '/dev/sda' refers to some other storage device, running the following commands unchanged will destroy data on that device, so always remember to substitute the correct device name!!! The best way to eliminate this danger is to disconnect all unused storage devices on the board before proceeding further.
Copy the image’s boot loader to the target device, using the Start sector value from Step 4 as the argument for 'count':
# dd if=$(echo *.img) of=/dev/sda bs=512 count=32768
Step 6 - Partition the target device
# fdisk /dev/sda
At the fdisk prompt, create a new DOS disk label with the 'o' command. Use the 'n' command to create a primary partition of size +200M beginning at the same Start sector as the disk image. Type 'p' to view the partition table, which should now look something like this:
Device Boot Start End Sectors Size Id Type /dev/sda1 32768 442367 409600 200M 83 Linux
Use 'n' again to create another primary partition beginning one sector after the first partition’s end sector and filling the remainder of the card. Type 'p' once more to view the partition table:
Device Boot Start End Sectors Size Id Type /dev/sda1 32768 442367 409600 200M 83 Linux /dev/sda2 442368 30636031 30193664 14.4G 83 Linux
Ensure that the first partition’s Start sector matches that of the disk image (32768 in this example) and that the second partition’s Start sector is one greater than the End sector of the first (442368 and 442367, respectively, in this example). If you’ve made a mistake, use 'd' to delete a partition and start again.
Once everything looks correct, type 'w' to write the partition table to disk.
Step 7 - Copy the system to the target device
The following commands will create a filesystem on the target device’s boot partition and copy the boot partition data from the image file to it. Don’t forget to substitute the correct device name if necessary. If you’re building the system on an eMMC, the boot partition device will be something like '/dev/mmcblk1p1' instead of '/dev/sda1'.
# mkfs.ext4 /dev/sda1 # or '/dev/mmcblk1p1', for an eMMC target # e2label /dev/sda1 CRYPTO_BOOT # mount /dev/sda1 boot # cp -av mnt/boot/* boot # (cd boot; ln -s . boot)
Create the encrypted root partition. When prompted for a passphrase, it’s advisable to choose an easy one like 'abc' for now. The passphrase can be changed later with the 'cryptsetup luksChangeKey' command (type 'man cryptsetup' for details) once your encrypted system is up and running.
# cryptsetup luksFormat /dev/sda2 # or '/dev/mmcblk1p2', for an eMMC target
Activate the encrypted root partition and create a filesystem on it:
# cryptsetup luksOpen /dev/sda2 rootfs # enter your passphrase from above # mkfs.ext4 /dev/mapper/rootfs
Mount the encrypted root partition and copy the system to it:
# mount /dev/mapper/rootfs root # (cd mnt && rsync -a --info=progress2 --exclude=boot * ../root) # sync # be patient, this could take a while # mkdir root/boot # touch root/root/.no_rootfs_resize
Unmount the boot partition and image and free the loop device:
# umount mnt boot # losetup -d /dev/loop0
Step 8 - Prepare the target system chroot
# BOOT_PART=($(lsblk -l -o NAME,LABEL | grep CRYPTO_BOOT)) # ROOT_PART=${BOOT_PART%1}2 # ROOT_UUID="$(lsblk --nodeps --noheadings --output=UUID /dev/$ROOT_PART)" # BOOT_UUID="$(lsblk --noheadings --output=UUID /dev/$BOOT_PART)" # cd root # mount /dev/$BOOT_PART boot # mount -o rbind /dev dev # mount -t proc proc proc # mount -t sysfs sys sys
Copy '/etc/resolv.conf' and '/etc/hosts' so you’ll have a working Internet connection within the chroot:
# cat /etc/resolv.conf > etc/resolv.conf # cat /etc/hosts > etc/hosts
If you’re using non-default APT repositories, you may need to copy their configuration files as well so that 'apt update' and 'apt install' will use them inside the chroot. Note that you can only do this if the host and target systems have the same distro/version. If that’s not the case, you’ll have to edit the target files by hand.
# cat /etc/apt/sources.list > etc/apt/sources.list # cat /etc/apt/sources.list.d/armbian.list > etc/apt/sources.list.d/armbian.list
If you’re using an apt proxy, then copy its configuration file too:
# cp /etc/apt/apt.conf.d/*proxy etc/apt/apt.conf.d/
Step 9 - Edit or create required configuration files in the target system
Perform the editing steps below using a text editor of your choice:
If the file 'boot/armbianEnv.txt' exists, edit it so that the 'rootdev', 'console' and 'bootlogo' lines read as follows. If you’ll be unlocking the disk via the serial console, then use 'console=serial' instead of 'console=display'. Note that enabling the serial console will make it impossible to unlock the disk from the keyboard and monitor, though unlocking via SSH will still work:
rootdev=/dev/mapper/rootfs console=display bootlogo=false If your image lacks an 'armbianEnv.txt' file, you’ll need to edit the file 'boot/extlinux/extlinux.conf' instead. All changes will be made to the line beginning with “append”. Alter the argument beginning with “root=” so that it reads “root=/dev/mapper/rootfs”. If you’ll be unlocking the disk via the serial console, remove the “console=tty1” argument. If not, remove the argument beginning with “console=ttyS...”. Replace the “splash plymouth...” argument with “splash=verbose”. Make sure to read the note about unlocking via serial console in the previous step.
Edit 'etc/initramfs-tools/initramfs.conf'. If your board will have a statically configured IP, add the following line to the end of the file, substituting the correct IP in place of 192.168.0.88:
IP=192.168.0.88:::255.255.255.0::end0:off If the board will be configured via DHCP, then edit the DEVICE line as follows:
DEVICE=end0 If your default network device is eth0, use that instead of end0.
If host and target systems are both Debian buster, you may wish add some key modules to the initramfs to avoid a blank display at bootup time. The easiest way to do this is to add all currently loaded modules as follows: # lsmod | cut -d ' ' -f1 | tail -n+2 > etc/initramfs-tools/modules Retrieve the SSH public key from the remote unlocking host and copy it to the target:
# mkdir -p etc/dropbear/initramfs # rsync yourusername@remote_machine:.ssh/id_*.pub etc/dropbear/initramfs/authorized_keys If you want to unlock the disk from more than one host, then edit the authorized_keys file by hand, adding the required additional keys.
Create 'etc/crypttab':
# echo "rootfs UUID=$ROOT_UUID none initramfs,luks" > etc/crypttab Create 'etc/fstab':
# echo '/dev/mapper/rootfs / ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 1' > etc/fstab # echo "UUID=$BOOT_UUID /boot ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 2" >> etc/fstab # echo 'tmpfs /tmp tmpfs defaults,nosuid 0 0' >> etc/fstab Create the dropbear configuration file:
# echo 'DROPBEAR_OPTIONS="-p 2222"' > etc/dropbear/initramfs/dropbear.conf # echo 'DROPBEAR=y' >> etc/dropbear/initramfs/dropbear.conf
If the target is Ubuntu bionic, then a deprecated environment variable must be set as follows:
# echo 'export CRYPTSETUP=y' > etc/initramfs-tools/conf.d/cryptsetup
Set up automatic disk unlock prompt. Performing this optional step will cause the disk password prompt to appear automatically when you log in remotely via SSH to unlock the disk. Using your text editor, create the file 'etc/initramfs-tools/hooks/cryptroot-unlock.sh' with the following contents: #!/bin/sh if [ "$1" = 'prereqs' ]; then echo 'dropbear-initramfs'; exit 0; fi . /usr/share/initramfs-tools/hook-functions source='/tmp/cryptroot-unlock-profile' root_home=$(echo $DESTDIR/root-*) root_home=${root_home#$DESTDIR} echo 'if [ "$SSH_CLIENT" ]; then /usr/bin/cryptroot-unlock; fi' > $source copy_file ssh_login_profile $source $root_home/.profile exit 0
Save the file and execute the command:
chmod 755 'etc/initramfs-tools/hooks/cryptroot-unlock.sh'
Step 10 - Chroot into the target system, install packages and configure
Now chroot into the encrypted system. All remaining steps will be performed inside the chroot:
# chroot .
Install the cryptsetup package and the dropbear SSH server:
# apt update # echo 'force-confdef' > /root/.dpkg.cfg # apt --yes install cryptsetup-initramfs dropbear-initramfs # for a buster or focal image # apt --yes install cryptsetup dropbear-initramfs # for a bionic image # rm /root/.dpkg.cfg
Make sure everything was included in the initramfs (all three commands should produce output):
# lsinitramfs /boot/initrd.img-* | grep 'usr.*cryptsetup' # lsinitramfs /boot/initrd.img-* | grep dropbear # lsinitramfs /boot/initrd.img-* | grep authorized_keys
Now regenerate your SSH host keys:
# ssh-keygen -A
Your work is finished! Exit the chroot and shut down the board:
# exit # halt -p
Insert your freshly written SD card into the board’s main SD slot (or, if the target is an eMMC, just remove the SD card from that slot) and reboot.
Unlock the disk by executing the following command on your remote unlocking machine, substituting the correct IP address if necessary:
$ ssh -p 2222 root@192.168.0.88
If you performed step 9.10 above, the disk password prompt should appear automatically after login. If not, you must enter the command 'cryptroot-unlock'.
You may also unlock the disk from the target board’s console if you wish. Note, however, that certain disk images (RockPi 4 buster mainline, for example) might give you a blank display at startup, so you’ll have to enter your disk password “blindly”. This bug will hopefully be fixed in the future.
If all went well, your root-filesystem encrypted Armbian system is now up and running!
-
MMGen got a reaction from DIYprojectz in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
@DIYprojectz: It should be possible to put the encrypted root filesystem on a different device than the boot partition, though I've never tried it with an SoC or Armbian. Thanks for the idea. I promise to look into it, but don't expect immediate results as I'm busy with other things at the moment.
-
MMGen got a reaction from Werner in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
Thanks for the offer/request. I'll be busy for the next several days, but when I get some free time I'll look into doing this.
-
MMGen got a reaction from mar0ni in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
Full root filesystem encryption on an Armbian system
(new, fully rewritten, replaces my earlier tutorial on this topic)
MMGen (https://github.com/mmgen)
This tutorial provides detailed, step-by-step instructions for setting up full root filesystem encryption on an Armbian system. The disk can be unlocked remotely via SSH or the serial console, permitting unattended bootup.
An automated script that performs the same steps, saving you much time and effort, can be found at https://github.com/mmgen/mmgen-geek-tools
Note that unlike my earlier tutorial all steps are performed within a running Armbian system.
The tutorial is known to work with the following board/image combinations:
Orange Pi PC2 Debian Buster mainline / Ubuntu Bionic and Focal legacy RockPi 4 Debian Buster mainline / Ubuntu Bionic and Focal legacy RockPro 64 Ubuntu Focal mainline Odroid HC4 Debian Buster mainline / Ubuntu Focal mainline
You may have success with other boards/images too. If so, please post the details below (or open an issue in the mmgen-geek-tools Github repository), and I’ll add your board to the list.
Requirements:
A SoC with a running, upgradeable and Internet-connected Armbian system A blank Micro-SD card and USB card reader, or, alternatively, an eMMC installed on the board The ability to edit text files and do simple administrative tasks on the Linux command line
Step 1 - Preliminaries
All steps in this tutorial are performed as root user on a running Armbian system (the “host”).
The encrypted system (the “target”) will be created on a blank micro-SD card (the “target device”).
If the board has an eMMC, it may be used as the target device instead of an SD card. Depending on your platform, you may need to run “armbian-config” and select “Install to internal storage” -> “Install/Update the bootloader on eMMC” to enable booting from the eMMC.
Architecture of host and target (e.g. 64-bit or 32-bit ARM) must be the same.
For best results, the host and target hardware should also be identical or similar. Building on a host with more memory than the target, for example, may lead to disk unlocking failure on the target.
If you’re building the target system for the currently running board and with the currently running image, which is the recommended approach, the two preceding points will be a non-issue.
Packages will be installed using APT, so the host machine must be Internet-connected and its clock correctly set.
Step 2 - Upgrade your system and install the cryptsetup package
# apt update && apt upgrade # apt install cryptsetup
Step 3 - Get and unpack the latest Armbian image for your board
Create your build directory:
# mkdir armbenc-build && cd armbenc-build
Download the Armbian image of your choice for your board, place it in this directory and unpack:
# xz -dv *.img.xz
Step 4 - Create mount directories and set up the loop mount
Create the mount directories:
# mkdir -p mnt boot root
Determine your first free loop device:
# losetup -f
Associate the image file with the loop device name displayed by the previous command. This will be '/dev/loop0' in most cases, but if your output was different, substitute that for '/dev/loop0' in the following steps.
# losetup -P /dev/loop0 *.img
Examine the disk image using fdisk on the loop device:
# fdisk -l /dev/loop0
The output should look something like this:
Device Boot Start End Sectors Size Id Type /dev/loop0p1 32768 3489791 3457024 1.7G 83 Linux
Make a note of the start sector (32768 in this case). You’ll need this value in the steps below.
Now mount the loop device:
# mount /dev/loop0p1 mnt
Step 5 - Copy the boot loader to the target device
If applicable, insert a blank micro-SD card and card reader into a USB port.
Determine the target device name using 'dmesg' or 'lsblk'. We’ll assume it to be '/dev/sda', since that’s the most likely case. If your device name is different, substitute it for '/dev/sda' in the the following steps. For an eMMC, the device name will be something like '/dev/mmcblk1'.
WARNING: if '/dev/sda' refers to some other storage device, running the following commands unchanged will destroy data on that device, so always remember to substitute the correct device name!!! The best way to eliminate this danger is to disconnect all unused storage devices on the board before proceeding further.
Copy the image’s boot loader to the target device, using the Start sector value from Step 4 as the argument for 'count':
# dd if=$(echo *.img) of=/dev/sda bs=512 count=32768
Step 6 - Partition the target device
# fdisk /dev/sda
At the fdisk prompt, create a new DOS disk label with the 'o' command. Use the 'n' command to create a primary partition of size +200M beginning at the same Start sector as the disk image. Type 'p' to view the partition table, which should now look something like this:
Device Boot Start End Sectors Size Id Type /dev/sda1 32768 442367 409600 200M 83 Linux
Use 'n' again to create another primary partition beginning one sector after the first partition’s end sector and filling the remainder of the card. Type 'p' once more to view the partition table:
Device Boot Start End Sectors Size Id Type /dev/sda1 32768 442367 409600 200M 83 Linux /dev/sda2 442368 30636031 30193664 14.4G 83 Linux
Ensure that the first partition’s Start sector matches that of the disk image (32768 in this example) and that the second partition’s Start sector is one greater than the End sector of the first (442368 and 442367, respectively, in this example). If you’ve made a mistake, use 'd' to delete a partition and start again.
Once everything looks correct, type 'w' to write the partition table to disk.
Step 7 - Copy the system to the target device
The following commands will create a filesystem on the target device’s boot partition and copy the boot partition data from the image file to it. Don’t forget to substitute the correct device name if necessary. If you’re building the system on an eMMC, the boot partition device will be something like '/dev/mmcblk1p1' instead of '/dev/sda1'.
# mkfs.ext4 /dev/sda1 # or '/dev/mmcblk1p1', for an eMMC target # e2label /dev/sda1 CRYPTO_BOOT # mount /dev/sda1 boot # cp -av mnt/boot/* boot # (cd boot; ln -s . boot)
Create the encrypted root partition. When prompted for a passphrase, it’s advisable to choose an easy one like 'abc' for now. The passphrase can be changed later with the 'cryptsetup luksChangeKey' command (type 'man cryptsetup' for details) once your encrypted system is up and running.
# cryptsetup luksFormat /dev/sda2 # or '/dev/mmcblk1p2', for an eMMC target
Activate the encrypted root partition and create a filesystem on it:
# cryptsetup luksOpen /dev/sda2 rootfs # enter your passphrase from above # mkfs.ext4 /dev/mapper/rootfs
Mount the encrypted root partition and copy the system to it:
# mount /dev/mapper/rootfs root # (cd mnt && rsync -a --info=progress2 --exclude=boot * ../root) # sync # be patient, this could take a while # mkdir root/boot # touch root/root/.no_rootfs_resize
Unmount the boot partition and image and free the loop device:
# umount mnt boot # losetup -d /dev/loop0
Step 8 - Prepare the target system chroot
# BOOT_PART=($(lsblk -l -o NAME,LABEL | grep CRYPTO_BOOT)) # ROOT_PART=${BOOT_PART%1}2 # ROOT_UUID="$(lsblk --nodeps --noheadings --output=UUID /dev/$ROOT_PART)" # BOOT_UUID="$(lsblk --noheadings --output=UUID /dev/$BOOT_PART)" # cd root # mount /dev/$BOOT_PART boot # mount -o rbind /dev dev # mount -t proc proc proc # mount -t sysfs sys sys
Copy '/etc/resolv.conf' and '/etc/hosts' so you’ll have a working Internet connection within the chroot:
# cat /etc/resolv.conf > etc/resolv.conf # cat /etc/hosts > etc/hosts
If you’re using non-default APT repositories, you may need to copy their configuration files as well so that 'apt update' and 'apt install' will use them inside the chroot. Note that you can only do this if the host and target systems have the same distro/version. If that’s not the case, you’ll have to edit the target files by hand.
# cat /etc/apt/sources.list > etc/apt/sources.list # cat /etc/apt/sources.list.d/armbian.list > etc/apt/sources.list.d/armbian.list
If you’re using an apt proxy, then copy its configuration file too:
# cp /etc/apt/apt.conf.d/*proxy etc/apt/apt.conf.d/
Step 9 - Edit or create required configuration files in the target system
Perform the editing steps below using a text editor of your choice:
If the file 'boot/armbianEnv.txt' exists, edit it so that the 'rootdev', 'console' and 'bootlogo' lines read as follows. If you’ll be unlocking the disk via the serial console, then use 'console=serial' instead of 'console=display'. Note that enabling the serial console will make it impossible to unlock the disk from the keyboard and monitor, though unlocking via SSH will still work:
rootdev=/dev/mapper/rootfs console=display bootlogo=false If your image lacks an 'armbianEnv.txt' file, you’ll need to edit the file 'boot/extlinux/extlinux.conf' instead. All changes will be made to the line beginning with “append”. Alter the argument beginning with “root=” so that it reads “root=/dev/mapper/rootfs”. If you’ll be unlocking the disk via the serial console, remove the “console=tty1” argument. If not, remove the argument beginning with “console=ttyS...”. Replace the “splash plymouth...” argument with “splash=verbose”. Make sure to read the note about unlocking via serial console in the previous step.
Edit 'etc/initramfs-tools/initramfs.conf'. If your board will have a statically configured IP, add the following line to the end of the file, substituting the correct IP in place of 192.168.0.88:
IP=192.168.0.88:::255.255.255.0::end0:off If the board will be configured via DHCP, then edit the DEVICE line as follows:
DEVICE=end0 If your default network device is eth0, use that instead of end0.
If host and target systems are both Debian buster, you may wish add some key modules to the initramfs to avoid a blank display at bootup time. The easiest way to do this is to add all currently loaded modules as follows: # lsmod | cut -d ' ' -f1 | tail -n+2 > etc/initramfs-tools/modules Retrieve the SSH public key from the remote unlocking host and copy it to the target:
# mkdir -p etc/dropbear/initramfs # rsync yourusername@remote_machine:.ssh/id_*.pub etc/dropbear/initramfs/authorized_keys If you want to unlock the disk from more than one host, then edit the authorized_keys file by hand, adding the required additional keys.
Create 'etc/crypttab':
# echo "rootfs UUID=$ROOT_UUID none initramfs,luks" > etc/crypttab Create 'etc/fstab':
# echo '/dev/mapper/rootfs / ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 1' > etc/fstab # echo "UUID=$BOOT_UUID /boot ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 2" >> etc/fstab # echo 'tmpfs /tmp tmpfs defaults,nosuid 0 0' >> etc/fstab Create the dropbear configuration file:
# echo 'DROPBEAR_OPTIONS="-p 2222"' > etc/dropbear/initramfs/dropbear.conf # echo 'DROPBEAR=y' >> etc/dropbear/initramfs/dropbear.conf
If the target is Ubuntu bionic, then a deprecated environment variable must be set as follows:
# echo 'export CRYPTSETUP=y' > etc/initramfs-tools/conf.d/cryptsetup
Set up automatic disk unlock prompt. Performing this optional step will cause the disk password prompt to appear automatically when you log in remotely via SSH to unlock the disk. Using your text editor, create the file 'etc/initramfs-tools/hooks/cryptroot-unlock.sh' with the following contents: #!/bin/sh if [ "$1" = 'prereqs' ]; then echo 'dropbear-initramfs'; exit 0; fi . /usr/share/initramfs-tools/hook-functions source='/tmp/cryptroot-unlock-profile' root_home=$(echo $DESTDIR/root-*) root_home=${root_home#$DESTDIR} echo 'if [ "$SSH_CLIENT" ]; then /usr/bin/cryptroot-unlock; fi' > $source copy_file ssh_login_profile $source $root_home/.profile exit 0
Save the file and execute the command:
chmod 755 'etc/initramfs-tools/hooks/cryptroot-unlock.sh'
Step 10 - Chroot into the target system, install packages and configure
Now chroot into the encrypted system. All remaining steps will be performed inside the chroot:
# chroot .
Install the cryptsetup package and the dropbear SSH server:
# apt update # echo 'force-confdef' > /root/.dpkg.cfg # apt --yes install cryptsetup-initramfs dropbear-initramfs # for a buster or focal image # apt --yes install cryptsetup dropbear-initramfs # for a bionic image # rm /root/.dpkg.cfg
Make sure everything was included in the initramfs (all three commands should produce output):
# lsinitramfs /boot/initrd.img-* | grep 'usr.*cryptsetup' # lsinitramfs /boot/initrd.img-* | grep dropbear # lsinitramfs /boot/initrd.img-* | grep authorized_keys
Now regenerate your SSH host keys:
# ssh-keygen -A
Your work is finished! Exit the chroot and shut down the board:
# exit # halt -p
Insert your freshly written SD card into the board’s main SD slot (or, if the target is an eMMC, just remove the SD card from that slot) and reboot.
Unlock the disk by executing the following command on your remote unlocking machine, substituting the correct IP address if necessary:
$ ssh -p 2222 root@192.168.0.88
If you performed step 9.10 above, the disk password prompt should appear automatically after login. If not, you must enter the command 'cryptroot-unlock'.
You may also unlock the disk from the target board’s console if you wish. Note, however, that certain disk images (RockPi 4 buster mainline, for example) might give you a blank display at startup, so you’ll have to enter your disk password “blindly”. This bug will hopefully be fixed in the future.
If all went well, your root-filesystem encrypted Armbian system is now up and running!
-
MMGen got a reaction from Bagel in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
Yes, this should be doable. Create a LUKS partition and ext4 fs on the SSD, copy the root fs to it, update /etc/crypttab with the new device UUID, mount, chroot and update the initramfs. I haven't tested this myself though, so other steps might be required. But first you should try the tutorial without modification to make sure it works for your board. If it does, please let me know and I'll add the HC4 to the "supported" list.
-
MMGen got a reaction from Werner in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
Full root filesystem encryption on an Armbian system
(new, fully rewritten, replaces my earlier tutorial on this topic)
MMGen (https://github.com/mmgen)
This tutorial provides detailed, step-by-step instructions for setting up full root filesystem encryption on an Armbian system. The disk can be unlocked remotely via SSH or the serial console, permitting unattended bootup.
An automated script that performs the same steps, saving you much time and effort, can be found at https://github.com/mmgen/mmgen-geek-tools
Note that unlike my earlier tutorial all steps are performed within a running Armbian system.
The tutorial is known to work with the following board/image combinations:
Orange Pi PC2 Debian Buster mainline / Ubuntu Bionic and Focal legacy RockPi 4 Debian Buster mainline / Ubuntu Bionic and Focal legacy RockPro 64 Ubuntu Focal mainline Odroid HC4 Debian Buster mainline / Ubuntu Focal mainline
You may have success with other boards/images too. If so, please post the details below (or open an issue in the mmgen-geek-tools Github repository), and I’ll add your board to the list.
Requirements:
A SoC with a running, upgradeable and Internet-connected Armbian system A blank Micro-SD card and USB card reader, or, alternatively, an eMMC installed on the board The ability to edit text files and do simple administrative tasks on the Linux command line
Step 1 - Preliminaries
All steps in this tutorial are performed as root user on a running Armbian system (the “host”).
The encrypted system (the “target”) will be created on a blank micro-SD card (the “target device”).
If the board has an eMMC, it may be used as the target device instead of an SD card. Depending on your platform, you may need to run “armbian-config” and select “Install to internal storage” -> “Install/Update the bootloader on eMMC” to enable booting from the eMMC.
Architecture of host and target (e.g. 64-bit or 32-bit ARM) must be the same.
For best results, the host and target hardware should also be identical or similar. Building on a host with more memory than the target, for example, may lead to disk unlocking failure on the target.
If you’re building the target system for the currently running board and with the currently running image, which is the recommended approach, the two preceding points will be a non-issue.
Packages will be installed using APT, so the host machine must be Internet-connected and its clock correctly set.
Step 2 - Upgrade your system and install the cryptsetup package
# apt update && apt upgrade # apt install cryptsetup
Step 3 - Get and unpack the latest Armbian image for your board
Create your build directory:
# mkdir armbenc-build && cd armbenc-build
Download the Armbian image of your choice for your board, place it in this directory and unpack:
# xz -dv *.img.xz
Step 4 - Create mount directories and set up the loop mount
Create the mount directories:
# mkdir -p mnt boot root
Determine your first free loop device:
# losetup -f
Associate the image file with the loop device name displayed by the previous command. This will be '/dev/loop0' in most cases, but if your output was different, substitute that for '/dev/loop0' in the following steps.
# losetup -P /dev/loop0 *.img
Examine the disk image using fdisk on the loop device:
# fdisk -l /dev/loop0
The output should look something like this:
Device Boot Start End Sectors Size Id Type /dev/loop0p1 32768 3489791 3457024 1.7G 83 Linux
Make a note of the start sector (32768 in this case). You’ll need this value in the steps below.
Now mount the loop device:
# mount /dev/loop0p1 mnt
Step 5 - Copy the boot loader to the target device
If applicable, insert a blank micro-SD card and card reader into a USB port.
Determine the target device name using 'dmesg' or 'lsblk'. We’ll assume it to be '/dev/sda', since that’s the most likely case. If your device name is different, substitute it for '/dev/sda' in the the following steps. For an eMMC, the device name will be something like '/dev/mmcblk1'.
WARNING: if '/dev/sda' refers to some other storage device, running the following commands unchanged will destroy data on that device, so always remember to substitute the correct device name!!! The best way to eliminate this danger is to disconnect all unused storage devices on the board before proceeding further.
Copy the image’s boot loader to the target device, using the Start sector value from Step 4 as the argument for 'count':
# dd if=$(echo *.img) of=/dev/sda bs=512 count=32768
Step 6 - Partition the target device
# fdisk /dev/sda
At the fdisk prompt, create a new DOS disk label with the 'o' command. Use the 'n' command to create a primary partition of size +200M beginning at the same Start sector as the disk image. Type 'p' to view the partition table, which should now look something like this:
Device Boot Start End Sectors Size Id Type /dev/sda1 32768 442367 409600 200M 83 Linux
Use 'n' again to create another primary partition beginning one sector after the first partition’s end sector and filling the remainder of the card. Type 'p' once more to view the partition table:
Device Boot Start End Sectors Size Id Type /dev/sda1 32768 442367 409600 200M 83 Linux /dev/sda2 442368 30636031 30193664 14.4G 83 Linux
Ensure that the first partition’s Start sector matches that of the disk image (32768 in this example) and that the second partition’s Start sector is one greater than the End sector of the first (442368 and 442367, respectively, in this example). If you’ve made a mistake, use 'd' to delete a partition and start again.
Once everything looks correct, type 'w' to write the partition table to disk.
Step 7 - Copy the system to the target device
The following commands will create a filesystem on the target device’s boot partition and copy the boot partition data from the image file to it. Don’t forget to substitute the correct device name if necessary. If you’re building the system on an eMMC, the boot partition device will be something like '/dev/mmcblk1p1' instead of '/dev/sda1'.
# mkfs.ext4 /dev/sda1 # or '/dev/mmcblk1p1', for an eMMC target # e2label /dev/sda1 CRYPTO_BOOT # mount /dev/sda1 boot # cp -av mnt/boot/* boot # (cd boot; ln -s . boot)
Create the encrypted root partition. When prompted for a passphrase, it’s advisable to choose an easy one like 'abc' for now. The passphrase can be changed later with the 'cryptsetup luksChangeKey' command (type 'man cryptsetup' for details) once your encrypted system is up and running.
# cryptsetup luksFormat /dev/sda2 # or '/dev/mmcblk1p2', for an eMMC target
Activate the encrypted root partition and create a filesystem on it:
# cryptsetup luksOpen /dev/sda2 rootfs # enter your passphrase from above # mkfs.ext4 /dev/mapper/rootfs
Mount the encrypted root partition and copy the system to it:
# mount /dev/mapper/rootfs root # (cd mnt && rsync -a --info=progress2 --exclude=boot * ../root) # sync # be patient, this could take a while # mkdir root/boot # touch root/root/.no_rootfs_resize
Unmount the boot partition and image and free the loop device:
# umount mnt boot # losetup -d /dev/loop0
Step 8 - Prepare the target system chroot
# BOOT_PART=($(lsblk -l -o NAME,LABEL | grep CRYPTO_BOOT)) # ROOT_PART=${BOOT_PART%1}2 # ROOT_UUID="$(lsblk --nodeps --noheadings --output=UUID /dev/$ROOT_PART)" # BOOT_UUID="$(lsblk --noheadings --output=UUID /dev/$BOOT_PART)" # cd root # mount /dev/$BOOT_PART boot # mount -o rbind /dev dev # mount -t proc proc proc # mount -t sysfs sys sys
Copy '/etc/resolv.conf' and '/etc/hosts' so you’ll have a working Internet connection within the chroot:
# cat /etc/resolv.conf > etc/resolv.conf # cat /etc/hosts > etc/hosts
If you’re using non-default APT repositories, you may need to copy their configuration files as well so that 'apt update' and 'apt install' will use them inside the chroot. Note that you can only do this if the host and target systems have the same distro/version. If that’s not the case, you’ll have to edit the target files by hand.
# cat /etc/apt/sources.list > etc/apt/sources.list # cat /etc/apt/sources.list.d/armbian.list > etc/apt/sources.list.d/armbian.list
If you’re using an apt proxy, then copy its configuration file too:
# cp /etc/apt/apt.conf.d/*proxy etc/apt/apt.conf.d/
Step 9 - Edit or create required configuration files in the target system
Perform the editing steps below using a text editor of your choice:
If the file 'boot/armbianEnv.txt' exists, edit it so that the 'rootdev', 'console' and 'bootlogo' lines read as follows. If you’ll be unlocking the disk via the serial console, then use 'console=serial' instead of 'console=display'. Note that enabling the serial console will make it impossible to unlock the disk from the keyboard and monitor, though unlocking via SSH will still work:
rootdev=/dev/mapper/rootfs console=display bootlogo=false If your image lacks an 'armbianEnv.txt' file, you’ll need to edit the file 'boot/extlinux/extlinux.conf' instead. All changes will be made to the line beginning with “append”. Alter the argument beginning with “root=” so that it reads “root=/dev/mapper/rootfs”. If you’ll be unlocking the disk via the serial console, remove the “console=tty1” argument. If not, remove the argument beginning with “console=ttyS...”. Replace the “splash plymouth...” argument with “splash=verbose”. Make sure to read the note about unlocking via serial console in the previous step.
Edit 'etc/initramfs-tools/initramfs.conf'. If your board will have a statically configured IP, add the following line to the end of the file, substituting the correct IP in place of 192.168.0.88:
IP=192.168.0.88:::255.255.255.0::end0:off If the board will be configured via DHCP, then edit the DEVICE line as follows:
DEVICE=end0 If your default network device is eth0, use that instead of end0.
If host and target systems are both Debian buster, you may wish add some key modules to the initramfs to avoid a blank display at bootup time. The easiest way to do this is to add all currently loaded modules as follows: # lsmod | cut -d ' ' -f1 | tail -n+2 > etc/initramfs-tools/modules Retrieve the SSH public key from the remote unlocking host and copy it to the target:
# mkdir -p etc/dropbear/initramfs # rsync yourusername@remote_machine:.ssh/id_*.pub etc/dropbear/initramfs/authorized_keys If you want to unlock the disk from more than one host, then edit the authorized_keys file by hand, adding the required additional keys.
Create 'etc/crypttab':
# echo "rootfs UUID=$ROOT_UUID none initramfs,luks" > etc/crypttab Create 'etc/fstab':
# echo '/dev/mapper/rootfs / ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 1' > etc/fstab # echo "UUID=$BOOT_UUID /boot ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 2" >> etc/fstab # echo 'tmpfs /tmp tmpfs defaults,nosuid 0 0' >> etc/fstab Create the dropbear configuration file:
# echo 'DROPBEAR_OPTIONS="-p 2222"' > etc/dropbear/initramfs/dropbear.conf # echo 'DROPBEAR=y' >> etc/dropbear/initramfs/dropbear.conf
If the target is Ubuntu bionic, then a deprecated environment variable must be set as follows:
# echo 'export CRYPTSETUP=y' > etc/initramfs-tools/conf.d/cryptsetup
Set up automatic disk unlock prompt. Performing this optional step will cause the disk password prompt to appear automatically when you log in remotely via SSH to unlock the disk. Using your text editor, create the file 'etc/initramfs-tools/hooks/cryptroot-unlock.sh' with the following contents: #!/bin/sh if [ "$1" = 'prereqs' ]; then echo 'dropbear-initramfs'; exit 0; fi . /usr/share/initramfs-tools/hook-functions source='/tmp/cryptroot-unlock-profile' root_home=$(echo $DESTDIR/root-*) root_home=${root_home#$DESTDIR} echo 'if [ "$SSH_CLIENT" ]; then /usr/bin/cryptroot-unlock; fi' > $source copy_file ssh_login_profile $source $root_home/.profile exit 0
Save the file and execute the command:
chmod 755 'etc/initramfs-tools/hooks/cryptroot-unlock.sh'
Step 10 - Chroot into the target system, install packages and configure
Now chroot into the encrypted system. All remaining steps will be performed inside the chroot:
# chroot .
Install the cryptsetup package and the dropbear SSH server:
# apt update # echo 'force-confdef' > /root/.dpkg.cfg # apt --yes install cryptsetup-initramfs dropbear-initramfs # for a buster or focal image # apt --yes install cryptsetup dropbear-initramfs # for a bionic image # rm /root/.dpkg.cfg
Make sure everything was included in the initramfs (all three commands should produce output):
# lsinitramfs /boot/initrd.img-* | grep 'usr.*cryptsetup' # lsinitramfs /boot/initrd.img-* | grep dropbear # lsinitramfs /boot/initrd.img-* | grep authorized_keys
Now regenerate your SSH host keys:
# ssh-keygen -A
Your work is finished! Exit the chroot and shut down the board:
# exit # halt -p
Insert your freshly written SD card into the board’s main SD slot (or, if the target is an eMMC, just remove the SD card from that slot) and reboot.
Unlock the disk by executing the following command on your remote unlocking machine, substituting the correct IP address if necessary:
$ ssh -p 2222 root@192.168.0.88
If you performed step 9.10 above, the disk password prompt should appear automatically after login. If not, you must enter the command 'cryptroot-unlock'.
You may also unlock the disk from the target board’s console if you wish. Note, however, that certain disk images (RockPi 4 buster mainline, for example) might give you a blank display at startup, so you’ll have to enter your disk password “blindly”. This bug will hopefully be fixed in the future.
If all went well, your root-filesystem encrypted Armbian system is now up and running!
-
MMGen got a reaction from Bagel in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
Full root filesystem encryption on an Armbian system
(new, fully rewritten, replaces my earlier tutorial on this topic)
MMGen (https://github.com/mmgen)
This tutorial provides detailed, step-by-step instructions for setting up full root filesystem encryption on an Armbian system. The disk can be unlocked remotely via SSH or the serial console, permitting unattended bootup.
An automated script that performs the same steps, saving you much time and effort, can be found at https://github.com/mmgen/mmgen-geek-tools
Note that unlike my earlier tutorial all steps are performed within a running Armbian system.
The tutorial is known to work with the following board/image combinations:
Orange Pi PC2 Debian Buster mainline / Ubuntu Bionic and Focal legacy RockPi 4 Debian Buster mainline / Ubuntu Bionic and Focal legacy RockPro 64 Ubuntu Focal mainline Odroid HC4 Debian Buster mainline / Ubuntu Focal mainline
You may have success with other boards/images too. If so, please post the details below (or open an issue in the mmgen-geek-tools Github repository), and I’ll add your board to the list.
Requirements:
A SoC with a running, upgradeable and Internet-connected Armbian system A blank Micro-SD card and USB card reader, or, alternatively, an eMMC installed on the board The ability to edit text files and do simple administrative tasks on the Linux command line
Step 1 - Preliminaries
All steps in this tutorial are performed as root user on a running Armbian system (the “host”).
The encrypted system (the “target”) will be created on a blank micro-SD card (the “target device”).
If the board has an eMMC, it may be used as the target device instead of an SD card. Depending on your platform, you may need to run “armbian-config” and select “Install to internal storage” -> “Install/Update the bootloader on eMMC” to enable booting from the eMMC.
Architecture of host and target (e.g. 64-bit or 32-bit ARM) must be the same.
For best results, the host and target hardware should also be identical or similar. Building on a host with more memory than the target, for example, may lead to disk unlocking failure on the target.
If you’re building the target system for the currently running board and with the currently running image, which is the recommended approach, the two preceding points will be a non-issue.
Packages will be installed using APT, so the host machine must be Internet-connected and its clock correctly set.
Step 2 - Upgrade your system and install the cryptsetup package
# apt update && apt upgrade # apt install cryptsetup
Step 3 - Get and unpack the latest Armbian image for your board
Create your build directory:
# mkdir armbenc-build && cd armbenc-build
Download the Armbian image of your choice for your board, place it in this directory and unpack:
# xz -dv *.img.xz
Step 4 - Create mount directories and set up the loop mount
Create the mount directories:
# mkdir -p mnt boot root
Determine your first free loop device:
# losetup -f
Associate the image file with the loop device name displayed by the previous command. This will be '/dev/loop0' in most cases, but if your output was different, substitute that for '/dev/loop0' in the following steps.
# losetup -P /dev/loop0 *.img
Examine the disk image using fdisk on the loop device:
# fdisk -l /dev/loop0
The output should look something like this:
Device Boot Start End Sectors Size Id Type /dev/loop0p1 32768 3489791 3457024 1.7G 83 Linux
Make a note of the start sector (32768 in this case). You’ll need this value in the steps below.
Now mount the loop device:
# mount /dev/loop0p1 mnt
Step 5 - Copy the boot loader to the target device
If applicable, insert a blank micro-SD card and card reader into a USB port.
Determine the target device name using 'dmesg' or 'lsblk'. We’ll assume it to be '/dev/sda', since that’s the most likely case. If your device name is different, substitute it for '/dev/sda' in the the following steps. For an eMMC, the device name will be something like '/dev/mmcblk1'.
WARNING: if '/dev/sda' refers to some other storage device, running the following commands unchanged will destroy data on that device, so always remember to substitute the correct device name!!! The best way to eliminate this danger is to disconnect all unused storage devices on the board before proceeding further.
Copy the image’s boot loader to the target device, using the Start sector value from Step 4 as the argument for 'count':
# dd if=$(echo *.img) of=/dev/sda bs=512 count=32768
Step 6 - Partition the target device
# fdisk /dev/sda
At the fdisk prompt, create a new DOS disk label with the 'o' command. Use the 'n' command to create a primary partition of size +200M beginning at the same Start sector as the disk image. Type 'p' to view the partition table, which should now look something like this:
Device Boot Start End Sectors Size Id Type /dev/sda1 32768 442367 409600 200M 83 Linux
Use 'n' again to create another primary partition beginning one sector after the first partition’s end sector and filling the remainder of the card. Type 'p' once more to view the partition table:
Device Boot Start End Sectors Size Id Type /dev/sda1 32768 442367 409600 200M 83 Linux /dev/sda2 442368 30636031 30193664 14.4G 83 Linux
Ensure that the first partition’s Start sector matches that of the disk image (32768 in this example) and that the second partition’s Start sector is one greater than the End sector of the first (442368 and 442367, respectively, in this example). If you’ve made a mistake, use 'd' to delete a partition and start again.
Once everything looks correct, type 'w' to write the partition table to disk.
Step 7 - Copy the system to the target device
The following commands will create a filesystem on the target device’s boot partition and copy the boot partition data from the image file to it. Don’t forget to substitute the correct device name if necessary. If you’re building the system on an eMMC, the boot partition device will be something like '/dev/mmcblk1p1' instead of '/dev/sda1'.
# mkfs.ext4 /dev/sda1 # or '/dev/mmcblk1p1', for an eMMC target # e2label /dev/sda1 CRYPTO_BOOT # mount /dev/sda1 boot # cp -av mnt/boot/* boot # (cd boot; ln -s . boot)
Create the encrypted root partition. When prompted for a passphrase, it’s advisable to choose an easy one like 'abc' for now. The passphrase can be changed later with the 'cryptsetup luksChangeKey' command (type 'man cryptsetup' for details) once your encrypted system is up and running.
# cryptsetup luksFormat /dev/sda2 # or '/dev/mmcblk1p2', for an eMMC target
Activate the encrypted root partition and create a filesystem on it:
# cryptsetup luksOpen /dev/sda2 rootfs # enter your passphrase from above # mkfs.ext4 /dev/mapper/rootfs
Mount the encrypted root partition and copy the system to it:
# mount /dev/mapper/rootfs root # (cd mnt && rsync -a --info=progress2 --exclude=boot * ../root) # sync # be patient, this could take a while # mkdir root/boot # touch root/root/.no_rootfs_resize
Unmount the boot partition and image and free the loop device:
# umount mnt boot # losetup -d /dev/loop0
Step 8 - Prepare the target system chroot
# BOOT_PART=($(lsblk -l -o NAME,LABEL | grep CRYPTO_BOOT)) # ROOT_PART=${BOOT_PART%1}2 # ROOT_UUID="$(lsblk --nodeps --noheadings --output=UUID /dev/$ROOT_PART)" # BOOT_UUID="$(lsblk --noheadings --output=UUID /dev/$BOOT_PART)" # cd root # mount /dev/$BOOT_PART boot # mount -o rbind /dev dev # mount -t proc proc proc # mount -t sysfs sys sys
Copy '/etc/resolv.conf' and '/etc/hosts' so you’ll have a working Internet connection within the chroot:
# cat /etc/resolv.conf > etc/resolv.conf # cat /etc/hosts > etc/hosts
If you’re using non-default APT repositories, you may need to copy their configuration files as well so that 'apt update' and 'apt install' will use them inside the chroot. Note that you can only do this if the host and target systems have the same distro/version. If that’s not the case, you’ll have to edit the target files by hand.
# cat /etc/apt/sources.list > etc/apt/sources.list # cat /etc/apt/sources.list.d/armbian.list > etc/apt/sources.list.d/armbian.list
If you’re using an apt proxy, then copy its configuration file too:
# cp /etc/apt/apt.conf.d/*proxy etc/apt/apt.conf.d/
Step 9 - Edit or create required configuration files in the target system
Perform the editing steps below using a text editor of your choice:
If the file 'boot/armbianEnv.txt' exists, edit it so that the 'rootdev', 'console' and 'bootlogo' lines read as follows. If you’ll be unlocking the disk via the serial console, then use 'console=serial' instead of 'console=display'. Note that enabling the serial console will make it impossible to unlock the disk from the keyboard and monitor, though unlocking via SSH will still work:
rootdev=/dev/mapper/rootfs console=display bootlogo=false If your image lacks an 'armbianEnv.txt' file, you’ll need to edit the file 'boot/extlinux/extlinux.conf' instead. All changes will be made to the line beginning with “append”. Alter the argument beginning with “root=” so that it reads “root=/dev/mapper/rootfs”. If you’ll be unlocking the disk via the serial console, remove the “console=tty1” argument. If not, remove the argument beginning with “console=ttyS...”. Replace the “splash plymouth...” argument with “splash=verbose”. Make sure to read the note about unlocking via serial console in the previous step.
Edit 'etc/initramfs-tools/initramfs.conf'. If your board will have a statically configured IP, add the following line to the end of the file, substituting the correct IP in place of 192.168.0.88:
IP=192.168.0.88:::255.255.255.0::end0:off If the board will be configured via DHCP, then edit the DEVICE line as follows:
DEVICE=end0 If your default network device is eth0, use that instead of end0.
If host and target systems are both Debian buster, you may wish add some key modules to the initramfs to avoid a blank display at bootup time. The easiest way to do this is to add all currently loaded modules as follows: # lsmod | cut -d ' ' -f1 | tail -n+2 > etc/initramfs-tools/modules Retrieve the SSH public key from the remote unlocking host and copy it to the target:
# mkdir -p etc/dropbear/initramfs # rsync yourusername@remote_machine:.ssh/id_*.pub etc/dropbear/initramfs/authorized_keys If you want to unlock the disk from more than one host, then edit the authorized_keys file by hand, adding the required additional keys.
Create 'etc/crypttab':
# echo "rootfs UUID=$ROOT_UUID none initramfs,luks" > etc/crypttab Create 'etc/fstab':
# echo '/dev/mapper/rootfs / ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 1' > etc/fstab # echo "UUID=$BOOT_UUID /boot ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 2" >> etc/fstab # echo 'tmpfs /tmp tmpfs defaults,nosuid 0 0' >> etc/fstab Create the dropbear configuration file:
# echo 'DROPBEAR_OPTIONS="-p 2222"' > etc/dropbear/initramfs/dropbear.conf # echo 'DROPBEAR=y' >> etc/dropbear/initramfs/dropbear.conf
If the target is Ubuntu bionic, then a deprecated environment variable must be set as follows:
# echo 'export CRYPTSETUP=y' > etc/initramfs-tools/conf.d/cryptsetup
Set up automatic disk unlock prompt. Performing this optional step will cause the disk password prompt to appear automatically when you log in remotely via SSH to unlock the disk. Using your text editor, create the file 'etc/initramfs-tools/hooks/cryptroot-unlock.sh' with the following contents: #!/bin/sh if [ "$1" = 'prereqs' ]; then echo 'dropbear-initramfs'; exit 0; fi . /usr/share/initramfs-tools/hook-functions source='/tmp/cryptroot-unlock-profile' root_home=$(echo $DESTDIR/root-*) root_home=${root_home#$DESTDIR} echo 'if [ "$SSH_CLIENT" ]; then /usr/bin/cryptroot-unlock; fi' > $source copy_file ssh_login_profile $source $root_home/.profile exit 0
Save the file and execute the command:
chmod 755 'etc/initramfs-tools/hooks/cryptroot-unlock.sh'
Step 10 - Chroot into the target system, install packages and configure
Now chroot into the encrypted system. All remaining steps will be performed inside the chroot:
# chroot .
Install the cryptsetup package and the dropbear SSH server:
# apt update # echo 'force-confdef' > /root/.dpkg.cfg # apt --yes install cryptsetup-initramfs dropbear-initramfs # for a buster or focal image # apt --yes install cryptsetup dropbear-initramfs # for a bionic image # rm /root/.dpkg.cfg
Make sure everything was included in the initramfs (all three commands should produce output):
# lsinitramfs /boot/initrd.img-* | grep 'usr.*cryptsetup' # lsinitramfs /boot/initrd.img-* | grep dropbear # lsinitramfs /boot/initrd.img-* | grep authorized_keys
Now regenerate your SSH host keys:
# ssh-keygen -A
Your work is finished! Exit the chroot and shut down the board:
# exit # halt -p
Insert your freshly written SD card into the board’s main SD slot (or, if the target is an eMMC, just remove the SD card from that slot) and reboot.
Unlock the disk by executing the following command on your remote unlocking machine, substituting the correct IP address if necessary:
$ ssh -p 2222 root@192.168.0.88
If you performed step 9.10 above, the disk password prompt should appear automatically after login. If not, you must enter the command 'cryptroot-unlock'.
You may also unlock the disk from the target board’s console if you wish. Note, however, that certain disk images (RockPi 4 buster mainline, for example) might give you a blank display at startup, so you’ll have to enter your disk password “blindly”. This bug will hopefully be fixed in the future.
If all went well, your root-filesystem encrypted Armbian system is now up and running!
-
MMGen got a reaction from Werner in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
Add serial console disk unlocking instructions at step 9.1. Serial console disk unlocking has been added as an option to the automated script as well.
-
MMGen got a reaction from legogris in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
No, I wouldn't assume that. See the comments by @sunzone above regarding the Orange Pi Zero.
In their case, the problem may be connected with the fact that the OPi Zero requires 'flash-kernel' to set up the boot loader.
I think that boards/images that don't depend on flash-kernel should generally work with this tutorial, but I need more test data to confirm that hypothesis.
-
MMGen reacted to Werner in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
I added a link to this topic to the build options.
-
MMGen got a reaction from Igor in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
Full root filesystem encryption on an Armbian system
(new, fully rewritten, replaces my earlier tutorial on this topic)
MMGen (https://github.com/mmgen)
This tutorial provides detailed, step-by-step instructions for setting up full root filesystem encryption on an Armbian system. The disk can be unlocked remotely via SSH or the serial console, permitting unattended bootup.
An automated script that performs the same steps, saving you much time and effort, can be found at https://github.com/mmgen/mmgen-geek-tools
Note that unlike my earlier tutorial all steps are performed within a running Armbian system.
The tutorial is known to work with the following board/image combinations:
Orange Pi PC2 Debian Buster mainline / Ubuntu Bionic and Focal legacy RockPi 4 Debian Buster mainline / Ubuntu Bionic and Focal legacy RockPro 64 Ubuntu Focal mainline Odroid HC4 Debian Buster mainline / Ubuntu Focal mainline
You may have success with other boards/images too. If so, please post the details below (or open an issue in the mmgen-geek-tools Github repository), and I’ll add your board to the list.
Requirements:
A SoC with a running, upgradeable and Internet-connected Armbian system A blank Micro-SD card and USB card reader, or, alternatively, an eMMC installed on the board The ability to edit text files and do simple administrative tasks on the Linux command line
Step 1 - Preliminaries
All steps in this tutorial are performed as root user on a running Armbian system (the “host”).
The encrypted system (the “target”) will be created on a blank micro-SD card (the “target device”).
If the board has an eMMC, it may be used as the target device instead of an SD card. Depending on your platform, you may need to run “armbian-config” and select “Install to internal storage” -> “Install/Update the bootloader on eMMC” to enable booting from the eMMC.
Architecture of host and target (e.g. 64-bit or 32-bit ARM) must be the same.
For best results, the host and target hardware should also be identical or similar. Building on a host with more memory than the target, for example, may lead to disk unlocking failure on the target.
If you’re building the target system for the currently running board and with the currently running image, which is the recommended approach, the two preceding points will be a non-issue.
Packages will be installed using APT, so the host machine must be Internet-connected and its clock correctly set.
Step 2 - Upgrade your system and install the cryptsetup package
# apt update && apt upgrade # apt install cryptsetup
Step 3 - Get and unpack the latest Armbian image for your board
Create your build directory:
# mkdir armbenc-build && cd armbenc-build
Download the Armbian image of your choice for your board, place it in this directory and unpack:
# xz -dv *.img.xz
Step 4 - Create mount directories and set up the loop mount
Create the mount directories:
# mkdir -p mnt boot root
Determine your first free loop device:
# losetup -f
Associate the image file with the loop device name displayed by the previous command. This will be '/dev/loop0' in most cases, but if your output was different, substitute that for '/dev/loop0' in the following steps.
# losetup -P /dev/loop0 *.img
Examine the disk image using fdisk on the loop device:
# fdisk -l /dev/loop0
The output should look something like this:
Device Boot Start End Sectors Size Id Type /dev/loop0p1 32768 3489791 3457024 1.7G 83 Linux
Make a note of the start sector (32768 in this case). You’ll need this value in the steps below.
Now mount the loop device:
# mount /dev/loop0p1 mnt
Step 5 - Copy the boot loader to the target device
If applicable, insert a blank micro-SD card and card reader into a USB port.
Determine the target device name using 'dmesg' or 'lsblk'. We’ll assume it to be '/dev/sda', since that’s the most likely case. If your device name is different, substitute it for '/dev/sda' in the the following steps. For an eMMC, the device name will be something like '/dev/mmcblk1'.
WARNING: if '/dev/sda' refers to some other storage device, running the following commands unchanged will destroy data on that device, so always remember to substitute the correct device name!!! The best way to eliminate this danger is to disconnect all unused storage devices on the board before proceeding further.
Copy the image’s boot loader to the target device, using the Start sector value from Step 4 as the argument for 'count':
# dd if=$(echo *.img) of=/dev/sda bs=512 count=32768
Step 6 - Partition the target device
# fdisk /dev/sda
At the fdisk prompt, create a new DOS disk label with the 'o' command. Use the 'n' command to create a primary partition of size +200M beginning at the same Start sector as the disk image. Type 'p' to view the partition table, which should now look something like this:
Device Boot Start End Sectors Size Id Type /dev/sda1 32768 442367 409600 200M 83 Linux
Use 'n' again to create another primary partition beginning one sector after the first partition’s end sector and filling the remainder of the card. Type 'p' once more to view the partition table:
Device Boot Start End Sectors Size Id Type /dev/sda1 32768 442367 409600 200M 83 Linux /dev/sda2 442368 30636031 30193664 14.4G 83 Linux
Ensure that the first partition’s Start sector matches that of the disk image (32768 in this example) and that the second partition’s Start sector is one greater than the End sector of the first (442368 and 442367, respectively, in this example). If you’ve made a mistake, use 'd' to delete a partition and start again.
Once everything looks correct, type 'w' to write the partition table to disk.
Step 7 - Copy the system to the target device
The following commands will create a filesystem on the target device’s boot partition and copy the boot partition data from the image file to it. Don’t forget to substitute the correct device name if necessary. If you’re building the system on an eMMC, the boot partition device will be something like '/dev/mmcblk1p1' instead of '/dev/sda1'.
# mkfs.ext4 /dev/sda1 # or '/dev/mmcblk1p1', for an eMMC target # e2label /dev/sda1 CRYPTO_BOOT # mount /dev/sda1 boot # cp -av mnt/boot/* boot # (cd boot; ln -s . boot)
Create the encrypted root partition. When prompted for a passphrase, it’s advisable to choose an easy one like 'abc' for now. The passphrase can be changed later with the 'cryptsetup luksChangeKey' command (type 'man cryptsetup' for details) once your encrypted system is up and running.
# cryptsetup luksFormat /dev/sda2 # or '/dev/mmcblk1p2', for an eMMC target
Activate the encrypted root partition and create a filesystem on it:
# cryptsetup luksOpen /dev/sda2 rootfs # enter your passphrase from above # mkfs.ext4 /dev/mapper/rootfs
Mount the encrypted root partition and copy the system to it:
# mount /dev/mapper/rootfs root # (cd mnt && rsync -a --info=progress2 --exclude=boot * ../root) # sync # be patient, this could take a while # mkdir root/boot # touch root/root/.no_rootfs_resize
Unmount the boot partition and image and free the loop device:
# umount mnt boot # losetup -d /dev/loop0
Step 8 - Prepare the target system chroot
# BOOT_PART=($(lsblk -l -o NAME,LABEL | grep CRYPTO_BOOT)) # ROOT_PART=${BOOT_PART%1}2 # ROOT_UUID="$(lsblk --nodeps --noheadings --output=UUID /dev/$ROOT_PART)" # BOOT_UUID="$(lsblk --noheadings --output=UUID /dev/$BOOT_PART)" # cd root # mount /dev/$BOOT_PART boot # mount -o rbind /dev dev # mount -t proc proc proc # mount -t sysfs sys sys
Copy '/etc/resolv.conf' and '/etc/hosts' so you’ll have a working Internet connection within the chroot:
# cat /etc/resolv.conf > etc/resolv.conf # cat /etc/hosts > etc/hosts
If you’re using non-default APT repositories, you may need to copy their configuration files as well so that 'apt update' and 'apt install' will use them inside the chroot. Note that you can only do this if the host and target systems have the same distro/version. If that’s not the case, you’ll have to edit the target files by hand.
# cat /etc/apt/sources.list > etc/apt/sources.list # cat /etc/apt/sources.list.d/armbian.list > etc/apt/sources.list.d/armbian.list
If you’re using an apt proxy, then copy its configuration file too:
# cp /etc/apt/apt.conf.d/*proxy etc/apt/apt.conf.d/
Step 9 - Edit or create required configuration files in the target system
Perform the editing steps below using a text editor of your choice:
If the file 'boot/armbianEnv.txt' exists, edit it so that the 'rootdev', 'console' and 'bootlogo' lines read as follows. If you’ll be unlocking the disk via the serial console, then use 'console=serial' instead of 'console=display'. Note that enabling the serial console will make it impossible to unlock the disk from the keyboard and monitor, though unlocking via SSH will still work:
rootdev=/dev/mapper/rootfs console=display bootlogo=false If your image lacks an 'armbianEnv.txt' file, you’ll need to edit the file 'boot/extlinux/extlinux.conf' instead. All changes will be made to the line beginning with “append”. Alter the argument beginning with “root=” so that it reads “root=/dev/mapper/rootfs”. If you’ll be unlocking the disk via the serial console, remove the “console=tty1” argument. If not, remove the argument beginning with “console=ttyS...”. Replace the “splash plymouth...” argument with “splash=verbose”. Make sure to read the note about unlocking via serial console in the previous step.
Edit 'etc/initramfs-tools/initramfs.conf'. If your board will have a statically configured IP, add the following line to the end of the file, substituting the correct IP in place of 192.168.0.88:
IP=192.168.0.88:::255.255.255.0::end0:off If the board will be configured via DHCP, then edit the DEVICE line as follows:
DEVICE=end0 If your default network device is eth0, use that instead of end0.
If host and target systems are both Debian buster, you may wish add some key modules to the initramfs to avoid a blank display at bootup time. The easiest way to do this is to add all currently loaded modules as follows: # lsmod | cut -d ' ' -f1 | tail -n+2 > etc/initramfs-tools/modules Retrieve the SSH public key from the remote unlocking host and copy it to the target:
# mkdir -p etc/dropbear/initramfs # rsync yourusername@remote_machine:.ssh/id_*.pub etc/dropbear/initramfs/authorized_keys If you want to unlock the disk from more than one host, then edit the authorized_keys file by hand, adding the required additional keys.
Create 'etc/crypttab':
# echo "rootfs UUID=$ROOT_UUID none initramfs,luks" > etc/crypttab Create 'etc/fstab':
# echo '/dev/mapper/rootfs / ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 1' > etc/fstab # echo "UUID=$BOOT_UUID /boot ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 2" >> etc/fstab # echo 'tmpfs /tmp tmpfs defaults,nosuid 0 0' >> etc/fstab Create the dropbear configuration file:
# echo 'DROPBEAR_OPTIONS="-p 2222"' > etc/dropbear/initramfs/dropbear.conf # echo 'DROPBEAR=y' >> etc/dropbear/initramfs/dropbear.conf
If the target is Ubuntu bionic, then a deprecated environment variable must be set as follows:
# echo 'export CRYPTSETUP=y' > etc/initramfs-tools/conf.d/cryptsetup
Set up automatic disk unlock prompt. Performing this optional step will cause the disk password prompt to appear automatically when you log in remotely via SSH to unlock the disk. Using your text editor, create the file 'etc/initramfs-tools/hooks/cryptroot-unlock.sh' with the following contents: #!/bin/sh if [ "$1" = 'prereqs' ]; then echo 'dropbear-initramfs'; exit 0; fi . /usr/share/initramfs-tools/hook-functions source='/tmp/cryptroot-unlock-profile' root_home=$(echo $DESTDIR/root-*) root_home=${root_home#$DESTDIR} echo 'if [ "$SSH_CLIENT" ]; then /usr/bin/cryptroot-unlock; fi' > $source copy_file ssh_login_profile $source $root_home/.profile exit 0
Save the file and execute the command:
chmod 755 'etc/initramfs-tools/hooks/cryptroot-unlock.sh'
Step 10 - Chroot into the target system, install packages and configure
Now chroot into the encrypted system. All remaining steps will be performed inside the chroot:
# chroot .
Install the cryptsetup package and the dropbear SSH server:
# apt update # echo 'force-confdef' > /root/.dpkg.cfg # apt --yes install cryptsetup-initramfs dropbear-initramfs # for a buster or focal image # apt --yes install cryptsetup dropbear-initramfs # for a bionic image # rm /root/.dpkg.cfg
Make sure everything was included in the initramfs (all three commands should produce output):
# lsinitramfs /boot/initrd.img-* | grep 'usr.*cryptsetup' # lsinitramfs /boot/initrd.img-* | grep dropbear # lsinitramfs /boot/initrd.img-* | grep authorized_keys
Now regenerate your SSH host keys:
# ssh-keygen -A
Your work is finished! Exit the chroot and shut down the board:
# exit # halt -p
Insert your freshly written SD card into the board’s main SD slot (or, if the target is an eMMC, just remove the SD card from that slot) and reboot.
Unlock the disk by executing the following command on your remote unlocking machine, substituting the correct IP address if necessary:
$ ssh -p 2222 root@192.168.0.88
If you performed step 9.10 above, the disk password prompt should appear automatically after login. If not, you must enter the command 'cryptroot-unlock'.
You may also unlock the disk from the target board’s console if you wish. Note, however, that certain disk images (RockPi 4 buster mainline, for example) might give you a blank display at startup, so you’ll have to enter your disk password “blindly”. This bug will hopefully be fixed in the future.
If all went well, your root-filesystem encrypted Armbian system is now up and running!
-
MMGen reacted to sunzone in Full root filesystem encryption on an Armbian system (NEW, replaces 2017 tutorial on this topic)
I will look into that.
Thanks.
Edit: building Armbian with the CRYPTROOT_ENABLE option works
-
MMGen got a reaction from Werner in Full root filesystem encryption on an Armbian/Orange Pi PC 2 system
Fixed boot sector size, luksFormat command. Removed outdated image downloading and unpacking instructions.
Tested on SD and eMMC; Orange Pi PC2 and RockPi 4; Bionic legacy, Focal legacy and Buster mainline images.
Instead of this tutorial, users are now encouraged to use my automated script, which does things in a better, more up-to-date way:
git clone https://github.com/mmgen/mmgen-geek-tools
-
MMGen got a reaction from tkaiser in Full root filesystem encryption on an Armbian/Orange Pi PC 2 system
Revised and re-tested tutorial with current Armbian OPi PC2 images, removed unneeded kernel compilation section.
-
MMGen got a reaction from StuxNet in Full root filesystem encryption on an Armbian/Orange Pi PC 2 system
Update: commenting out the following line in 'boot.cmd' allows you to unlock the disk from the tty as well as via ssh:
# if test "${console}" = "serial" || test "${console}" = "both"; then setenv consoleargs "${consoleargs} console=ttyS0,115200"; fi
-
MMGen got a reaction from StuxNet in Full root filesystem encryption on an Armbian/Orange Pi PC 2 system
Rechecked tutorial, fixed a non-critical error, removed a couple unnecessary commands.
Just replace the bogus device filenames with real ones and everything will work "out of the box".
-
MMGen got a reaction from StuxNet in Full root filesystem encryption on an Armbian/Orange Pi PC 2 system
Full root filesystem encryption on an Armbian/Orange Pi PC 2 system
MMGen (https://github.com/mmgen)
WARNING: This tutorial has been obsoleted by Full root filesystem encryption on an Armbian system. In addition, an automated script is available, which can be downloaded here or by cloning the following repository: git clone https://github.com/mmgen/mmgen-geek-tools
This tutorial provides detailed, step-by-step instructions for setting up full root filesystem encryption on an Armbian/Orange Pi PC2 system. With minor changes, it can be adapted to other Armbian-supported boards. The disk is unlocked remotely via ssh, permitting unattended bootup.
Requirements:
Linux host system One Orange Pi PC 2 Two blank Micro-SD cards (or a working Armbian system for your board + one blank SD card) USB Micro-SD card reader Ability to edit text files and do simple administrative tasks on the Linux command line
Part 1 - Get, unpack and copy an Armbian image for your board
Create your build directory:
$ mkdir armbenc-build && cd armbenc-build Download and unpack an Armbian image for your board and place it in this directory.
If you have two blank SD cards, the first will hold an ordinary unencrypted Armbian system used for the setup process, while the second will hold the target encrypted system.
Alternatively, if you already have a working Armbian system for your board, you can use it for the setup process. In that case, your one blank SD card will be considered the “second” card, and you can ignore all instructions hereafter pertaining to the first card.
Note that for the remainder of this section, the first SD card will be referred to as '/dev/sdX' and the second as '/dev/sdY'. You'll replace these with the SD cards' true device filenames. The device names can be discovered using the command 'dmesg' or 'lsblk'. If you remove the first card before inserting the second, it's possible (but not guaranteed) that the cards will have the same device name.
Insert the first blank SD card and copy the image to it:
$ sudo dd if=$(echo *.img) of=/dev/sdX bs=4M After the command exits, you may remove the first card.
Now insert the second SD card, which will hold a small unencrypted boot partition plus your encrypted Armbian system. Copy the image's boot loader to it:
$ sudo dd if=$(echo *.img) of=/dev/sdY bs=512 count=32768 Now partition the card:
$ sudo fdisk /dev/sdY Within fdisk, create a new DOS disklabel with the 'o' command. Use the 'n' command to create a primary partition of size +200M beginning at sector 32768. Type 'p' to view the partition table. Note the end sector. Now create a second primary partition beginning one sector after the first partition's end sector and filling the remainder of the card. When you're finished, your partition table will look something like this:
Device Boot Start End Sectors Size Id Type /dev/sdY1 32768 442367 409600 200M 83 Linux /dev/sdY2 442368 123596799 123154432 58.7G 83 Linux Double-check that the second partition begins one sector after the end of the first one. If you mess something up, use 'd' to delete partitions or 'q' to exit fdisk and try again.
Once everything looks correct, type 'w' to write the partition table.
Now you'll begin the process of copying the system to the second card. First you'll associate the image file with a loop device and mount the device:
$ losetup -f # displays the name of the loop device; remember this $ sudo losetup -Pf *.img # associate image file with the above loop device $ mkdir mnt boot root $ sudo mount /dev/loopXp1 mnt # replace '/dev/loopX' with the above loop device Create a filesystem on the SD card's boot partition and copy the boot partition data from the image file to it:
$ sudo mkfs.ext4 /dev/sdY1 $ sudo e2label /dev/sdY1 OPI_PC2_BOOT # don't omit this step! $ sudo mount /dev/sdY1 boot $ sudo cp -av mnt/boot/* boot $ (cd boot; sudo ln -s . boot) Create the encrypted root partition (for this the 'cryptsetup-bin' package must be installed on the host). You'll be prompted for a passphrase. It's recommended to choose an easy one like 'abc' for now. The passphrase can easily be changed later (consult the 'cryptsetup' man page for details):
$ sudo cryptsetup --pbkdf argon2i --pbkdf-memory 600000 luksFormat /dev/sdY2 Note that the --pbkdf-memory argument must be less than the available free memory in kilobytes at bootup time. Otherwise you’ll get an out-of-memory error and your disk will fail to unlock. 600000 is a safe value for the Orange Pi PC2 with its 1GB of RAM.
Activate the encrypted root partition, create a filesystem on it and mount it:
$ sudo cryptsetup luksOpen /dev/sdY2 foo # enter your passphrase from above $ sudo mkfs.ext4 /dev/mapper/foo $ sudo mount /dev/mapper/foo root Copy the system to the encrypted root partition:
$ (cd mnt && sudo rsync -av --exclude=boot * ../root) $ sync # be patient, this could take a while $ sudo mkdir root/boot $ sudo touch root/root/.no_rootfs_resize Unmount the mounted image and second SD card, and free the loop device and encrypted mapping:
$ sudo umount mnt boot root $ sudo losetup -d /dev/loopX $ sudo cryptsetup luksClose foo From here on, all your work will be done on the Orange Pi.
Part 2 - boot into the unencrypted Armbian system
If applicable, insert the first (unencrypted) SD card into the Pi's Micro-SD card slot.
Insert a USB card reader holding the second SD card into a USB port on the Pi.
Boot the Pi.
If applicable, log in as root with password '1234', follow the password update instructions, and stay logged in as root. The following steps will be performed from a root shell.
Part 3 - set up the unencrypted Armbian system
Update the APT package index and install cryptsetup:
# apt-get update # apt-get install cryptsetup
Part 4 - set up the encrypted Armbian system
Prepare the encrypted system chroot:
# BOOT_PART=($(lsblk -l -o NAME,LABEL | grep OPI_PC2_BOOT)) # ROOT_PART=${BOOT_PART%1}2 # cryptsetup luksOpen /dev/$ROOT_PART foo # mkdir /mnt/enc_root # mount /dev/mapper/foo /mnt/enc_root # mount /dev/$BOOT_PART /mnt/enc_root/boot # cd /mnt/enc_root # mount -o rbind /dev dev # mount -t proc proc proc # mount -t sysfs sys sys Copy some key files so you'll have a working Internet connection within the chroot:
# cat /etc/resolv.conf > etc/resolv.conf # cat /etc/hosts > etc/hosts Now chroot into the encrypted system. From this point on, all work will be done inside the chroot:
# chroot . # apt-get update # echo 'export CRYPTSETUP=y' > /etc/initramfs-tools/conf.d/cryptsetup # apt-get install cryptsetup-initramfs dropbear-initramfs # for focal and buster # apt-get install cryptsetup dropbear-initramfs # for bionic Check to see that the cryptsetup scripts are present in the initramfs (command should produce output):
# gunzip -c /boot/initrd.img* | cpio --quiet -t | grep cryptsetup Edit '/etc/fstab' to look exactly like this:
/dev/mapper/rootfs / ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 1 /dev/mmcblk0p1 /boot ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 2 tmpfs /tmp tmpfs defaults,nosuid 0 0 Add the following lines to '/etc/initramfs-tools/initramfs.conf'. If the Orange Pi's IP address will be statically configured, substitute the correct static IP address after 'IP='. If it will be configured via DHCP, omit the IP line entirely:
DEVICE=eth0 IP=192.168.0.88:::255.255.255.0::eth0:off Add the following parameters to the quoted bootargs line in '/boot/boot.cmd'. Note that the 'root' parameter replaces the existing one:
root=/dev/mapper/rootfs cryptopts=source=/dev/mmcblk0p2,target=rootfs If you want to be able to unlock the disk from the virtual console (which you probably do) as well as via ssh, then comment out the following line:
# if test "${console}" = "serial" || test "${console}" = "both"; then setenv consoleargs "${consoleargs} console=ttyS0,115200"; fi In case you're wondering, 'setenv console "display"' doesn't work. Don't ask me why.
Compile the boot menu:
# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr Copy the SSH public key from the machine you'll be unlocking the disk from to the Armbian machine:
# rsync yourusername@remote_machine:.ssh/id_*.pub /etc/dropbear-initramfs/authorized_keys If you'll be unlocking the disk from more than one host, then edit the authorized_keys file by hand and add the additional SSH public keys.
Edit '/etc/dropbear-initramfs/config', adding the following lines:
DROPBEAR_OPTIONS="-p 2222" DROPBEAR=y Reconfigure dropbear:
# dpkg-reconfigure dropbear-initramfs Make sure everything was included in the initramfs (both commands should produce output):
# gunzip -c /boot/initrd.img* | cpio --quiet -t | grep dropbear # gunzip -c /boot/initrd.img* | cpio --quiet -t | grep authorized_keys Your work is finished! Exit the chroot and shut down the Orange Pi:
# exit # halt -p Swap the SD cards and restart the Pi. Unlock the disk by executing the following command on your remote machine. Substitute the Pi's correct static or DHCP-configured IP address for the one below. If necessary, also substitute the correct disk password in place of 'abc':
$ ssh -p 2222 -x root@192.168.0.88 'echo -n abc > /lib/cryptsetup/passfifo' If you choose to unlock the disk from the tty, just enter your disk password and hit ENTER.
If all went well, your root-filesystem encrypted Armbian system is now up and running!
-
MMGen got a reaction from gnasch in Full root filesystem encryption on an Armbian/Orange Pi PC 2 system
Full root filesystem encryption on an Armbian/Orange Pi PC 2 system
MMGen (https://github.com/mmgen)
WARNING: This tutorial has been obsoleted by Full root filesystem encryption on an Armbian system. In addition, an automated script is available, which can be downloaded here or by cloning the following repository: git clone https://github.com/mmgen/mmgen-geek-tools
This tutorial provides detailed, step-by-step instructions for setting up full root filesystem encryption on an Armbian/Orange Pi PC2 system. With minor changes, it can be adapted to other Armbian-supported boards. The disk is unlocked remotely via ssh, permitting unattended bootup.
Requirements:
Linux host system One Orange Pi PC 2 Two blank Micro-SD cards (or a working Armbian system for your board + one blank SD card) USB Micro-SD card reader Ability to edit text files and do simple administrative tasks on the Linux command line
Part 1 - Get, unpack and copy an Armbian image for your board
Create your build directory:
$ mkdir armbenc-build && cd armbenc-build Download and unpack an Armbian image for your board and place it in this directory.
If you have two blank SD cards, the first will hold an ordinary unencrypted Armbian system used for the setup process, while the second will hold the target encrypted system.
Alternatively, if you already have a working Armbian system for your board, you can use it for the setup process. In that case, your one blank SD card will be considered the “second” card, and you can ignore all instructions hereafter pertaining to the first card.
Note that for the remainder of this section, the first SD card will be referred to as '/dev/sdX' and the second as '/dev/sdY'. You'll replace these with the SD cards' true device filenames. The device names can be discovered using the command 'dmesg' or 'lsblk'. If you remove the first card before inserting the second, it's possible (but not guaranteed) that the cards will have the same device name.
Insert the first blank SD card and copy the image to it:
$ sudo dd if=$(echo *.img) of=/dev/sdX bs=4M After the command exits, you may remove the first card.
Now insert the second SD card, which will hold a small unencrypted boot partition plus your encrypted Armbian system. Copy the image's boot loader to it:
$ sudo dd if=$(echo *.img) of=/dev/sdY bs=512 count=32768 Now partition the card:
$ sudo fdisk /dev/sdY Within fdisk, create a new DOS disklabel with the 'o' command. Use the 'n' command to create a primary partition of size +200M beginning at sector 32768. Type 'p' to view the partition table. Note the end sector. Now create a second primary partition beginning one sector after the first partition's end sector and filling the remainder of the card. When you're finished, your partition table will look something like this:
Device Boot Start End Sectors Size Id Type /dev/sdY1 32768 442367 409600 200M 83 Linux /dev/sdY2 442368 123596799 123154432 58.7G 83 Linux Double-check that the second partition begins one sector after the end of the first one. If you mess something up, use 'd' to delete partitions or 'q' to exit fdisk and try again.
Once everything looks correct, type 'w' to write the partition table.
Now you'll begin the process of copying the system to the second card. First you'll associate the image file with a loop device and mount the device:
$ losetup -f # displays the name of the loop device; remember this $ sudo losetup -Pf *.img # associate image file with the above loop device $ mkdir mnt boot root $ sudo mount /dev/loopXp1 mnt # replace '/dev/loopX' with the above loop device Create a filesystem on the SD card's boot partition and copy the boot partition data from the image file to it:
$ sudo mkfs.ext4 /dev/sdY1 $ sudo e2label /dev/sdY1 OPI_PC2_BOOT # don't omit this step! $ sudo mount /dev/sdY1 boot $ sudo cp -av mnt/boot/* boot $ (cd boot; sudo ln -s . boot) Create the encrypted root partition (for this the 'cryptsetup-bin' package must be installed on the host). You'll be prompted for a passphrase. It's recommended to choose an easy one like 'abc' for now. The passphrase can easily be changed later (consult the 'cryptsetup' man page for details):
$ sudo cryptsetup --pbkdf argon2i --pbkdf-memory 600000 luksFormat /dev/sdY2 Note that the --pbkdf-memory argument must be less than the available free memory in kilobytes at bootup time. Otherwise you’ll get an out-of-memory error and your disk will fail to unlock. 600000 is a safe value for the Orange Pi PC2 with its 1GB of RAM.
Activate the encrypted root partition, create a filesystem on it and mount it:
$ sudo cryptsetup luksOpen /dev/sdY2 foo # enter your passphrase from above $ sudo mkfs.ext4 /dev/mapper/foo $ sudo mount /dev/mapper/foo root Copy the system to the encrypted root partition:
$ (cd mnt && sudo rsync -av --exclude=boot * ../root) $ sync # be patient, this could take a while $ sudo mkdir root/boot $ sudo touch root/root/.no_rootfs_resize Unmount the mounted image and second SD card, and free the loop device and encrypted mapping:
$ sudo umount mnt boot root $ sudo losetup -d /dev/loopX $ sudo cryptsetup luksClose foo From here on, all your work will be done on the Orange Pi.
Part 2 - boot into the unencrypted Armbian system
If applicable, insert the first (unencrypted) SD card into the Pi's Micro-SD card slot.
Insert a USB card reader holding the second SD card into a USB port on the Pi.
Boot the Pi.
If applicable, log in as root with password '1234', follow the password update instructions, and stay logged in as root. The following steps will be performed from a root shell.
Part 3 - set up the unencrypted Armbian system
Update the APT package index and install cryptsetup:
# apt-get update # apt-get install cryptsetup
Part 4 - set up the encrypted Armbian system
Prepare the encrypted system chroot:
# BOOT_PART=($(lsblk -l -o NAME,LABEL | grep OPI_PC2_BOOT)) # ROOT_PART=${BOOT_PART%1}2 # cryptsetup luksOpen /dev/$ROOT_PART foo # mkdir /mnt/enc_root # mount /dev/mapper/foo /mnt/enc_root # mount /dev/$BOOT_PART /mnt/enc_root/boot # cd /mnt/enc_root # mount -o rbind /dev dev # mount -t proc proc proc # mount -t sysfs sys sys Copy some key files so you'll have a working Internet connection within the chroot:
# cat /etc/resolv.conf > etc/resolv.conf # cat /etc/hosts > etc/hosts Now chroot into the encrypted system. From this point on, all work will be done inside the chroot:
# chroot . # apt-get update # echo 'export CRYPTSETUP=y' > /etc/initramfs-tools/conf.d/cryptsetup # apt-get install cryptsetup-initramfs dropbear-initramfs # for focal and buster # apt-get install cryptsetup dropbear-initramfs # for bionic Check to see that the cryptsetup scripts are present in the initramfs (command should produce output):
# gunzip -c /boot/initrd.img* | cpio --quiet -t | grep cryptsetup Edit '/etc/fstab' to look exactly like this:
/dev/mapper/rootfs / ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 1 /dev/mmcblk0p1 /boot ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 2 tmpfs /tmp tmpfs defaults,nosuid 0 0 Add the following lines to '/etc/initramfs-tools/initramfs.conf'. If the Orange Pi's IP address will be statically configured, substitute the correct static IP address after 'IP='. If it will be configured via DHCP, omit the IP line entirely:
DEVICE=eth0 IP=192.168.0.88:::255.255.255.0::eth0:off Add the following parameters to the quoted bootargs line in '/boot/boot.cmd'. Note that the 'root' parameter replaces the existing one:
root=/dev/mapper/rootfs cryptopts=source=/dev/mmcblk0p2,target=rootfs If you want to be able to unlock the disk from the virtual console (which you probably do) as well as via ssh, then comment out the following line:
# if test "${console}" = "serial" || test "${console}" = "both"; then setenv consoleargs "${consoleargs} console=ttyS0,115200"; fi In case you're wondering, 'setenv console "display"' doesn't work. Don't ask me why.
Compile the boot menu:
# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr Copy the SSH public key from the machine you'll be unlocking the disk from to the Armbian machine:
# rsync yourusername@remote_machine:.ssh/id_*.pub /etc/dropbear-initramfs/authorized_keys If you'll be unlocking the disk from more than one host, then edit the authorized_keys file by hand and add the additional SSH public keys.
Edit '/etc/dropbear-initramfs/config', adding the following lines:
DROPBEAR_OPTIONS="-p 2222" DROPBEAR=y Reconfigure dropbear:
# dpkg-reconfigure dropbear-initramfs Make sure everything was included in the initramfs (both commands should produce output):
# gunzip -c /boot/initrd.img* | cpio --quiet -t | grep dropbear # gunzip -c /boot/initrd.img* | cpio --quiet -t | grep authorized_keys Your work is finished! Exit the chroot and shut down the Orange Pi:
# exit # halt -p Swap the SD cards and restart the Pi. Unlock the disk by executing the following command on your remote machine. Substitute the Pi's correct static or DHCP-configured IP address for the one below. If necessary, also substitute the correct disk password in place of 'abc':
$ ssh -p 2222 -x root@192.168.0.88 'echo -n abc > /lib/cryptsetup/passfifo' If you choose to unlock the disk from the tty, just enter your disk password and hit ENTER.
If all went well, your root-filesystem encrypted Armbian system is now up and running!