LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Security (https://www.linuxquestions.org/questions/linux-security-4/)
-   -   How to pass password to cryptsetup from a memory variable? (https://www.linuxquestions.org/questions/linux-security-4/how-to-pass-password-to-cryptsetup-from-a-memory-variable-4175528760/)

taylorkh 12-19-2014 09:09 AM

How to pass password to cryptsetup from a memory variable?
 
I have a hard drive on my CentOS 6 system, not the OS drive, on which I have created a single partition encrypted with cryptsetup and luksOpen. Works fine. I mount it with this script
Code:

#!/bin/bash
sudo cryptsetup luksOpen /dev/sdc1 sdc1
sudo mount /dev/mapper/sdc1 /data/crypt
echo SSD Partition Attached - press enter
read nothing

The script allows cryptsetup to prompt me for the passphrase and then does the deed.

Performance has been quite robust and I like it so much I am considering encrypting a couple of other partitions. Not to get into a debate on passphrase philosophy... I prefer using one strong passphrase which I can remember for more than one partition rather than multiple phrases which I cannot remember and must write down. That said...

I am trying to figure out how to pass the passphrase to cryptsetup within my script. I would propose to prompt myself for the passphrase, store it in a memory variable, pass it to cryptsetup in order to open and mount each partition and then allow the passphrase to evaporate when the script exits. Problem is... I see in the man page how to use a key file to pass information to cryptsetup but not a memory variable. I do not want to write the passphrase into a file which I would then have to worry about protecting. Any suggestions?

TIA,

Ken

linosaurusroot 12-19-2014 09:41 AM

--key-file, -d name
Read the passphrase from file.

If the name given is "-", then the passphrase will be read from stdin. In this case, reading will not stop
at newline characters.

Something like this (untested)
Code:

#!/bin/bash

echo type passphrase
read pass

echo $pass | sudo cryptsetup luksOpen /dev/sdc1 sdc1  -d -
echo $pass | sudo cryptsetup luksOpen /dev/sdy1 sdy1  -d -
echo $pass | sudo cryptsetup luksOpen /dev/sdz1 sdz1  -d -

sudo mount /dev/mapper/sdc1 /data/crypt
sudo mount /dev/mapper/sdy1 /data/crimeplans
sudo mount /dev/mapper/sdz1 /data/sonydownloads

echo SSD Partitions Attached - press enter
read nothing


taylorkh 12-19-2014 09:58 AM

Thanks linosaurusroot,

That looks like it might do the trick. I don't do enough scripting these days (since I retired).

Ken

metaschima 12-19-2014 12:52 PM

I recommend not storing the password in a variable or a file, just let it prompt you for the password. You shouldn't need the --keyfile or -d option.

The main issue is what does bash do with your password when the script ends, I'll bet you it is still in RAM.

taylorkh 12-19-2014 01:45 PM

Granted the password may still be in RAM. However, the encrypted partition(s) will be accessible - protected only by my screen saver/password or ssh/password etc. When the PC is shut down the passphrase will no longer be in RAM (unless a black helicopter lands and the RAM is frozen with freon or something :eek:

I agree with not storing the passphrase in a file. However, with several partitions or files to unlock each time the PC is booted... cryptsetup probably saves it somewhere in RAM while it is doing its thing. It would potentially store it several times in RAM.

Ken

rknichols 12-19-2014 02:34 PM

Regardless of whether the passphrase is somewhere in RAM, all of the master keys are definitely in kernel memory and available to anyone with root access ("dmsetup table --showkeys ...") while the container is unlocked. cryptsetup does take pains to destroy any copies of keys or passphrases in its own memory space.

metaschima 12-19-2014 04:01 PM

Quote:

Originally Posted by rknichols (Post 5287694)
cryptsetup does take pains to destroy any copies of keys or passphrases in its own memory space.

Yes, while bash does not.

linosaurusroot 12-20-2014 10:59 AM

Quote:

Originally Posted by metaschima (Post 5287641)
I recommend not storing the password in a variable or a file, just let it prompt you for the password. You shouldn't need the --keyfile or -d option.

The main issue is what does bash do with your password when the script ends, I'll bet you it is still in RAM.

So your solution would be to extend cryptsetup to do multiple actions on one command-line requiring passphrase entry only once? That'd be a great patch if you posted it.

Miati 12-27-2014 10:20 AM

well... going off of linosaurusroot code and
Quote:

requiring passphrase entry only once?
Would this possibly work? I would suspect gpg would protect info. Dunno about a pipe however.
example.gpg contains a single line with newline of the password encrypted to my public key (thus only I can decrypt with my private key). Technically however, it can be anything in the file as long as it matches the password :)
The private key is locked, this makes a single password entry to unlock multiple times. It will be your private keys password you'll need to enter however.

Code:

#!/bin/bash

pass_file=example.gpg

gpg -d "$pass_file" | sudo cryptsetup luksOpen /dev/sdc1 sdc1  -d -
gpg -d "$pass_file" | sudo cryptsetup luksOpen /dev/sdy1 sdy1  -d -
gpg -d "$pass_file" | sudo cryptsetup luksOpen /dev/sdz1 sdz1  -d -

sudo mount /dev/mapper/sdc1 /data/crypt
sudo mount /dev/mapper/sdy1 /data/crimeplans
sudo mount /dev/mapper/sdz1 /data/sonydownloads

echo SSD Partitions Attached

Not sure why the worry about a variable stored in ram though. If you are actually worried about your password being stolen from ram, why not full disk encryption? Then use a single keyfile inside to unlock multiple others drives.

jtshoe 01-23-2018 12:36 PM

Adding a solution to this old thread, keeping in mind the possible security implications of storing the password in a bash variable. If the 'echo $pass' shown above is not working for you, it is because the echo command is also passing a newline at the end of $pass to cryptsetup, which causes the luksOpen to fail. It tries to open the drive with 'password\n' instead of 'password'. You need to tell echo to not include the newline:

Code:

echo -n $pass | sudo cryptsetup luksOpen /dev/sdc1 sdc1  -d -
Also, use 'read -s' to input the password, which will prevent the password from being displayed on the screen while typing.

taylorkh 01-23-2018 01:00 PM

Hello jtshoe and thanks for tickling this old thread. It is always interesting to look back and wonder "what was I thinking?" :D

My most recent approach to this issue is to use a passphrase to unlock the partitions. I have the passphrase stored on a zombie green USB flash drive (makes it easy to locate) which I plug in when I boot one of my serves. A script run as a systemctl one-time .service at startup will:

1 - look for the USB drive file system by its UUID
2 - if found it will mount it
3 - if the key is found on the mounted filesystem it will unlock and mount the encrypted file systems using the key
4 - unmount the flash drive file system

If the required flash drive or key is not present the server boots normally but the drives stay locked. I can remove the flash drive once the server is fully booted up. I can then hide, lock up, loose or swallow the flash drive. If a black helicopter shows up I can simply shut down the server(s) and when they are brought back up the data drives will remain locked.

Ken

RockT74 02-08-2018 05:22 AM

Would you mind sharing you one-time service script?
Would be very helpful, thx.

taylorkh 02-08-2018 05:34 AM

Let me get the pieces together and do a little write up - so I can remember what I did :D I will get it posted later today.

Ken

taylorkh 02-08-2018 07:42 AM

As requested, here is what I have at the moment. A key file is used to unlock the dmcrypt Luks encrypted partitions. The key file is stored on a particular flash drive with a specific UUID. This would prevent the key being placed on a random flash drive - unless the script was edited to reference the new UUID. I can of course clone the flash drive to another one with the same UUID by using Clonezilla or similar. All of this has nothing to do with anything as far as real security but it is an artifact from my original experimenting. As to what is actually happening...

My .service file is /usr/lib/systemd/system/unlock-n-mount.service and it contains
Quote:

[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=multiuser.target
The script referenced contains
Quote:

# This script, when run as root, will unlock and mount an encrypted file system
# Is the flash drive with the key present?
# UUID="219bfa8b-8cf2-4939-aafc-5d7fe55970be"

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/219bfa8b-8cf2-4939-aafc-5d7fe55970be"

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/219bfa8b-8cf2-4939-aafc-5d7fe55970be /keyhere

if [ -e /keyhere/taylor.key ]; then

# unlock the encrypted partion using the key file

cryptsetup luksOpen /dev/disk/by-uuid/02e6db96-e1ae-4c78-9085-fb9144c4f096 --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
Finally, here is a little sample of the log a success and a failure reported
Code:

17/11/05_09:37:15 AM starting unlock and mount script
17/11/05_09:37:15 AM waiting 100 mSec
17/11/05_09:37:15 AM waiting 200 mSec
17/11/05_09:37:15 AM waiting 300 mSec
17/11/05_09:37:15 AM usb drive found
17/11/05_09:37:21 AM encrypted file system mounted
17/11/05_11:03:59 AM starting unlock and mount script
17/11/05_11:03:59 AM waiting 100 mSec
17/11/05_11:03:59 AM waiting 200 mSec
17/11/05_11:03:59 AM waiting 300 mSec
17/11/05_11:04:00 AM waiting 400 mSec
17/11/05_11:04:00 AM waiting 500 mSec
17/11/05_11:04:00 AM waiting 600 mSec
17/11/05_11:04:00 AM waiting 700 mSec
17/11/05_11:04:00 AM waiting 800 mSec
17/11/05_11:04:00 AM waiting 900 mSec
17/11/05_11:04:00 AM waiting 1000 mSec
17/11/05_11:04:00 AM waiting 1100 mSec
17/11/05_11:04:00 AM waiting 1200 mSec
17/11/05_11:04:01 AM waiting 1300 mSec
17/11/05_11:04:01 AM waiting 1400 mSec
17/11/05_11:04:01 AM waiting 1500 mSec
17/11/05_11:04:01 AM waiting 1600 mSec
17/11/05_11:04:01 AM waiting 1700 mSec
17/11/05_11:04:01 AM waiting 1800 mSec
17/11/05_11:04:01 AM waiting 1900 mSec
17/11/05_11:04:01 AM waiting 2000 mSec
17/11/05_11:04:01 AM usb drive NOT found

The only concern I has is that, while it is unmounted, the flash drive is still powered up when the computer is fully booted to the gui (Mate desktop in this case.) I do not THINK that unplugging the flash drive presents any risk but I would rather have it powered down. The problem with USB is that it is so "plug and play" that if something is plugged in the system wants to play with it :rolleyes:

Bottom line, what I have presented does in fact work. Please feel free to ask if you have any questions - that helps me to learn as well.

Of course I had to enable the thing to make it run
Code:

systemctl enable unlock-n-mount
and to make sure
Code:

[ken@taylor15 system]$ systemctl status unlock-n-mount.service -l
● unlock-n-mount.service - Unlock and mount encrypted FS if thumb drive with key is present
  Loaded: loaded (/usr/lib/systemd/system/unlock-n-mount.service; enabled; vendor preset: disabled)
  Active: inactive (dead) since Tue 2018-01-09 08:49:45 EST; 10min ago
  Process: 605 ExecStart=/usr/sbin/unlock-n-mount.sh (code=exited, status=0/SUCCESS)
 Main PID: 605 (code=exited, status=0/SUCCESS)

Jan 09 08:49:39 taylor15 systemd[1]: Starting Unlock and mount encrypted FS if thumb drive with key is present...
Jan 09 08:49:45 taylor15 systemd[1]: Started Unlock and mount encrypted FS if thumb drive with key is present.

Ken


All times are GMT -5. The time now is 10:04 PM.