I'm kickstarting hosts to use LUKS - and as part of that, I've got a rather basic 'default' password in the kickstart file.

We 'finish' new builds via ansible, and so as part of this - I'd like to change the default luks password to something a little more robust (and managed via Ansible).

What I can't figure out though, is how I can use cryptsetup (or something else?) non-interactively to update the password.

I do want to keep using a password (and not a key file) - we're starting to deploy Clevis/Tang to do Network Bound Disk Encryption on root drives, and want to retain the password-to-boot option.

It seems

echo "oldpassphrase
newpassphrase" | cryptsetup luksAddKey /dev/sda2

Might do the trick, but it feels like a messy option?

3 Answers 3


It's possible to create a LUKS container non-interactively by using standard input as the key file: echo -n "mypassword" cryptsetup luksFormat --key-file - dev/sda2

But it's not possible to change the password non-interactively and without using key files because:

  1. cryptsetup does not accept passwords in the command line; It only accepts them from files and interactively; Probably to prevent leaking the password into your shell's history.
  2. Although you can use standard input as a key file, to add or change passwords you need to provide an existing password along with the new one; That's two inputs and there's only one standard input.

Option 1 - Use named pipes

Technically this requires a file, but the file is a named pipe, not a key file:

mkpipe fifo
echo -n "oldpass" | cryptsetup luksAddKey --key-file - test.img fifo &
echo -m "newpass" > fifo

The first command creates the named pipe, the second uses stdin to provide the original password and reads the new password from the pipe. This second command blocks, so the & puts it in the background. The third command writes the new password into the pipe, which allows cryptsetup to unblock and proceed.

Option 2 - Using the cryptsetup API

Cryptsetup is not only a utility, but also a library (libcryptsetup). You can use a function like crypt_keyslot_add_by_passphrase() in your own code to add a new password. This particular function accepts the existing and new password as char * (a string).

ct=$(cat /etc/crypttab)   
[[ $ct =~ ((sda[0-9])_crypt[[:blank:]]) ]] || _fail Could not find crypted partition  
echo Partition is $part

(echo "$existingPW"; echo "$newPW"; echo "$newPW") | cryptsetup luksAddKey $part

... takes a few seconds to complete.


Let's say you create a new volume as follows:

echo -n pass0 | cryptsetup luksFormat /dev/sda2 -

So the password in keyslot #0 is "pass0".

Next, you want to set the password in keyslot #1 to "pass1":

echo -n "pass0pass1" | cryptsetup luksAddKey --key-file /dev/stdin --keyfile-size 5 --key-slot 1 /dev/sda2 /dev/stdin

The length of the first password, "pass0", is 5 characters, and that's why you specify "--keyfile-size 5".

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .