(9 comments)

Recently I've bought an Odroid U3 peace of hardware, which is fueled by an Exynos-4412 (Quad core) application processor, providing a 2GB LP-DDR2 RAM and, for 3D graphic, Mali-400 GPU.
So, the first thing after U3's arrival, I wanted to install a Linux Fedora 20 on my microSD card, but on LUKS-encrypted LVM with the ability to unlock it remotely via SSH. And here we begin...

Prerequisites
- A preinstalled Linux Fedora 20 (image) for armhfp / odroidu, which you can download a copy from this location,
- At least 4GB microSD card (or SD if you have eMMC module), but 8 GBs or more is highly recommended,
- A local network with Odroid connected.

In short, steps, which I did to switch to encrypted LVM, were:
1) Copied Fedora image to SD card,
2) Booted Fedora, configured it, disabled "swap" in /etc/fstab and created initramfs (Dracut),
3) Powered off Odroid, deleted swap and resized boot partition because it is too small to hold our initramfs,
5) Backuped Fedora's rootfs partition on local storage, then deleted it and created on it's place an encrypted LVM,
6) Restored rootfs' content on the encrypted volume,
7) Made appropriate changes in /etc/fstab to point to the new FS'es.

The quest begins

On the beginning we will create the wanted Dracut's module, which will allow us to remotely unlock rootfs, by embedding into initramfs a small sshd daemon - Dropbear. I assume that you already have Fedora's image copied on your SD card and you are logged as root.
Create a new module called custom.

$ cd /usr/lib/dracut/modules.d/
$ mkdir 99custom; cd 99custom

Now we create all needed files in our module's folder. Modify the daemon.sh to meet your network needs.

$ cat > daemon.sh << EOF
#!/bin/sh

/sbin/ip link set dev lo up
/sbin/ip addr add 10.0.0.1/24 dev eth0
/sbin/ip link set dev eth0 up
/usr/sbin/dropbear -E -m -s -j -k -p 2222 -P /tmp/dropbear.pid
EOF
$ cat > local.conf << EOF
alias eth0 smsc95xx
EOF
$ cat > passwd << EOF
root:x:0:0:root:/root:/bin/sh
EOF
$ cat > shells << EOF 
/bin/sh
EOF
$ cat > authorized_keys << EOF
put_here_your_ssh_pub.id_key_for_passwordless_login
EOF

 

$ cat > modules.conf << EOF
smsc95xx
gf128mul
xts
aes-arm
sha256
dm-crypt
EOF

 

$ cat > module-setup.sh << EOF
#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh

check() {
    return 0
}

depends() {
    echo lvm
    echo dm
    echo crypt
    return 0
}    

install() {
    dracut_install -o ip
    dracut_install -o dropbear

    inst_simple "${moddir}/dropbear_dss_host_key" "/etc/dropbear/dropbear_dss_host_key"
    inst_simple "${moddir}/dropbear_rsa_host_key" "/etc/dropbear/dropbear_rsa_host_key"
    inst_simple "${moddir}/dropbear_ecdsa_host_key" "/etc/dropbear/dropbear_ecdsa_host_key"
    inst_dir "/root"
    inst_dir "/root/.ssh"
    
    inst_simple "${moddir}/local.conf" "/etc/modprobe.d/local.conf"
inst_simple "${moddir}/modules.conf" "/etc/modules-load.d/modules.conf"
    inst_simple "${moddir}/authorized_keys" "/root/.ssh/authorized_keys"
    inst_simple "/etc/hosts"
    inst_simple "/etc/host.conf"
    inst_simple "${moddir}/passwd" "/etc/passwd"
    inst_simple "${moddir}/shells" "/etc/shells"
    inst_hook pre-trigger 01 "$moddir/daemon.sh"
}
EOF

Set appropriate permissions on daemon.sh and module-setup.sh:

$ chmod +x daemon.sh module-setup.sh

Done, let's install now a Dropbear and generate the DSS, RSA and ECDSA keys.

$ yum -y install dropbear
$ dropbearkey -t dss -f dropbear_dss_host_key
$ dropbearkey -t rsa -f dropbear_rsa_host_key -s 4096
$ dropbearkey -t ecdsa -f dropbear_ecdsa_host_key -s 521

Great. You should have all the needed Dracut module files, so we can proceed with initramfs creation.

$ dracut -f --add-drivers "xts gf128mul aes-arm sha256 dm-crypt smsc95xx"

As you can see, we explicitly tell the Dracut to include the required kernel modules. Next, convert a typical initramfs image into u-boot format. In my case I'm running the 3.8.13.14 kernel.

$ mkimage -A arm -O linux -T ramdisk -C none -a 0 -e 0 -n initramfs \ 
-d /boot/initramfs-3.8.13.14.img /boot/uInitrd

We have temporarily exported initramfs in u-boot format into the /boot/uInitrd location. Why temporarily? Because /boot/uboot/ (mount point of the first VFAT 'boot' partition), does not have enough free space, yet. Resizing we shall and will do later...

Now we need to modify the boot.scr file, to inform Odroid about our initramfs image.

$ cat > /boot/boot.txt << EOF
setenv initrd_high "0xffffffff"
setenv fdt_high "0xffffffff"
setenv bootcmd "fatload mmc 0:1 0x40008000 zImage; fatload mmc 0:1 0x42000000 uInitrd; \
bootm 0x40008000 0x42000000"
setenv bootargs "console=tty1 console=ttySAC1,115200n8 root=/dev/mapper/VGname-root \
rd.lvm.lv=VGname/root rootwait ro mem=2047M"
boot
EOF

The above configuration does not include the rd.luks.uuid kernel parameter, which we will add later, when we get to know our Luks UUID partition.
Also, it is time to think about the name for your Volue Group - in the example above it's called VGname and the name of Logical Volume for rootfs is root.

BTW: The reason why would you need to specify a correct argument forrd.luks.uuid parameter is to make our LUKS partition "detectable" by plymouth, allowing us to unlock LVM also by the keyboard... ;-)

Create the boot.scr from boot.txt file.

mkimage -A arm -T script -C none -n "Modified boot.scr for odroid-u3" \
-d /boot/boot.txt /boot/boot.scr

Okay, I guess the major configuration is done. Make sure to check /etc/fstab and disable swap there. Next poweroff your Odroid and connect it to your local machine for rootfs backup. Also, backup content of the first boot parition, the VFAT formatted one. From this partition Odroid loads the Kernel and u-boot initramfs for your Fedora. Do the necessary swap deletion and recreate boot partition. Delete third partition (the rootfs one) and recreate it as secondary primary. After a proper syncing, you should have:

/dev/sdx1 - the boot VFAT partition (sized to approx 500MB),
/dev/sdx2 - the Linux partition with no FS at all for later LVM crypto use (the rest of a free space).

$ fdisk -l /dev/sdx

Disk /dev/sdd: 7.4 GiB, 7913603072 bytes, 15456256 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x000674ed

Device    Boot     Start       End  Blocks  Id System
/dev/sdx1           3072   1041015  518972  83 Linux
/dev/sdx2        1041016  15456255 7207620  83 Linux

On the local machine make sure you have the cryptsetup installed. To create an encrypted partition on your SD card, execute:

$ cryptsetup -v --cipher aes-xts-plain --key-size 512 --hash sha256 --iter-time 1000 \
--use-random luksFormat /dev/sdx2

We use the sha256 hash function, since sha512 is not available in the default preinstalled 3.8 kernel. 

# CONFIG_CRYPTO_SHA512 is not set

BTW:

XTS-PLAIN is perfectly fine when encrypting hard drives that are smaller than 2TB's. However, using XTS-PLAIN on hard drives larger than 2TB's will dramatically reduce your security because of repeating initialization vectors...

