Have someone already integrated mender-client and secure storage?
The idea is to have all mender configuration files (currently stored in /data/mender) stored in a secured partition.
AFAIK, mender-client (and other services) is launched after data.mount. What if a secured but unlocked for read/write partition is mounted in /data?
What the purpose of mender-grow-data.service. ?
is that resize required for proper image download?. What if that resize is done after the partition gets encrypted and unlocked for read/write?
Hi @sd-ricardo,
The Mender Client should be storage agnostic. So if the /data partition is mounted and accessible once the Client starts, you can employ whatever kind of encryption or security measure that fits your use case.
For the mender-grow-data.service, it is a possibility to have an image which adjusts to a variety of storage sizes. If you know the size of the /data storage area in advance, it is not needed.
Greetz,
Josef
Oh, I see!
Thanks!
Would it be any proble if I replace the dependency on data.mount to my custom service that encrypt and mount the martition?
- from this
[Unit]
Description=Mender persistent data dir
After=data.mount
Before=mender-client.service mender-authd.service mender-updated.service
ConditionPathExists=!/data/mender
[Service]
Type=oneshot
User=root
Group=root
ExecStart=/bin/mkdir -p -m 0700 /data/mender
[Install]
WantedBy=mender-client.service mender-authd.service mender-updated.service
- to this
[Unit]
Description=Mender persistent data dir
After=custom_encrypt_and_mount.service
Before=mender-client.service mender-authd.service mender-updated.service
ConditionPathExists=!/data/mender
[Service]
Type=oneshot
User=root
Group=root
ExecStart=/bin/mkdir -p -m 0700 /data/mender
[Install]
WantedBy=mender-client.service mender-authd.service mender-updated.service
Interesting take, @sd-ricardo!
My gut feeling is that, yes, it should work - but in good engineering tradition, I can just say "try and find out"![]()
Let us know then!
Greetz,
Josef
Thanks a lot!
I’m just finalyzing the fine tunning… so far seems to be working!
Hi @sd-ricardo,
I realize this is quite an old thread, but I thought it might be worth a shot
.
I am also looking into securing our application data. I got the impression that using LUKS + TPM has not been achieved before (I am working on a debian family custom image, not Yocto), so I am looking into alternatives. Encrypting the data partition seems like the next best thing to me, thus I wanted to ask if you were able to get this working and if you would want to share some pointers on how you went about this, what encryption tools you used, …
Thanks in advance!
Hi @JonathanC,
For securing application data, I have recently shown a solution with LUKS+TPM. It might need a bit of adjusting for Debian, but I’m pretty sure it should be straightforward: https://www.youtube.com/live/Fy_F0D9cW0o?si=r1mpNPV_2KTtM-Gr
Greetz,
Josef
Hi @TheYoctoJester,
This was the route I went down, so your video helped me speed that up a lot! I only had to make some minor changes to the script to get it to encrypt the /data partition that mender-convert creates. I added the files to the build through overlays and got the service to run at boot by making the symbolic link to /etc/systemd/system/multi-user.target.wants/ ahead of time also in the overlay (basically what systemctl start <service> does).
In the end it took me more than a week to get it working on my machine because there was some weirdness with secure boot. I had TPM and secure boot enabled in the BIOS and mokutil --sb-state showed Secure Boot enabled but the TPM pcr 7 would still fail (silently as far as I can tell). In the end resetting the secure boot state to setup in the bios and re-enabling it after flashing the OS image fixed it getting me past the password prompt at boot automatically.
Thanks again!
Unfortunately I came to the conclusion that my attempt at implementing this is not reliable for some reason… I tried deploying my image on a second identical device and it fails consistently. Upon booting with systemd debug logging on I can see that the pcr 7 value is changed after enrolling and from the second boot onward. I’m not quite sure how this is possible, the only suspect I have left is the initrd because I have some extra initrd changes that differ from the yt video, but as far as I can find this should not affect pcr 7 either so I am a bit lost.
Here is my systemd service and script:
[Unit]
Description=Encrypt persistent data partition
After=systemd-remount-fs.service
After=systemd-tmpfiles-setup.service
ConditionPathExists=!/etc/setup-data-crypt-done
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/setup-data-crypt.sh
ExecStartPost=/usr/bin/touch /etc/setup-data-crypt-done
User=root
Group=root
TimeoutSec=600
SuccessExitStatus=0
StandardOutput=journal+console
StandardError=journal+console
[Install]
WantedBy=multi-user.target
#!/bin/sh
set -e
DATA_PART_DEVICE="/dev/nvme0n1p4"
PASSWORD_FILE="/root/.data-crypt-password"
/usr/bin/echo "[data-crypt-setup] Setting up TPM-based data partition encryption..."
/usr/bin/umount /data
# Check if it is already encrypted
if /usr/sbin/cryptsetup isLuks ${DATA_PART_DEVICE}; then
/usr/bin/echo "[data-crypt-setup] Data partition is already encrypted. Skipping..."
exit 0
fi
# ensure root fs is writable
if ! touch /root/.test_write 2>/dev/null; then
/usr/bin/echo "[data-crypt-setup] Root filesystem is not writable. Skipping..."
exit 1
fi
/bin/rm -f /root/.test_write
# Generate a random password
/usr/bin/openssl rand -base64 44 > ${PASSWORD_FILE} || {
/usr/bin/echo "[data-crypt-setup] Failed to generate password. Skipping..."
exit 1
}
/bin/sync
# Create LUKS container with ext4 fs inside
/usr/bin/echo "[data-crypt-setup] Formatting data partition with LUKS2..."
/usr/bin/cat "${PASSWORD_FILE}" | /usr/sbin/cryptsetup luksFormat --batch-mode --type luks2 "${DATA_PART_DEVICE}"
/usr/bin/cat "${PASSWORD_FILE}" | /usr/sbin/cryptsetup open --batch-mode "${DATA_PART_DEVICE}" data-crypt
/usr/bin/echo "[data-crypt-setup] Creating ext4 filesystem on data partition..."
/usr/sbin/mkfs.ext4 -q /dev/mapper/data-crypt
/bin/sync
/usr/sbin/cryptsetup close data-crypt
/bin/sync
# Add dracut configuration
/usr/bin/echo "[data-crypt-setup] Adding dracut configuration..."
/usr/bin/cat > /etc/dracut.conf.d/crypt-tpm2.conf << 'EOF'
hostonly="yes"
use_systemd="yes"
add_dracutmodules+=" crypt tpm2-tss "
install_items+=" /etc/crypttab "
EOF
# Enroll key to TPM
/usr/bin/echo "[data-crypt-setup] Enrolling TPM for automatic unlock..."
export PASSWORD="$(cat ${PASSWORD_FILE})"
/usr/bin/systemd-cryptenroll --wipe-slot=tpm2 --tpm2-device=auto --tpm2-pcrs=7 "${DATA_PART_DEVICE}" || {
/usr/bin/echo "[data-crypt-setup] Failed to enroll TPM. Skipping..."
unset PASSWORD
/usr/bin/shred -vfz ${PASSWORD_FILE} 2>/dev/null || /bin/rm -f ${PASSWORD_FILE}
exit 1
}
unset PASSWORD
/usr/bin/shred -vfz ${PASSWORD_FILE} 2>/dev/null || /bin/rm -f ${PASSWORD_FILE}
# Update /etc/fstab and /etc/crypttab
/usr/bin/echo "[data-crypt-setup] Creating /etc/crypttab..."
/usr/bin/sed -i "s|/dev/nvme0n1p4|/dev/mapper/data-crypt|" /etc/fstab
/usr/bin/echo "data-crypt ${DATA_PART_DEVICE} none luks,tpm2-device=auto,discard,x-initrd.attach,no-read-workqueue,no-write-workqueue" > /etc/crypttab
/bin/chmod 0400 /etc/crypttab
/bin/sync
# Regenerate initramfs using dracut
/usr/bin/echo "[data-crypt-setup] Regenerating initramfs with dracut..."
/usr/bin/dracut -f --kver "$(/usr/bin/uname -r)" || {
/usr/bin/echo "[data-crypt-setup] Failed to regenerate initramfs with dracut..."
exit 1
}
/bin/sync
/usr/bin/echo "[data-crypt-setup] Setup successful. Rebooting system..."
/usr/bin/touch /etc/setup-data-crypt-done
/bin/sync
/usr/sbin/reboot
exit 0
A couple of notes, I had to switch to dracut on ubuntu because the default initramfs generator on ubuntu does not have support for tpm and I am unmounting /data instead of using Before=data.mount in the service because that resulted in a systemd dependency cycle on basic.target/service I believe.
Hi @JonathanC,
That sounds a bit unfortunate indeed. The only thing that comes to my mind immediately is possibly using a more suitable PCR? There is some description at Trusted Platform Module - ArchWiki.
Greetz,
Josef