How do I make cryptsetup automatically use a key file during mount time? - crypt

I am programmatically invoking cryptsetup and would like to pass in a key file on demand at the command line (not interactively).
How can I use cryptsetup with luks to take in a key file at the command line?

You need to create a keyfile:
dd if=/dev/random bs=32 count=1 of=/root/random_data_keyfile1
printf "YOUR PASSPHRASE" >/root/plaintext_passphrase_keyfile2
make the file read only to root:
sudo chmod 0400 /root/random_data_keyfile1
Add the key to LUKS:
cryptsetup luksAddKey /dev/sdX /root/random_data_keyfile1
You must add an entry to "/etc/crypttab":
echo "luks-$(cryptsetup luksUUID /dev/sdX) UUID=$(cryptsetup luksUUID /dev/sdX) /root/random_data_keyfile1" >>/etc/crypttab
reboot to make sure the device auto-unlocked. make sure you have the right device ID.
reference: https://access.redhat.com/solutions/1121163

Related

Shell script.....if error do this instead

At my home I have 2 PCs, my main windows gaming rig, and an ubuntu 13.04 file server. (NOT running ubuntu server just plain ubuntu)
I have the OS drive encrypted with luks (through installation)
But i have 5 Truecrypt ecrypted HDDs. They need to stay truecrypt for my needs. I have the following 2 scripts setup to mount my drives on boot of the PC.
This simple one to open terminal and run the next script-
#!/bin/bash
sleep 10
gnome-terminal -e /home/kun7/.TrueCrypt/mount_truecrypt_volumes.sh
And then the following code runs to get truecrypt password and mount drive to my specified points (needs to goto specified points for my other programs/libraries/shortcuts etc
#!/bin/bash
echo "Enter password ..."
oldConfig=`stty -g`
stty -echo
read password
stty $oldConfig
echo "Opening Pandora's Box ..."
truecrypt -t /dev/sdb5 /media/P --password="$password" -k "" --protect-hidden=no
truecrypt -t /dev/sda1 /media/B --password="$password" -k "" --protect-hidden=no
truecrypt -t /dev/sdd1 /media/M --password="$password" -k "" --protect-hidden=no
truecrypt -t /dev/sde1 /media/V --password="$password" -k "" --protect-hidden=no
truecrypt -t /dev/sdf /media/S --password="$password" -k "" --protect-hidden=no
echo "Drives mounted ... Close when ready"
exit 0
This works great for what I need. On occasion. My problem is that I have 2 drives connected via a PCI card. NORMALLY they are detected by the OS as sdb5 and sda1, but every now and then they get identified as sdc5 and sdd1.
This causes my script return...
Enter password ...
Opening Pandora's Box ...
Enter your user password or administrator password:
Error: No such file or directory:
/dev/sdb5
Incorrect password or not a TrueCrypt volume.
Enter password for /dev/sda1: Error: No such file or directory:
/dev/sdd1
Incorrect password or not a TrueCrypt volume.
Enter password for /dev/sdf:
What I'm wanting to do is to add an "if error" command at the end of my script to tell it. "If error, use this instead" and then list the alternate mount paths when the OS changes the drive points.
I think that makes sense.
I recommend you use the drives UUIDs instead.
You can get the drives UUID with:
$ sudo /sbin/blkid /dev/sda1
> /dev/sda1: UUID=<SOME-UUID-STRING> TYPE=<TYPE>
And with blkid -U <UUID> you query the device path. So in your script use this instead:
truecrypt -t $(/sbin/blkid -U <SOME-UUID-STRING>) /media/...
If you really prefer the "on error" approach:
function mount-truecrypt () {
local dev=$1
local mnt=$2
local alternative_dev=$3
truecrypt -t $dev $mnt --password="$password" -k "" --protect-hidden=no || \
truecrypt -t $alternative_dev $mnt --password="$password" -k "" --protect-hidden=no
}
mount-truecrypt /dev/sdb5 /media/P /dev/sdc5
Update:
Ok, UUIDs don't work because the partition table isn't available before decrypting with truecrypt and the devices are kind of random.
Here some tips for your udev rules: Writing udev rules might help you and this command:
sudo udevadm info -a -p $(sudo udevadm info -q path -n /dev/sda)
(From udevinfo) Gives you all the udev infos on your drives.
Though that's probably not easy either, since the partitions won't be available to udev either ..
But you could figure out where the main block device of you drive is by creating a symlink for the drive with a rule like this:
ATTRS{model}=="<MODEL>", ATTRS{serial}=="<SERIAL>", ACTION=="add", SYMLINK+="<my-symlink>"
Then /dev/ points to the device (/dev/sda or so) with readlink you can follow links like this:
readlink -f /dev/<my-symlink>
So you could try this in your script:
truecrypt "$(readlink -f /dev/<my-symlink>)1" <args>
To mount partition 1 on that drive. I'm not sure if it works, but mighht give you some ideas .
The problem is that for terminal/script mounting of drives through truecrypt your doing this:
truecrypt -t /dev/sda /media/Stuff
But if the /dev/sda change for each physical drive everytime you boot up, then this makes the script worthless. All links, and libraries are setup from /media/stuff which in turn rely on /dev/sda pointing to the same drive each time. So i need to make some persistent /dev/* points for truecrypt to use.
TIP: use udev to fond the info your using for matches, and make sure your setting completely random/customized /dev/*
Here is my current process for getting everything to work
1 - PC boots and takes rules from 10-custom-hdd-scsi.rules
2 - Login to Ubuntu where 1 script open terminal and then runs "3"
3 - Truecrypt script prompts for password, and mounts drives to specified mount points allowing for links/libraries to work.
First run - sudo /lib/udev/scsi_id --page=0x83 --whitelisted --device=/dev/sda and copy the result down. Do it for each drive you have, and you`ll have the Drives scsi id
10-custom-hdd-scsi.rules - This file has been saved in /etc/udev/rules.d
# These are the rules to force all drives into specific /dev/sd** slots for truecrypt mounting
#
#KERNELS - looks upwards in device path to find
#PROGRAM - Runs this. It is a serch for WWID (world wide ID)
#RESULT - This is the result its looking for. It is the specific Drives ID
#SYMLINK - Create the following link (i.e. personal /dev/***)
#
# "==" means match this
# "+=" means if it exists, do this aswell
#
KERNEL=="sd*", PROGRAM=="/lib/udev/scsi_id --page=0x83 --whitelisted --device=/dev/%k", RESULT=="<DRIVES ID>", SYMLINK+="TC-a%n"
KERNEL=="sd*", PROGRAM=="/lib/udev/scsi_id --page=0x83 --whitelisted --device=/dev/%k", RESULT=="<DRIVES ID>", SYMLINK+="TC-b%n"
KERNEL=="sd*", PROGRAM=="/lib/udev/scsi_id --page=0x83 --whitelisted --device=/dev/%k", RESULT=="<DRIVES ID>", SYMLINK+="TC-c%n"
KERNEL=="sd*", PROGRAM=="/lib/udev/scsi_id --page=0x83 --whitelisted --device=/dev/%k", RESULT=="<DRIVES ID>", SYMLINK+="TC-d%n"
KERNEL=="sd*", PROGRAM=="/lib/udev/scsi_id --page=0x83 --whitelisted --device=/dev/%k", RESULT=="<DRIVES ID>", SYMLINK+="TC-e%n"
BANG - custom udev rules to create a link for each drive. so now you`ll have the standard /dev/sd** that change everytime, AND /dev/TC-a that will stay the same.
First script to open terminal
#!/bin/bash
gnome-terminal -e /home/kun7/.TrueCrypt/mount_truecrypt_volumes.sh
And now the script telling truecrypt to mount your drives
#!/bin/bash
echo "Enter password ..."
oldConfig=`stty -g`
stty -echo
read password
stty $oldConfig
echo "Opening Pandora's Box ..."
truecrypt -t /dev/TC-a /media/E --password="$password" -k "" --protect-hidden=no
truecrypt -t /dev/TC-b /media/D --password="$password" -k "" --protect-hidden=no
truecrypt -t /dev/TC-c /media/C --password="$password" -k "" --protect-hidden=no
truecrypt -t /dev/TC-d /media/B --password="$password" -k "" --protect-hidden=no
truecrypt -t /dev/TC-e /media/A --password="$password" -k "" --protect-hidden=no
echo "Drives mounted ... Close when ready"
exit 0
-Now you'll boot up the PC, login, and get a terminal asking you for your truecrypt password.
-Type it in.
-And then you`ll be asked for your user password.
-The script will run, your drives will be mounted.
-And you now have continuous persistent mount point for your drives.

How to overwrite the asking for authentication when running an admin shell script in Apple Script?

I'm wanting to make a simple program that runs each time on login behind the UI. In my applescript I'm running a sudo command that requires admin authentication. Is there a way to overwrite the need for authentication each time it runs? I don't want to have to type my username and password each time this script runs after login. any help? (and in very simple terms to as I'm a novice.)
Much Thanks!
You can put your username and password in the applescript command so that it doesn't ask for those credentials. However note that these items are stored as plain text inside the applescript and thus it's possible for others to see them. It's not really secure but it's up to you to decide if it's safe. NOTE: you don't need "sudo" in the command any longer.
do shell script "whatever" user name "username" password "password" with administrator privileges
There are methods where you can store your password in the Keychain and retrieve it from the applescript, thus making it secure. If you want to do that then you create the password item as follows.
Open Keychain Access application and select the keychain in the left column. Then click File>New Password Item..., give it a name, put your account shortname in account, and enter the password. Highlight it in the password list and get information on it. Under the Attributes button enter its kind as generic key. This is chosen because there aren't many of them and the search is much faster. Whatever name you give to it must be put in the code below in "Your Password Name".
Now from applescript you can use it like this...
set myPass to getPW()
do shell script "whatever" user name "username" password myPass with administrator privileges
on getPW()
do shell script "security 2>&1 >/dev/null find-generic-password -gl \"Your Password Name\" | awk '{print $2}'"
return (text 2 thru -2 of result)
end getPW
Good luck!
Another solution is editing the
etc/sudoers
configuration file.
A setting on that file can allow a specific user to execute a specific commands (with... yes... specific parameters) as super user.
If the command itself is not the problem, but the problem is exposing the password in the code then this may be the solution.
The sudores file should be edited running the command visudo as super user.
Before you start tampering with sudoers I strongly suggest you to get a basic knowledge of visudo and the sudoers syntax, as messing that file may causes serius issues to the system.
As you know what you are doing is just a matter of adding a couple of lines.
For information you may Google or start here http://www.sudo.ws/sudoers.man.html
If you want all Administrator accounts to be able to use the sudo command without entering a password, then do the following.
Change the line shown below in the /private/etc/sudoers file from
%admin ALL=(ALL) ALL
to
%admin ALL=(ALL) NOPASSWD: ALL
This edit can be accomplished, by using the Terminal and TextEdit applications. Open the Terminal application and type the following commands:
cd ~/desktop
sudo cp -n /etc/sudoers /etc/sudoers.orignal
sudo cp /etc/sudoers sudoers.txt
sudo chmod ug+w sudoers.txt
open sudoers.txt
visudo -c -f sudoers.txt
sudo cp -X sudoers.txt /etc/sudoers
When done, the sudoers.txt file on your desktop can be put in the trash.
To undo your changes, use the command:
sudo cp /etc/sudoers.original /etc/sudoers
This was tested using OS X 10.10.1
If you want to do the same for a single user then see:
http://hints.macworld.com/article.php?story=20021202054815892
Below is a brief explanation of what each command does:
cd ~/desktop
This makes sure you are working from your desktop folder.
sudo cp -n /etc/sudoers /etc/sudoers.original
This backups your sudoers file. The backup can be used to undo your changes. The -n option insures that an existing sudoers.original file will not be overwritten.
sudo cp /etc/sudoers sudoers.txt
Copies the sudoers file to your desktop. The .txt extension is added so OS X will know this is a text file.
sudo chmod ug+w sudoers.txt
Changes the file’s permissions to allow write access.
open sudoers.txt
Opens the file in the TextEdit application. You need to edit the file and save the changes.
visudo -c -f sudoers.txt
Checks the edited file for syntax errors. The output should be sudoers.txt: parsed OK.
sudo cp -X sudoers.txt /etc/sudoers
Copies the file back to the /etc directory.

Specify private key in SSH as string

I can connect to a server via SSH using the -i option to specify the private key:
ssh -i ~/.ssh/id_dsa user#hostname
I am creating a script that takes the id_dsa text from the database but I am not sure how I can give that string to SSH. I would need something like:
ssh --option $STRING user#hostname
Where $STRING contains the value of id_dsa. I need to know the --option if there is one.
Try the following:
echo $KEY | ssh -i /dev/stdin username#host command
The key doesn't appear from a PS statement, but because stdin is redirected it's only useful for single commands or tunnels.
There is no such switch - as it would leak sensitive information. If there were, anyone could get your private key by doing a simple ps command.
EDIT: (because of theg added details in comment)
You really should store the key in to a temporary file. Make sure you set the permissions correctly before writing to the file, if you do not use command like mktemp to create the temporary file.
Make sure you run the broker (or agent in case of OpenSSH) process and load the key using <whatever command you use to fetch it form the database> | ssh-add -
Passing cryptokey as a string is not advisable but for the sake of the question, I would say I came across the same situation where I need to pass key as a string in a script. I could use key stored in a file too but the nature of the script is to make it very flexible, containing everything in itself was a requirement. so I used to assign variable and pass it and echo it as follows :
#!/bin/bash
KEY="${ YOUR SSH KEY HERE INSIDE }"
echo "${KEY}" | ssh -q -i /dev/stdin username#IP 'hostnamectl'
exit 0
Notes:
-q suppress all warnings
By the way , the catch here in above script, since we are using echo it will print the ssh key which is again not recommended , to hide that you can use grep to grep some anything which will not be printed for sure but still stdin will have the value from the echo. So the final cmd can be modified as follows :
#!/bin/bash
KEY="${ YOUR SSH KEY HERE INSIDE }"
echo "${KEY}" | grep -qw "less" | ssh -q -i /dev/stdin username#IP 'hostnamectl'
exit 0
This worked for me.
I was looking at the same problem. Adding private key content to ssh command via stdin did not work for me. I found out that its possible to add the private key file contents to ssh-agent using the command ssh-add. This will let you ssh into the remote host without explicitly specifying the identity file. My particular usecase was that I didn't want to store the SSH key in cleartext on my machine and was dynamically getting it from a secrets vault. This answer is mostly a collection of other answers on StackOverflow.
ssh-agent is a program to hold private keys used for public key
authentication. Through use of environment variables the agent can
be located and automatically used for authentication when logging
in to other machines using ssh
Source
This is what I have done.
First start the ssh-agent.
You can start it from your terminal by simply executing ssh-agent.
OPTIONAL: If you'd like to make sure ssh-agent is running on every login, you can add something like the following to your shell config.
This is what I have added to my ~/.bashrc file.
# set SSH_AUTH_SOCK env var to a fixed value
export SSH_AUTH_SOCK=~/.ssh/ssh-agent.sock
# test whether $SSH_AUTH_SOCK is valid
ssh-add -l 2>/dev/null >/dev/null
# if not valid, then start ssh-agent using $SSH_AUTH_SOCK
[ $? -ge 2 ] && ssh-agent -a "$SSH_AUTH_SOCK" >/dev/null
Source
(This particular snippet also makes sure new ssh-agent processes are not getting created when there's one already running.)
Now you have the ssh-agent running.
Since we're interested in loading SSH key as a string, I'll assume a scenario where private key contents has already been loaded in to a variable, $SSH_PRIVATE_KEY.
I can now add this Key contents to the ssh-agent by executing the following command.
ssh-add - <<< "${SSH_PRIVATE_KEY}"
This can just be added to the bashrc file as well.
You can confirm that your key has been added by listing all keys by executing ssh-agent -l. Aaand you're done now.
Try connecting to the remote host and you don't need a private key file.
ssh username#hostname
This does come with extra security risks. These are some I could think of:
Adding the private key to the ssh-agent will let any process on the machine access the key to authenticate remote hosts without explicitly providing any information.
Since the goal is to load Private key as a string, it will either be stored in a variable or the contents embedded directly in the command. This might make the key available in command history, the shell variable and other places.

How to check for usb device with if statement in bash

I'm attempting to create an automated bash script that fills up a file with urandom in the unit's flash storage. I can manually use all of the commands to make this happen, but I'm trying to create a script and having difficulty figuring out how to check for the usb device. I know that it will be either sda1 or sdb1, but not sure if the code below is sufficient ...? Thanks! Below, is the code:
if /dev/sda1
then
mount -t vfat /dev/sda1 /media/usbkey
else
mount -t vfat /dev/sdb1 /media/usbkey
fi
The way I script mountable drives is to first put a file on the drive, e.g. "Iamthemountabledrive.txt", then check for the existence of that file. If it isn't there, then I mount the drive. I use this technique to make sure an audio server is mounted for a 5 radio station network, checking every minute in case there is a network interrupt event.
testfile="/dev/usbdrive/Iamthedrive.txt"
if [ -e "$testfile" ]
then
echo "drive is mounted."
fi
You can mount by label or UUID and hence reduce the complexity of your script. For example if your flash storage has label MYLABEL (you can set and display VFAT labels using mtools' mlabel):
$ sudo mount LABEL=MYLABEL /media/usbkey

How to provide password to a command that prompts for one in bash?

I'm writing a UNIX shell function that is going to execute a command that will prompt the user for a password. I want to hard-code the password into the script and provide it to the command. I've tried piping the password into the command like this:
function() {
echo "password" | command
}
This may not work for some commands as the command may flush the input buffer before prompting for the password.
I've also tried redirecting standard input to a file containing the password like this, but that doesn't work either:
function() {
echo "password" > pass.tmp
command < pass.tmp
rm pass.tmp
}
I know that some commands allow for the password to be provided as an argument, but I'd rather go through standard input.
I'm looking for a quick and dirty way of piping a password into a command in bash.
How to use autoexpect to pipe a password into a command:
These steps are illustrated with an Ubuntu 12.10 desktop. The exact commands for your distribution may be slightly different.
This is dangerous because you risk exposing whatever password you use to anyone who can read the autoexpect script file.
DO NOT expose your root password or power user passwords by piping them through expect like this. Root kits WILL find this in an instant and your box is owned.
EXPECT spawns a process, reads text that comes in then sends text predefined in the script file.
Make sure you have expect and autoexpect installed:
sudo apt-get install expect
sudo apt-get install expect-dev
Read up on it:
man expect
man autoexpect
Go to your home directory:
cd /home/el
User el cannot chown a file to root and must enter a password:
touch testfile.txt
sudo chown root:root testfile.txt
[enter password to authorize the changing of the owner]
This is the password entry we want to automate. Restart the terminal to ensure that sudo asks us for the password again. Go to /home/el again and do this:
touch myfile.txt
autoexpect -f my_test_expect.exp sudo chown root:root myfile.txt
[enter password which authorizes the chown to root]
autoexpect done, file is my_test_expect.exp
You have created my_test_expect.exp file. Your super secret password is stored plaintext in this file. This should make you VERY uncomfortable. Mitigate some discomfort by restricting permissions and ownership as much as possible:
sudo chown el my_test_expect.exp //make el the owner.
sudo chmod 700 my_test_expect.exp //make file only readable by el.
You see these sorts of commands at the bottom of my_test_expect.exp:
set timeout -1
spawn sudo chown root:root myfile.txt
match_max 100000
expect -exact "\[sudo\] password for el: "
send -- "YourPasswordStoredInPlaintext\r"
expect eof
You will need to verify that the above expect commands are appropriate. If the autoexpect script is being overly sensitive or not sensitive enough then it will hang. In this case it's acceptable because the expect is waiting for text that will always arrive.
Run the expect script as user el:
expect my_test_expect.exp
spawn sudo chown root:root myfile.txt
[sudo] password for el:
The password contained in my_test_expect.exp was piped into a chown to root by user el. To see if the password was accepted, look at myfile.txt:
ls -l
-rw-r--r-- 1 root root 0 Dec 2 14:48 myfile.txt
It worked because it is root, and el never entered a password. If you expose your root, sudo, or power user password with this script, then acquiring root on your box will be easy. Such is the penalty for a security system that lets everybody in no questions asked.
Take a look at autoexpect (decent tutorial HERE). It's about as quick-and-dirty as you can get without resorting to trickery.
You can use the -S flag to read from std input. Find below an example:
function shutd()
{
echo "mySuperSecurePassword" | sudo -S shutdown -h now
}
Secure commands will not allow this, and rightly so, I'm afraid - it's a security hole you could drive a truck through.
If your command does not allow it using input redirection, or a command-line parameter, or a configuration file, then you're going to have to resort to serious trickery.
Some applications will actually open up /dev/tty to ensure you will have a hard time defeating security. You can get around them by temporarily taking over /dev/tty (creating your own as a pipe, for example) but this requires serious privileges and even it can be defeated.
with read
Here's an example that uses read to get the password and store it in the variable pass. Then, 7z uses the password to create an encrypted archive:
read -s -p "Enter password: " pass && 7z a archive.zip a_file -p"$pass"; unset pass
But be aware that the password can easily be sniffed.
Programs that prompt for passwords usually set the tty into "raw" mode, and read input directly from the tty. If you spawn the subprocess in a pty you can make that work. That is what Expect does...
Simply use :
echo "password" | sudo -S mount -t vfat /dev/sda1 /media/usb/;
if [ $? -eq 0 ]; then
echo -e '[ ok ] Usb key mounted'
else
echo -e '[warn] The USB key is not mounted'
fi
This code is working for me, and its in /etc/init.d/myscriptbash.sh
That's a really insecure idea, but:
Using the passwd command from within a shell script

Resources