After LUKS creation, decrypt it.

$ cryptsetup luksOpen /dev/sdd2 odroidLuks

And create Physical Volume on it.

$ pvcreate /dev/mapper/odroidLuks
Physical volume "/dev/mapper/odroidLuks" successfully created

Create Volume Group - do you recall the chosen name? ;-)

$ vgcreate VGname /dev/mapper/odroidLuks

In this example, on VG I create one Logical Volume.

$ lvcreate -l 100%FREE -n root VGname
Logical volume "root" created

Put some file system on your freshly created root LV.

$ mkfs.ext4 /dev/mapper/VGname-root

Ok, PV, VG and LV created. You can mount now your encrypted rootfs block device and restore the data from your backup. Moreover, and this is importand, do not forget to copy the boot.scr and uInitrd from rootfs ( boot/{boot.scr,uInitrd} ) onto VFAT boot partition!

When all data is restored, umount all SD's FSes and boot Odroid with it. After a few seconds you should be able to SSH into on 2222 port.
The unlock procedure is as follows:

-sh-4.2# /sbin/cryptsetup luksOpen /dev/mmcblk0p2 luks

After successfull unlock mount the rootfs.

-sh-4.2# /sbin/lvm vgchange -a y
-sh-4.2# mount /dev/mapper/VGname-root /sysroot
-sh-4.2# ps -C systemd-cryptsetup -o pid=
-sh-4.2# kill pid_of_systemd-cryptsetup
-sh-4.2# Connection to odroid closed by remote host.
Connection to odroid closed.

The connection closed information means, that your Fedora booted from encrypted rootfs.
For those, who want also have an option to unlock it throuth a password typed on the keyboard - add to the boot.txt file the rd.luks.uuid parameter with a correct luks UUID. To find out the luks UUID use cryptsetup.

$ cryptsetup luksDump /dev/mmcblk0p2 |grep UUID
UUID:             494282-4a4f-250-yourUUID
$ cat /boot/boot.txt
setenv initrd_high "0xffffffff"
setenv fdt_high "0xffffffff"
setenv bootcmd "fatload mmc 0:1 0x40008000 zImage; fatload mmc 0:1 0x42000000 uInitrd; \
bootm 0x40008000 0x42000000"
setenv bootargs "console=tty1 console=ttySAC1,115200n8 root=/dev/mapper/VGname-root \
rd.lvm.lv=VGname/root rd.luks.uuid=luks-494282-4a4f-250-yourUUID rootwait ro mem=2047M"
boot

Regenerate boot.scr to propagate our changes.

mkimage -A arm -T script -C none -n "boot.scr for odroid-u3" \
-d /boot/boot.txt /boot/uboot/boot.scr

And that would be it! Any comments appreciated.


Currently unrated

Comments

Adrian 4 years, 4 months ago

I tried each of the 3 xz images on my Odroid us installed on uSD. Cannot get anything to boot ? The boot partition seems light ;only has bootini and zlimage in it.
Did I miss something in the procedure above as no boot,
is my current status.Thankyou for any advice ?

Link | Reply
Currently unrated

mescanef 4 years, 4 months ago

hi adrian!

firstly thanks for readin. can you specify which XZ image have you used (can you provide a link?).
The Fedora 20 IMG taken from http://www.odroid.in/fedora-20/ has a separate boot partition, mounted under /boot/uboot. By default there are multiple scr files and the zImage - thats the place where should be the uInitrd as well. Can you provide details on the content of your boot partition? Exact what files, and what is the content of boot.scr?
Also, please provide output of the "fdisk -l /dev/put_here_your_uSD_devID" to see the partitions structure.

regards,
mescanef

Link | Reply
Currently unrated

Adrian 4 years, 3 months ago

Sorry, It took me a while to get back here
. xzcat .......... > ............

had a corrupted boot partition (tried a few times), whereas extracting the xz,
then dd to the uSD (fedora Arm Installer) worked fine.

