diff --git a/man/crypttab.xml b/man/crypttab.xml index e933b2db782..d84a914a5e0 100644 --- a/man/crypttab.xml +++ b/man/crypttab.xml @@ -10,7 +10,7 @@ The Red Hat version has been written by Miloslav Trmac . --> - + crypttab @@ -413,9 +413,22 @@ - If the encryption password is read from - console, it has to be entered twice to prevent - typos. + If the encryption password is read from console, it has to be entered twice to + prevent typos. + + + + + + Takes a RFC7512 PKCS#11 URI + pointing to a private RSA key which is used to decrypt the key specified in the third column of the + line. This is useful for unlocking encrypted volumes through security tokens or smartcards. See below + for an example how to set up this mechanism for unlocking a LUKS volume with a YubiKey security + token. The specified URI can refer directly to a private RSA key stored on a token or alternatively + just to a slot or token in which case a suitable private RSA key object is automatically searched on + it. In this case if multiple suitable objects are found the token is refused. The key configured in + the third column is passed as is to RSA decryption. The resulting decrypted key is then base64 + encoded before it is used to unlock the LUKS volume. @@ -458,7 +471,7 @@ - Example + Examples /etc/crypttab example Set up four encrypted block devices. One using LUKS for @@ -471,6 +484,27 @@ truecrypt /dev/sda2 /etc/container_password tcrypt hidden /mnt/tc_hidden /dev/null tcrypt-hidden,tcrypt-keyfile=/etc/keyfile external /dev/sda3 keyfile:LABEL=keydev keyfile-timeout=10s + + + Yubikey-based Volume Unlocking Example + + The PKCS#11 logic allows hooking up any compatible security token that is capable of storing RSA + decryption keys. Here's an example how to set up a Yubikey security token for this purpose: + + + +A few notes on the above: + + + We use RSA (and not ECC), since Yubikeys support PKCS#11 Decrypt() only for RSA keys + We use RSA2048, which is the longest key size current Yubikeys support + LUKS key size must be shorter than 2048bit due to RSA padding, hence we use 128 bytes + We use Yubikey key slot 9d, since that's apparently the keyslot to use for decryption purposes, + see + documentation. + + + diff --git a/man/yubikey-crypttab.sh b/man/yubikey-crypttab.sh new file mode 100644 index 00000000000..b7e8ee686f9 --- /dev/null +++ b/man/yubikey-crypttab.sh @@ -0,0 +1,45 @@ +# Make sure noone can read the files we generate but us +umask 077 + +# Destroy any old key on the Yubikey (careful!) +ykman piv reset + +# Generate a new private/public key pair on the device, store the public key in 'pubkey.pem'. +ykman piv generate-key -a RSA2048 9d pubkey.pem + +# Create a self-signed certificate from this public key, and store it on the device. +ykman piv generate-certificate --subject "Knobelei" 9d pubkey.pem + +# Check if the newly create key on the Yubikey shows up as token in PKCS#11. Have a look at the output, and +# copy the resulting token URI to the clipboard. +p11tool --list-tokens + +# Generate a (secret) random key to use as LUKS decryption key. +dd if=/dev/urandom of=plaintext.bin bs=128 count=1 + +# Encode the secret key also as base64 text (with all whitespace removed) +base64 < plaintext.bin | tr -d '\n\r\t ' > plaintext.base64 + +# Encrypt this newly generated (binary) LUKS decryption key using the public key whose private key is on the +# Yubikey, store the result in /etc/encrypted-luks-key.bin, where we'll look for it during boot. +openssl rsautl -encrypt -pubin -inkey pubkey.pem -in plaintext.bin -out /etc/encrypted-luks-key.bin + +# Configure the LUKS decryption key on the LUKS device. We use very low pbkdf settings since the key already +# has quite a high quality (it comes directly from /dev/urandom after all), and thus we don't need to do much +# key derivation. +cryptsetup luksAddKey /dev/sda1 plaintext.base64 --pbkdf=pbkdf2 --pbkdf-force-iterations=1000 + +# Now securely delete the plain text LUKS key, we don't need it anymore, and since it contains secret key +# material it should be removed from disk thoroughly. +shred -u plaintext.bin plaintext.base64 + +# We don't need the public key anymore either, let's remove it too. Since this one is not security +# sensitive we just do a regular "rm" here. +rm pubkey.pem + +# Test: Let's run systemd-cryptsetup to test if this all worked. The option string should contain the full +# PKCS#11 URI we have in the clipboard, it tells the tool how to decypher the encrypted LUKS key. +systemd-cryptsetup attach mytest /dev/sda1 /etc/encrypted-luks-key.bin 'pkcs11-uri=pkcs11:…' + +# If that worked, let's now add the same line persistently to /etc/crypttab, for the future. +echo "mytest /dev/sda1 /etc/encrypted-luks-key 'pkcs11-uri=pkcs11:…' >> /etc/crypttab