How to configure the mender to use dm-crypt partitions for rootfs?

Hello everyone,

We are using the mender 2.0 in standalone mode. Currently, the system is working fine and can able to update the artifacts (A/B block update).

However, as part of security enablement, we need to make the rootfs as encrypted with dm-encypt.

This means that the mender can not access the physical partitions directly as “/dev/mmcblk0p1” and need to use the virtual layer partition for the update.

Has anyone used or know how to configure the mender to use these virtual partitions for the A/B rootfs update?

Whether changing the “MENDER_STORAGE_DEVICE” to the virtual name is enough for the mender to take the virtual partitions or do I need to configure anything else?

@mirzak @eystein @drewmoseley @kacf @lluiscampos Any thoughts on this? Whether mender supports any device name or only known devices?

I have tried to modify the MENDER_STORAGE_DEVICE from “/dev/mmcblk0” to “/dev/dm-” and also tried to change MENDER_STORAGE_DEVICE_BASE from “/dev/mmcblk0p” to “/dev/dm-”.

Both give Yocto build error as follows:
ERROR: u-boot-imx-2018.03-r0 do_provide_mender_defines: Function failed: do_provide_mender_defines (log file is located at <path of the log>/2018.03-r0/temp/log.do_provide_mender_defines.6108)
ERROR: Logfile of failure stored in: <path of the log>/2018.03-r0/temp/log.do_provide_mender_defines.6108
Log data follows:
| DEBUG: Executing shell function do_provide_mender_defines
| + echo u-boot-imx
| + fgrep mender-auto-provided
| + true
| + expr 16777216 % ( 8388608 * 2 )
| + [ 0 -ne 0 ]
| + [ 16777216 -gt 16777216 ]
| + [ -n /dev/dm-1 ]
| + get_part_number_from_device /dev/dm-1
| + dev_base=unknown
| + printf %d unknown
| + part=0
| + MENDER_BOOT_PART_NUMBER=
| + bb_exit_handler
| + ret=1
| + echo WARNING: exit code 1 from a shell command.
| WARNING: exit code 1 from a shell command.
| + exit 1
| ERROR: Function failed: do_provide_mender_defines (log file is located at <path of the log>/2018.03-r0/temp/log.do_provide_mender_defines.6108)
ERROR: Task (<path of the log>/u-boot-imx_2018.03.bb:do_provide_mender_defines) failed with exit code '1'

Please note that the dm-crypt will change the partitions as /dev/dm-1 , /dev/dm-3 etc.

I have seen the following thread and mine is similar set-up (not exactly the same).

I understood that the kernel images need to be outside for this and can not update the kernel images as part of the rootfs update.

My worry is how the mender OTA update on rootfs works without specifying the physical block. If mender accesses the physical block (/dev/mmcblk0p1) and delete the partition, then the system will not mount it because encryption voids in this case. The physical partition is hidden always with dm-cyrpt and we can use the virtual physical partitions (/dev/dm-1 instead of /dev/mmcblk0p1) for the update.

However, specifying this /dev/dm-1 not passing the build.

It looks like the mender 2.0 's “meta-mender-core/classes/mender-helpers.bbclass” only define “/dev/mmcblk*p*” or “/dev/mmcblk*” for the U-boot.

as you have pointed out get_part_number_from_device() in https://github.com/mendersoftware/meta-mender/blob/master/meta-mender-core/classes/mender-helpers.bbclass does not have a case for encrypted partitions names.

The guys would probably welcome a pull request which contains an additionally case for dmcrypt named devices, could be very simple to add.

Its not clear to me why manipulating the names of MENDER_STORAGE_DEVICE_BASE and MENDER_ROOTFS_PART_A and MENDER_ROOTFS_PART_B would not be enough and carries the following caveat.

“Note that the Mender image builder will not produce such images, so only set these variables if you’re building partitioned images yourself, with a different layout than the default Mender layout (the example above reflects the default).”

Although thinking about it aren’t you going to need to create your own sdimg image recipe anyway to create a factory image with encrypted partitions?

Albeit as you have pointed out there are probably more hurdles to overcome after you have the storage device correctly added.

Thank you for the reply @dellgreen.
I’m using eMMC storage and the partition layout is different than the default mender layout (even for without encrypting case of mine).

Could you please let me know if I put the MENDER_STORAGE_DEVICE_BASE and MENDER_ROOTFS_PART_A and MENDER_ROOTFS_PART_B as actual physical partitions (/dev/mmcblk0p1), will it completely erase the physical partition while streaming the update?

In this case, I have to put the upper virtual layer partition created by dm-crypt (/dev/dm-1) for mender rootfs partitions. Removing only the “/dev/dm-1” level and update the rootfs will not break the dm-crypt functionalities.

To be honest, I’m not sure, I was under the impression that mender did streaming of block writes of the artifact to the non-active block device, so as long as the references to the mender block devices in uboot and the mender client config point to the /dev/dm-* block devices i would expect it to work as this block devices should of been decrypted by the kernel when you pass the necessary crypt parameters to the kernel from the bootloader.

This is not something I have done, so expect a level of trial and error and probably bbappend files for some recipes.

@dellgreen, a quick question.

My understanding is that changing MENDER_STORAGE_DEVICE, MENDER_STORAGE_DEVICE_BASE, MENDER_ROOTFS_PART_A, and MENDER_ROOTFS_PART_B will finally change the U-boot arguments. These configurations do not have any mender client source dependencies or implications.

Please correct me if I’m wrong. In this case, whether changing the U-boot arguments directly (instead of Yocto) using a patch will help? Yocto changes look like not going smooth and getting multiple errors, hence asked :slight_smile:

another thing to watch out for is /etc/mender/mender.conf on the root file system also contains references to both device partitions. Not sure why or whether relevant if using mender client in standalone mode.

So is setting MENDER_ROOTFS_PART_A, MENDER_ROOTFS_PART_B and MENDER_STORAGE_DEVICE_BASE to your virtual device and device partitions still failing the build?

another thing to watch out for is /etc/mender/mender.conf on the root file system also contains references to both device partitions. Not sure why or whether relevant if using mender client in standalone mode.

Thank you for pointing out this part. I will take care of the mender.conf.

So is setting MENDER_ROOTFS_PART_A, MENDER_ROOTFS_PART_B, and MENDER_STORAGE_DEVICE_BASE to your virtual device and device partitions still failing the build?

This will eventually fail since the changes will call “get_part_number_from_device()” and “get_uboot_device_from_device()” inside “meta-mender-core/classes/mender-helpers.bbclass”. This call is coming from the meta-mender-core/recipes-bsp/u-boot/u-boot-mender-common.inc’s “do_provide_mender_defines()”.

Both “get_part_number_from_device()” and “get_uboot_device_from_device()” currently hardcoded the partitions format. I have added the “dm-” in these calls but still getting the error. I’m debugging the issues :innocent:

1 Like

I have not personally worked with dm-crypt so do not have much more to add then what has been covered in this thread.

I did a similar thing and maybe I am able to give a few hints:

I am using an unmodified Mender (2.1) with LUKS/dm-crypt encrypted partitions (Data, A and B are encrypted, the boot partition is not encrypted).

The partition setup in /etc/mender/mender.conf contains the following values:

"RootfsPartA": "/dev/mapper/mydevice-root",
"RootfsPartB": "/dev/mapper/mydevice-root-mmcblk2p3",

The RootfsPartA is constant while the RootfsPartB setting gets adjusted within a Download_Enter… script.

In an ArtifactInstall_Leave… script I copy the signed FIT image from the encrypted rootfs partition to the unencrypted boot partition. U-Boot will then check the signature of the FIT image.

Unfortunately I cannot give any hints about the Yocto integration as I have done the full secure boot setup based on Debian using my tool called edi.

1 Like

I would like to know whether the RootfsPartA is always constant or will change during next update? Also how the A/B rootfs update working with the above case (including the fallback)? :thinking:

I keep RootfsPartA always constant and just adjust RootfsPartB. Like this Mender will always believe it is running from RootfsPartA. The beauty of device mapper is, that I can mount RootfsPartB within a Download_Enter… script in a way that it matches /etc/mender/mender.conf. During the update Mender will then happily stream the update to RootfsPartB. The switching between partition A and B on bootloader level is done in a similar way to this example. The “primary boot script” looks like this one. However, a small modification at the end of the script is needed to boot the secondary boot.scr from the unencrypted boot partition instead of the encrypted A or B partition. The secondary boot script then loads and starts the signed fit image that will then mount the encrypted partitions.