Last Updated 7 days by cneuhaus

📢 Automating LUKS – Seamless Encryption &  The Battle Against sudo

Fun fact – I used one Chat-Window with ChatGPT to find this solution, at the end I asked him to understand the objective of my questions, and used below prompt to build this post – wouhhh ( I love it how he ignores my spelling mistakes ;.))


The Problem

I’ve always been a fan of automation—no unnecessary manual steps, no friction, no surprises.
When dealing with LUKS-encrypted storage and Samba shares, I had one clear goal:

✅ Fully automate mounting and unmounting without needing to enter manual passwords

Actually, I have another script that gets the password via https request, so its a remote lock/unlock. The script is a simple web-server,  you will know how to do it 🙂

That sounds simple? It wasn’t.

The First Idea: Just Use udisksctl

At first, udisksctl seemed perfect. A simple:

udisksctl unlock -b /dev/sdf2

would unlock my LUKS volume, and:

udisksctl lock -b /dev/disk/by-uuid/XXXX

should lock it. No root, no sudo.

But then came the first brick wall: It asked for a password—even when running from a script.
💬 “Wait, why does udisksctl need root to lock a device, but not to unlock it?”

Welcome to Polkit & UDisks2—a world of undocumented edge cases.

Polkit: The Rabbit Hole

My next move? Polkit rules.
It should allow passwordless execution, right?

polkit.addRule(function(action, subject) {
    if ((action.id == "org.freedesktop.udisks2.encrypted-unlock" ||
         action.id == "org.freedesktop.udisks2.lock-device") &&
        subject.isInGroup("disk")) {
        return polkit.Result.YES;
    }
});

Result? Still asking for a password.
Debugging with journalctl -f | grep polkit told me that some actions were still being denied.
One step forward, two steps back.

The Real Issue: fuser, Samba & Busy Devices

Unmounting a LUKS volume is not just about stopping I/O operations—it’s about breaking any remaining connections.

  • Samba still held open files on my mounted LUKS drive.
  • udisksctl lock failed with “Device or resource busy”.
  • umount -l wasn’t enough—because smbd was still running in the background.

I needed to force kill processes before unmounting.

sudo smbcontrol smbd close-share LUKSShare
sudo fuser -km /data/check
sudo udisksctl unmount -b /dev/mapper/my_luks_drive

💡 Lesson learned: Locking a LUKS device isn’t just about the disk—it’s about all the services using it.

The Compromise: Selective sudo

At this point, I had a choice:

  1. Go even deeper into Polkit and hack my way through more rules.
  2. Accept reality and selectively allow sudo—but in a controlled way.

I chose option 2.
Using visudo, I allowed only the required commands to run without a password:

youruser ALL=(ALL) NOPASSWD: /usr/bin/udisksctl lock -b /dev/disk/by-uuid/*,                              /usr/bin/smbcontrol smbd close-share *,                              /usr/bin/fuser -km /data/check

This kept security tight while making automation work smoothly.

The Final Setup

At the end of this journey, I had a fully working system that:

  • ✅ Mounts LUKS automatically.
  • ✅ Unmounts and locks it without requiring sudo manually.
  • ✅ Closes Samba shares properly to avoid device busy errors.
  • ✅ Uses sudo only for the absolute essentials (but without password prompts).

Final Changes

Below are the final changed files:

  • 📂 Mount and Unmount Scripts
    (automating the full LUKS lifecycle)
  • 📂 sudoers File
    (allowing selective passwordless sudo execution)
  • 📂 Polkit Rules
    (the necessary adjustments to make it work)

🚀 Conclusion

This wasn’t just about avoiding sudo. It was about understanding Linux security, process management, and automation.
Would I do it the same way again? Probably.

Would I recommend it to someone else?
💡 “Only if you’re really into debugging Linux internals.”

🚀 Final setup below. Let me know if you see ways to make it even cleaner.

💡 This post is for those who want real, practical automation without compromising security.
If you’ve fought the same battle, drop a comment. 🔥

Mount

 1 #!/bin/bash
 2
 3 # Check if password is provided
 4 if [ -z "$1" ]; then
 5     echo "Usage: $0 <password>"
 6     exit 1
 7 fi
 8
 9 password="$1"
10 device="/dev/sdx1"   # Your LUKS partition
12 luks_name="luks-xxx"  # Custom device name
13
14 # Unlock LUKS partition with a fixed name
15 udisksctl unlock --block-device "$device" --key-file <(echo -n "$password")
16
17 sleep 1
18 # Mount the unlocked LUKS volume
19 udisksctl mount -b "/dev/mapper/$luks_name"

Unmount

#!/bin/bash
 2
 3 # Configuration: Set your LUKS device details
 4 LUKS_UUID="luks-xxxx" 
 5 LUKS_MAPPER="/dev/mapper/luks-xxxx"
 6 MOUNT_PATH="//mount_point"  # Mount point
 7 SAMBA_SHARE_NAME="smb_share"  # Samba share name
 8 DEVICE="/dev/sdx1"
 9
10 # Close active Samba connections
11 echo "Closing Samba share: $SAMBA_SHARE_NAME..."
12 sudo smbcontrol smbd close-share "$SAMBA_SHARE_NAME"
13
14 sleep 1
15
16
17 # Unmount the LUKS volume
18 echo "Unmounting LUKS volume..."
19 sudo udisksctl unmount -b "$LUKS_MAPPER" || umount -l "$LUKS_MAPPER"
20
21
22 # Kill all processes using the mount point
23 #echo "Killing active processes on $MOUNT_PATH..."
24 #sudo fuser -km "$MOUNT_PATH"
25
26 # Wait for system to release resources
27 sleep 1
28
29 # Lock the LUKS device
30 echo "Locking LUKS device..."
31 sudo udisksctl lock -b "$DEVICE"
32
33 if [ $? -eq 0 ]; then
34     echo "LUKS device successfully locked!"
35     exit 0
36 else
37     echo "Failed to lock LUKS device."
38     exit 1
39 fi
40
41 sleep 1
42
43 echo "Set HD to sleep mode"
44 # sudo hdparm -y "$DEVICE

Sudo File:

docbox ALL=(ALL) NOPASSWD: /usr/bin/udisksctl lock -b /dev/sdf2 , \
                            /usr/bin/udisksctl unmount -b /dev/mapper/*, \
                            /usr/bin/smbcontrol smbd close-share *, \
                            /usr/bin/fuser -km *, \
                            /usr/sbin/hdparm -y /dev/sdx1

Polkit Files:

polkit.addRule(function(action, subject) {
    if ((action.id == "org.freedesktop.udisks2.encrypted-unlock" ||
         action.id == "org.freedesktop.udisks2.filesystem-mount" ||
         action.id == "org.freedesktop.udisks2.filesystem-unmount-others" ||
         action.id == "org.freedesktop.udisks2.unmount" ||
         action.id == "org.freedesktop.udisks2.lock-device" ||
         action.id == "org.freedesktop.udisks2.encrypted-unlock-other-seat") &&
        subject.isInGroup("disk")) {
        return polkit.Result.YES;
    }
});

 

Categories: Uncategorized