From 8200c9668df710a30892044ac57a075f9005ca25 Mon Sep 17 00:00:00 2001 From: Johannes Bauer Date: Wed, 23 Oct 2019 16:13:23 +0200 Subject: [PATCH] Rewrite README A lot has changed, let's update the README even though it's not all done yet. --- README.md | 156 ++++++++++-------------------------------------------- 1 file changed, 29 insertions(+), 127 deletions(-) diff --git a/README.md b/README.md index 398fafa..56fb7b6 100644 --- a/README.md +++ b/README.md @@ -1,133 +1,35 @@ -Disclaimer -========== -**Warning** luksrku is currently *highly* experimental software. It is not -intended for production use yet. It is released following the "release early, -release often" philosophy in the hope to get valuable feedback for possible -areas of improvement. Please only use it when you're pretty certain that you -know what you're doing. Better yet, only use it after code review. If you've -reviewed my code, please let me know. I'm very interested in any and all -feedback. Drop it at joe@johannes-bauer.com, please. Thanks! +# luksrku +luksrku is a tool that allows you to remotely unlock LUKS disks during bootup +from within your initrd. The intention is to have full-disk-encryption with +LUKS-rootfs running headlessly. You should be able to remotely unlock their +LUKS cryptographic file systems when you know they have been (legitimately) +rebooted. -luksrku -======= -luksrku is a tool that allows you to remotely unlock LUKS disks during bootup. -The intention is to have headless systems running and you should be able to -remotely unlock their LUKS cryptographic file systems when you know they have -been (legitimately) rebooted. This works as follows: The *TLS server* runs on -the computer which needs unlocking. This computer broadcasts a UDP packet onto -the network indicating that it needs unlocking. The *TLS client* which knows -the LUKS passphrase then catches that packet, connect to the server and sends -the passphrase. The TLS configuration that is used ensures mutual -authentication and perfect forward secrecy. Concretely, TLS v1.2 is used with a -ECDHE handshake on Curve25519 and using the ECDHE-PSK-CHACHA20-POLY1305 cipher -suite. For authentication, a 256 bit long random PSK is used. The passphrase -for unlocking should be in a own keyslot (i.e., do not use a passphrase which -you remember). +This works as follows: The luksrku client (which needs unlocking) and luksrku +server (which holds all the LUKS keys) share a secret. The client either knows +the address of the server or it can issue a broadcast in the network to find +the correct one. With the help of the shared secret, a TLS connection is +established betweem the client and a legitimate server (who also knows the same +secret). The server then tells the client all the LUKS passphrases, which +performs luksOpen on all volumes. -Configuration -============= -Clients and servers use a configuration file. This is originally a text file -that is then converted to encrypted binary format using the luksrku-config -tool. This binary configuration file is encrypted using AES256-GCM, uses a 128 -bit randomized initialization vector and authenticated with a 128 bit -authentication tag. The key derivation function which is used to derive the 256 -bit AES key from the passphrase is scrypt with N = 131072, r = 8, p = 1. +## Security +luksrku uses TLSv1.3-PSK with forward-secrecy key shares (i.e., ECDHE). The +curves that are used are X448 and X25519 for key agreement and +TLS_CHACHA20_POLY1305_SHA256 or TLS_AES_256_GCM_SHA384 as cipher suites. PSKs +are 256 bit long and randomly generated (/dev/urandom). Likewise, the LUKS +passphrases are based on 256 bit long secrets and are converted to Base64 for +easier handling (when setting up everything initially). -Storing in a binary format serves two purposes: - 1. Error-prone parsing of human-modifiable text is done in a separate - application. These chunks of code are not linked into the luksrku binary. - 2. It allows for easy encryption. +The binary protocol that runs between both is intentionally extremely simple to +allow for easy code review. -The server key database contains no secrets, yet it is encrypted nevertheless. -The sole purpose is to keep the number of alternative code paths minimal. There -is no technical reason to encrypt the server configuration file, but again: it -contains *no* secrets. Using the same storage for server and client was maybe -an awkward design choice, but this is something that is ugly, but not -security-critical. - -The client key database contains the LUKS keys, therefore it is advisable to -keep it encrypted with a passphrase. Only if this passphrase is correctly -entered on the client, the password can be decrypted on the client and -transmitted to the server. Note that care is taken to ensure no -length-of-message side channels reveal information about the underlying LUKS -passphrase. Therefore the transmitted messages are always of the same length. - -The PSK that is used to communicate between client and server ensures mutual -authentication. If the PSK is stolen by an adversary, that adversary can simply -pose as a server and ask the client for the LUKS key. Therefore it is integral -that this PSK is kept safe. Passive attacks (i.e., where the adversary is only -eavesdropping on communication), however, are not compromised because the TLS -channel provides PFS. - -Prerequisites -============= -Since the used cryptography (such as ECDH on Curve25519 and the -ECDHE-PSK-CHACHA20-POLY1305 cipher suite) are fairly new, support for at least -OpenSSL-1.1.0 is essential. - - -Example -======= -This is a very crude example. Feel free to improve it and send a PR. Let's say -we want to unlock the crypt-root of a headless system. I.e., only one LUKS -partition that should be unlocked. That LUKS partition has the UUID of -952ebed9-5256-4b4c-9de5-7f8829b4a74a (use blkid to find out). This is what we -can do: - - 1. Build >=OpenSSL-1.1.0 (e.g., using the provided ./build_openssl command) - 2. Build and install luksrku: make && sudo make install - 3. Generate the keyfiles. For this we use the provided gen_config script: - -``` -Disk UUID : 952ebed9-5256-4b4c-9de5-7f8829b4a74a -Disk name : crypt-root -Suggestion: TDFV6Z6XyDQ52ASswVFSEl8mrVfnH9F5b -Passphrase: - -Disk UUID : -# server.txt -# Host UUID Host PSK Disk UUIDs -d66f96fc-7056-46e1-aea6-0f3d705cd3bc d94f3fc6c3507123bda4034dd8c865a1b4cf9870bda50e9ed9f861621d581017 952ebed9-5256-4b4c-9de5-7f8829b4a74a=crypt-root - -# client.txt -# Host UUID Host PSK Disk UUIDs -d66f96fc-7056-46e1-aea6-0f3d705cd3bc d94f3fc6c3507123bda4034dd8c865a1b4cf9870bda50e9ed9f861621d581017 952ebed9-5256-4b4c-9de5-7f8829b4a74a=54444656365a3658794451353241537377564653456c386d7256666e4839463562 -``` - - 4. We want to use the suggested passphrase, which should contain 192 bits of - entropy. For this, ee use cryptsetup luksAddKey to add the suggested - passphrase to the LUKS keyring on the server. - 5. The config script has given suggestions for server.txt and client.txt. We - copy the respective contents into the files. - 6. Then we create the client and server binary configuration files: - -``` -$ luksrku-config server server.txt server.bin -Successfully read key file with 1 entries. -$ luksrku-config client client.txt client.bin -Successfully read key file with 1 entries. -Passphrase to encrypt keyfile: -``` - - 7. Now we'll have a server.bin and password-protected client.bin. On the - server machine (i.e., the one with the LUKS disk) we copy server.bin to - /etc/luksrku-server.bin. - 8. On the server, we modify the luksrku-script in the initramfs/ subdirectory - to fit the NIC of the server and the IP address we want (this is really - ugly at the moment and needs to be fixed ASAP, but it is what it is now). - 9. On the server, then run the "./install" script as root which will install - initramfs hooks. - 10. On the server, update the initramfs (update-initramfs -u). Previously make - a copy of your initramfs so that you can boot your system in case things - go wrong (which they will, trust me). - 11. Boot the server. If everything went fine (it won't at the first run), it - will now broadcast UDP packets onto the network indicating its presence. - These packets will be sent to UDP port 23170. - 12. On the client, start the client to unlock the server's key: - -``` -$ luksrku --client-mode -k client.bin -Keyfile password: -``` +The key database is encrypted itself, using AES256-GCM, a 128 bit randomized +initialization vector and authenticated with a 128 bit authentication tag. Key +derivation is done using scrypt with N = 131072 = 2^18, r = 8, p = 1. +## Dependencies +OpenSSL v1.1 is required for luksrku. +## Example +TODO