Rewrite README
A lot has changed, let's update the README even though it's not all done yet.
This commit is contained in:
parent
c89ff552d4
commit
8200c9668d
156
README.md
156
README.md
@ -1,133 +1,35 @@
|
|||||||
Disclaimer
|
# luksrku
|
||||||
==========
|
luksrku is a tool that allows you to remotely unlock LUKS disks during bootup
|
||||||
**Warning** luksrku is currently *highly* experimental software. It is not
|
from within your initrd. The intention is to have full-disk-encryption with
|
||||||
intended for production use yet. It is released following the "release early,
|
LUKS-rootfs running headlessly. You should be able to remotely unlock their
|
||||||
release often" philosophy in the hope to get valuable feedback for possible
|
LUKS cryptographic file systems when you know they have been (legitimately)
|
||||||
areas of improvement. Please only use it when you're pretty certain that you
|
rebooted.
|
||||||
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
|
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
|
||||||
luksrku is a tool that allows you to remotely unlock LUKS disks during bootup.
|
the address of the server or it can issue a broadcast in the network to find
|
||||||
The intention is to have headless systems running and you should be able to
|
the correct one. With the help of the shared secret, a TLS connection is
|
||||||
remotely unlock their LUKS cryptographic file systems when you know they have
|
established betweem the client and a legitimate server (who also knows the same
|
||||||
been (legitimately) rebooted. This works as follows: The *TLS server* runs on
|
secret). The server then tells the client all the LUKS passphrases, which
|
||||||
the computer which needs unlocking. This computer broadcasts a UDP packet onto
|
performs luksOpen on all volumes.
|
||||||
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).
|
|
||||||
|
|
||||||
Configuration
|
## Security
|
||||||
=============
|
luksrku uses TLSv1.3-PSK with forward-secrecy key shares (i.e., ECDHE). The
|
||||||
Clients and servers use a configuration file. This is originally a text file
|
curves that are used are X448 and X25519 for key agreement and
|
||||||
that is then converted to encrypted binary format using the luksrku-config
|
TLS_CHACHA20_POLY1305_SHA256 or TLS_AES_256_GCM_SHA384 as cipher suites. PSKs
|
||||||
tool. This binary configuration file is encrypted using AES256-GCM, uses a 128
|
are 256 bit long and randomly generated (/dev/urandom). Likewise, the LUKS
|
||||||
bit randomized initialization vector and authenticated with a 128 bit
|
passphrases are based on 256 bit long secrets and are converted to Base64 for
|
||||||
authentication tag. The key derivation function which is used to derive the 256
|
easier handling (when setting up everything initially).
|
||||||
bit AES key from the passphrase is scrypt with N = 131072, r = 8, p = 1.
|
|
||||||
|
|
||||||
Storing in a binary format serves two purposes:
|
The binary protocol that runs between both is intentionally extremely simple to
|
||||||
1. Error-prone parsing of human-modifiable text is done in a separate
|
allow for easy code review.
|
||||||
application. These chunks of code are not linked into the luksrku binary.
|
|
||||||
2. It allows for easy encryption.
|
|
||||||
|
|
||||||
The server key database contains no secrets, yet it is encrypted nevertheless.
|
The key database is encrypted itself, using AES256-GCM, a 128 bit randomized
|
||||||
The sole purpose is to keep the number of alternative code paths minimal. There
|
initialization vector and authenticated with a 128 bit authentication tag. Key
|
||||||
is no technical reason to encrypt the server configuration file, but again: it
|
derivation is done using scrypt with N = 131072 = 2^18, r = 8, p = 1.
|
||||||
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:
|
|
||||||
```
|
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
OpenSSL v1.1 is required for luksrku.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
TODO
|
||||||
|
Loading…
Reference in New Issue
Block a user