Weird as i have used xzcat successfully before with other images. Anyhow all good now. I am keen on fedora 20, the currect kernel does not support emmc boot, and i am looking forward to the update.

Link | Reply
Currently unrated

mescanef 4 years, 3 months ago

hi!

good to hear that you managed to encrypt your fedora. :-)

regarding the emmc module, i dont know if it is supported by the kernel - i dont use the emmc simply because i dont have it ;-).
however, the kernel is the same for all available distros (fedora/ubuntu (...)), which means the EMMC support should be compiled by default.
kindly please run on your fedora these below commands and reply what is the output:

uname -a
zgrep -i mmc /proc/config.gz

regards,
mescanef

Link | Reply
Currently unrated

Adrian 4 years, 3 months ago

Hi ok , I did those ;

[[email protected] ~]# uname -a
Linux fc20odroid 3.8.13.14 #14 SMP PREEMPT Mon Jan 27 16:44:26 BRST 2014 armv7l armv7l armv7l GNU/Linux
[[email protected] ~]#

[[email protected] ~]# zgrep -i mmc /proc/config.gz
CONFIG_S3C_DEV_HSMMC=y
CONFIG_S3C_DEV_HSMMC1=y
CONFIG_S3C_DEV_HSMMC2=y
CONFIG_S3C_DEV_HSMMC3=y
# Configuration for HSMMC 8-bit bus width
# Supported MMC/SDIO adapters
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
# CONFIG_MMC_CLKGATE is not set
# MMC/SD/SDIO Card Drivers
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_MINORS=8
CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_MMC_TEST is not set
# MMC/SD/SDIO Host Controller Drivers
# CONFIG_MMC_ARMMMCI is not set
CONFIG_MMC_SDHCI=y
# CONFIG_MMC_SDHCI_PLTFM is not set
CONFIG_MMC_SDHCI_S3C=y
# CONFIG_MMC_SDHCI_PXAV3 is not set
# CONFIG_MMC_SDHCI_PXAV2 is not set
# CONFIG_MMC_SDHCI_S3C_DMA is not set
CONFIG_MMC_DW=y
CONFIG_MMC_DW_IDMAC=y
# CONFIG_MMC_VUB300 is not set
# CONFIG_MMC_USHC is not set
[[email protected] ~]#


Is there any way to enable emmc support on the existing system here ?

Thankyou

Adrian ... vk4tux

Link | Reply
Currently unrated

mescanef 4 years, 3 months ago

hi,

the kernel config looks preety standard to me, and while I have bit more up-to-date version, the config here is the same.
my major question is regarding this: what happens when you have connected emmc card along with mircoSD?
Fedora boots from microSD, right? And then, if so, you should be able to "partition" the emmc card from the booted fedora.

what you could try to accomplish here is to boot from the microSD card (have a boot partition there with the kernel image, uinitrd, boot.scr... for the decryption), and the rest - the roofs - keep on the emmc module as an encrypted LVM partition. after booting from microSD the initramfs will (or at least should) detect your emmc as well...

in other words, create the encrypted partition on emmc, then create phisical volume (pvcreate) on it, later the volume group (vgcreate) and logical volume on the end. just don't have the same two VG's names on emmc and microSD... :-)

regards,
mescanef

Link | Reply
Currently unrated

Adrian 4 years, 3 months ago

I was hoping to boot from the emmc with no uSD involved or connected. ?

Thankyou

Link | Reply
Currently unrated

mescanef 4 years, 3 months ago

hello adrian,

cant give you the details on booting from emmc - I encourage you to ask on the official odroid forum: http://forum.odroid.com/
(Im also reg. there ;-)).

regards,
mescanef

Link | Reply
Currently unrated

Adrian 4 years, 3 months ago

Yes, We have been waiting on Mauro there
Patience is a virtue ....................ho-hum.

regards

Adrian

Link | Reply
Currently unrated

New Comment

required

required (not published)

optional