Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have been putting this off for too long. Time to figure it out...
I have 4 encrypted file systems in my server (dmcrypt,LUKS). I unlock them with a key file located in /root/ and entries in /etc/crypttab. They are then mounted by /etc/fstab. Works great but...
I really want to keep the key file on a USB flash drive which I can store securely away from the server when not in use. To accomplish this I have written and tested a script which which will look for the correct USB drive, mount it, look for the key file and if it is present unlock and mount the file systems. It then unmounts the USB drive and powers it off. Now I need to figure out how to plug this into the systemd startup process.
I have finally wrapped my head around the fact that my scrip, while not starting a continuously running daemon, is in fact considered a "service" - a oneshot type of service. Therefor my .service unit file would look something like
Code:
[Unit]
Description=Unlock and mount encrypted FS if thumb drive with key is present
After= {something to indicated USB is available}
[Service]
Type=oneshot
ExecStart=/usr/sbin/unlock-n-mount
[Install]
WantedBy=multi-user.target
If I now look at the dependencies of the job... The root file system must be mounted and the USB "environment" must be available. The first is no problem. The root file system must be mounted so the system can read the script. As to the second... How do I tell systemd that I need to be able to connect to a USB drive in order to run my "service"? That is what I need to specify on the "After=" line I think.
I have searched for all .target files but I do not find anything which smells like it is USB related. Can anyone enlighten me?
TIA,
Ken
p.s. There might be a better location for my script and I would appreciate advice on that. However, it is the least of my worries at this point.
Thanks ondoho. If I follow your reasoning I should boot the server then, once it is up and running, insert the USB drive with the key. At this point the udev rule would initiate the unlock and mount script. Is that correct? An interesting idea.
My original desire was to allow the server to boot and IF the key was present have the process which uses /etc/crypttab unlock the file systems. If the key was not present the server would come up with the file systems locked. I never did have any luck figuring out how to do this.
I created the script and - as a learning experience - decided to incorporate it into the systemd startup process. That said...
I have created the unit file as described in the original post - less the USB line. It dawned on me that as I can boot a system from a USB drive the USB "environment" must be available very early on. I can systemctl start my service but so far I have not gotten it to fire on bootup. Yes, it is enabled. No errors, just no unlocked and mounted file system. Time to put some more logging into the script I guess.
My original desire was to allow the server to boot and IF the key was present have the process which uses /etc/crypttab unlock the file systems. If the key was not present the server would come up with the file systems locked. I never did have any luck figuring out how to do this.
ah, i see.
but i believe udev is suitable for that also.
do some research into udev.
Having no idea how to determine if the usb drive was available, I removed the After line from my .service unit file and executed systemctl start unlock-n-mount. IT WORKED! I then enabled my service and rebooted the PC. It did NOT work
For my next trick I changed the WantedBy to graphical.target and added After=multi-user.target. This worked on reboot. Not exactly as precise as I wanted - it is a long way from multi-user to graphical in startup terms. Not really but it is the principle of the thing. So then, I tweaked my script to look for the USB file system every 0.1 seconds until found and then do its thing. I set my WantedBy back to multi-user.target. AND IT WORKS Here is my result as it stands. I sure wish I could find exactly what dependency(s) I want this to run After...
Code:
[Unit]
Description=Unlock and mount encrypted FS if thumb drive with key is present
[Service]
Type=oneshot
ExecStart=/usr/sbin/unlock-n-mount.sh
[Install]
WantedBy=multi-user.target
The script
Code:
#!/bin/bash
# This script, when run as root, will unlock and mount an encrypted file system
# Is the flash drive with the key present?
# UUID="f10ef73c-c646-4cb3-8f87-7cccc44eaf8b"
echo $(date +%y/%m/%d_%r) "starting unlock and mount script" >> /var/log/ken.log
# kluge - wait until fs is available - usb delay?
filesystem="/dev/disk/by-uuid/f10ef73c-c646-4cb3-8f87-7cccc44eaf8b"
for k in $(seq 1 20)
do
if [ -b $filesystem ]; then
echo $(date +%y/%m/%d_%r) usb drive found >> /var/log/ken.log
break
else
echo $(date +%y/%m/%d_%r) waiting 0.$k seconds >> /var/log/ken.log
sleep 0.1
fi
done
# is the directory to which the flash drive is to me mounted present? It should be but if not, creat it.
directory="/keyhere"
if ! [ -d $directory ]; then
mkdir $directory
fi
# same for the directory where the encrypted partition is to be mounted
directory="/media/secret1"
if ! [ -d $directory ]; then
mkdir $directory
fi
# mount the flash drive with the key
mount /dev/disk/by-uuid/f10ef73c-c646-4cb3-8f87-7cccc44eaf8b /keyhere
if [ -e /keyhere/taylor.key ]; then
# unlock the encrypted partion using the key file
cryptsetup luksOpen /dev/disk/by-uuid/02e5db96-e1ae-4c88-9045-fb9122c4f096 --key-file /keyhere/taylor.key secret1
# finally, mount the now unlocked partition
mount /dev/mapper/secret1 /media/secret1 2>> /var/log/ken.err
if [ -d "/media/secret1/lost+found" ]; then
echo $(date +%y/%m/%d_%r) "encrypted file system mounted" >> /var/log/ken.log
else
echo $(date +%y/%m/%d_%r) "encrypted file system NOT mounted" >> /var/log/ken.log
fi
# unmount the usb file system
umount /keyhere
else
echo $(date +%y/%m/%d_%r) "keyfile not present on the usb drive" >> /var/log/ken.log
fi
Here is a sample from the log
Code:
[ken@taylor15 ~]$ cat /var/log/ken.log
17/10/22_10:00:01 AM starting unlock and mount script
17/10/22_10:00:01 AM waiting 0.1 seconds
17/10/22_10:00:01 AM waiting 0.2 seconds
17/10/22_10:00:01 AM usb drive found
17/10/22_10:00:07 AM encrypted file system mounted
After doing some testing of various scenarios - no USB drive, no key on USB drive etc. I decided to tidy up my script a little - mostly re. the log I was writing and a logic error. Here is the "final" script if anyone is interested.
Code:
#!/bin/bash
# This script, when run as root, will unlock and mount an encrypted file system
# Is the flash drive with the key present?
# UUID="f10ef73c-c646-4cb3-8f87-7cccc44eaf8b"
echo $(date +%y/%m/%d_%r) "starting unlock and mount script" >> /var/log/ken.log
# kluge - wait until fs is available - usb delay?
filesystem="/dev/disk/by-uuid/f10ef73c-c646-4cb3-8f87-7cccc44eaf8b"
for k in $(seq 1 20)
do
if [ -b $filesystem ]; then
echo $(date +%y/%m/%d_%r) usb drive found >> /var/log/ken.log
break
else
(( delay = $k * 100 ))
echo $(date +%y/%m/%d_%r) waiting $delay mSec >> /var/log/ken.log
sleep 0.1
fi
done
if ! [ -b $filesystem ]; then
echo $(date +%y/%m/%d_%r) usb drive NOT found >> /var/log/ken.log
exit
fi
# is the directory to which the flash drive is to me mounted present? It should be but if not, creat it.
directory="/keyhere"
if ! [ -d $directory ]; then
mkdir $directory
fi
# same for the directory where the encrypted partition is to be mounted
directory="/media/secret1"
if ! [ -d $directory ]; then
mkdir $directory
fi
# mount the flash drive with the key
mount /dev/disk/by-uuid/f10ef73c-c646-4cb3-8f87-7cccc44eaf8b /keyhere
if [ -e /keyhere/taylor.key ]; then
# unlock the encrypted partion using the key file
cryptsetup luksOpen /dev/disk/by-uuid/02e5db96-e1ae-4c88-9045-fb9122c4f096 --key-file /keyhere/taylor.key secret1
# finally, mount the now unlocked partition
mount /dev/mapper/secret1 /media/secret1 2>> /var/log/ken.err
if [ -d "/media/secret1/lost+found" ]; then
echo $(date +%y/%m/%d_%r) "encrypted file system mounted" >> /var/log/ken.log
else
echo $(date +%y/%m/%d_%r) "encrypted file system NOT mounted" >> /var/log/ken.log
fi
else
echo $(date +%y/%m/%d_%r) "keyfile not present on the usb drive" >> /var/log/ken.log
fi
# unmount the usb file system
umount /keyhere
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.