LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This 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


Reply
  Search this Thread
Old 10-20-2017, 08:51 AM   #1
taylorkh
Senior Member
 
Registered: Jul 2006
Location: North Carolina
Distribution: CentOS 6, CentOS 7 (with Mate), Ubuntu 16.04 Mate
Posts: 2,127

Rep: Reputation: 174Reputation: 174
My first homemade ".service" unit file


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.
 
Old 10-20-2017, 02:58 PM   #2
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
Quote:
Originally Posted by taylorkh View Post
Code:
After= {something to indicated USB is available}
sorry to burst your bubble, but this is better achieved with a udev rule: http://dt.iki.fi/udev/
 
Old 10-20-2017, 06:15 PM   #3
taylorkh
Senior Member
 
Registered: Jul 2006
Location: North Carolina
Distribution: CentOS 6, CentOS 7 (with Mate), Ubuntu 16.04 Mate
Posts: 2,127

Original Poster
Rep: Reputation: 174Reputation: 174
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.

Ken
 
Old 10-21-2017, 03:32 AM   #4
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
Quote:
Originally Posted by taylorkh View Post
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.
 
Old 10-22-2017, 09:15 AM   #5
taylorkh
Senior Member
 
Registered: Jul 2006
Location: North Carolina
Distribution: CentOS 6, CentOS 7 (with Mate), Ubuntu 16.04 Mate
Posts: 2,127

Original Poster
Rep: Reputation: 174Reputation: 174
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
Ken
 
Old 10-22-2017, 12:49 PM   #6
taylorkh
Senior Member
 
Registered: Jul 2006
Location: North Carolina
Distribution: CentOS 6, CentOS 7 (with Mate), Ubuntu 16.04 Mate
Posts: 2,127

Original Poster
Rep: Reputation: 174Reputation: 174
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
and three examples from the log
Code:
[ken@taylor15 ~]$ cat /var/log/ken.log 
17/10/22_01:40:44 PM starting unlock and mount script
17/10/22_01:40:44 PM waiting 100 mSec
17/10/22_01:40:44 PM waiting 200 mSec
17/10/22_01:40:44 PM waiting 300 mSec
17/10/22_01:40:44 PM usb drive found
17/10/22_01:40:44 PM keyfile not present on the usb drive
17/10/22_01:44:22 PM starting unlock and mount script
17/10/22_01:44:23 PM waiting 100 mSec
17/10/22_01:44:23 PM waiting 200 mSec
17/10/22_01:44:23 PM waiting 300 mSec
17/10/22_01:44:23 PM waiting 400 mSec
17/10/22_01:44:23 PM waiting 500 mSec
17/10/22_01:44:23 PM waiting 600 mSec
17/10/22_01:44:23 PM waiting 700 mSec
17/10/22_01:44:23 PM waiting 800 mSec
17/10/22_01:44:23 PM waiting 900 mSec
17/10/22_01:44:24 PM waiting 1000 mSec
17/10/22_01:44:24 PM waiting 1100 mSec
17/10/22_01:44:24 PM waiting 1200 mSec
17/10/22_01:44:24 PM waiting 1300 mSec
17/10/22_01:44:24 PM waiting 1400 mSec
17/10/22_01:44:24 PM waiting 1500 mSec
17/10/22_01:44:24 PM waiting 1600 mSec
17/10/22_01:44:24 PM waiting 1700 mSec
17/10/22_01:44:24 PM waiting 1800 mSec
17/10/22_01:44:24 PM waiting 1900 mSec
17/10/22_01:44:25 PM waiting 2000 mSec
17/10/22_01:44:25 PM usb drive NOT found
17/10/22_01:46:02 PM starting unlock and mount script
17/10/22_01:46:02 PM waiting 100 mSec
17/10/22_01:46:03 PM waiting 200 mSec
17/10/22_01:46:03 PM waiting 300 mSec
17/10/22_01:46:03 PM waiting 400 mSec
17/10/22_01:46:03 PM usb drive found
17/10/22_01:46:08 PM encrypted file system mounted
Now I have to install nfs on the test PC. The unlocked and mounted file system is supposed to be exported.

Ken
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
"service snmptrapd start" is failing with error "libnetsnmptrapd.so.31: undefined symbol: my_progname" ziaur25 Linux - Software 10 10-24-2018 10:29 PM
"nmcli con" failed "Can't obtain connections: settings service is not running." parcox Slackware 2 08-14-2012 04:26 PM
Logs filling up with "smbd/service.c:make_connection" - "couldn't find service" DumbTerminal Linux - Networking 14 07-16-2007 06:33 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 06:45 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration