Go to file
Johannes Bauer 5400e3716a Documentation of usage
Added documentation of simple usage and also integration into initramfs.
2019-10-25 18:39:10 +02:00
codegen Cleanups 2016-09-24 20:14:53 +02:00
initramfs Adapt initramfs hooks 2019-10-25 13:06:20 +02:00
parsers Implemented finding of keyserver and unlocking of volumes 2019-10-25 11:08:20 +02:00
testdata Unlocking LUKS volumes works 2019-10-25 12:19:01 +02:00
.gitignore Integrate editor properly from command line 2019-10-23 11:34:40 +02:00
argparse_client.c Implemented finding of keyserver and unlocking of volumes 2019-10-25 11:08:20 +02:00
argparse_client.h Implemented finding of keyserver and unlocking of volumes 2019-10-25 11:08:20 +02:00
argparse_edit.c Implemented finding of keyserver and unlocking of volumes 2019-10-25 11:08:20 +02:00
argparse_edit.h Implemented finding of keyserver and unlocking of volumes 2019-10-25 11:08:20 +02:00
argparse_server.c Implemented finding of keyserver and unlocking of volumes 2019-10-25 11:08:20 +02:00
argparse_server.h Implemented finding of keyserver and unlocking of volumes 2019-10-25 11:08:20 +02:00
blacklist.c Unlocking LUKS volumes works 2019-10-25 12:19:01 +02:00
blacklist.h Unlocking LUKS volumes works 2019-10-25 12:19:01 +02:00
ChangeLog Release v0.02 2019-10-19 15:08:30 +02:00
client.c Vaulted key database fully used 2019-10-25 18:17:43 +02:00
client.h Add client code back in 2019-10-23 20:13:25 +02:00
editor.c Vault creation works 2019-10-25 17:18:09 +02:00
editor.h Started with server implementation 2019-10-23 13:18:51 +02:00
exec.c Refactor command execution to not use tempfile 2019-10-25 13:02:35 +02:00
exec.h Refactor command execution to not use tempfile 2019-10-25 13:02:35 +02:00
file_encryption.c Implemented export of key database 2019-10-21 22:47:58 +02:00
file_encryption.h Fix default KDF 2019-10-25 13:33:48 +02:00
global.h Unlocking LUKS volumes works 2019-10-25 12:19:01 +02:00
keydb.c Vaulted keydb should work, but it's not used yet 2019-10-25 17:46:21 +02:00
keydb.h Vaulted keydb should work, but it's not used yet 2019-10-25 17:46:21 +02:00
LICENSE LICENSE added (GPLv3) 2016-09-22 20:47:43 +02:00
LICENSE-header LICENSE added (GPLv3) 2016-09-22 20:47:43 +02:00
licensify Script to add LICENSE headers to all files 2016-09-22 20:48:11 +02:00
log.c TLS-PSK now taken out of secure vault, but LUKS passphrases not 2019-10-25 18:02:51 +02:00
log.h Client and server commnunication now works 2019-10-23 21:54:10 +02:00
luks.c Refactor command execution to not use tempfile 2019-10-25 13:02:35 +02:00
luks.h Refactor command execution to not use tempfile 2019-10-25 13:02:35 +02:00
luksrku-config.c LICENSE added (GPLv3) 2016-09-22 20:47:43 +02:00
luksrku.c More disabled code removal 2019-10-24 16:57:35 +02:00
Makefile Documentation of usage 2019-10-25 18:39:10 +02:00
msg.h Receiving broadcast messages and plausibility-checking 2019-10-25 09:33:20 +02:00
openssl.c Consolidated session establishment for client and server 2019-10-23 22:06:47 +02:00
openssl.h Consolidated session establishment for client and server 2019-10-23 22:06:47 +02:00
pgmopts.c Remove debugging and set default timeout 2019-10-25 13:24:08 +02:00
pgmopts.h Implemented finding of keyserver and unlocking of volumes 2019-10-25 11:08:20 +02:00
README.md Documentation of usage 2019-10-25 18:39:10 +02:00
server.c Vaulted key database fully used 2019-10-25 18:17:43 +02:00
server.h Add client code back in 2019-10-23 20:13:25 +02:00
signals.c Client and server commnunication now works 2019-10-23 21:54:10 +02:00
signals.h Client and server commnunication now works 2019-10-23 21:54:10 +02:00
thread.c Added detached thread handling code 2019-10-23 19:47:26 +02:00
thread.h Added detached thread handling code 2019-10-23 19:47:26 +02:00
udp.c Unlocking LUKS volumes works 2019-10-25 12:19:01 +02:00
udp.h Implemented finding of keyserver and unlocking of volumes 2019-10-25 11:08:20 +02:00
util.c Implemented finding of keyserver and unlocking of volumes 2019-10-25 11:08:20 +02:00
util.h Implemented finding of keyserver and unlocking of volumes 2019-10-25 11:08:20 +02:00
uuid.c Further work on creating correct type-4 UUIDs 2019-10-20 17:45:21 +02:00
uuid.h Implement actual lookup of luksrku entry 2019-10-23 15:28:38 +02:00
vault.c Vault creation works 2019-10-25 17:18:09 +02:00
vault.h Make vault threadsafe 2019-10-25 16:30:46 +02:00
vaulted_keydb.c Documentation of usage 2019-10-25 18:39:10 +02:00
vaulted_keydb.h Vaulted key database fully used 2019-10-25 18:17:43 +02:00

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.

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.

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).

The binary protocol that runs between both is intentionally extremely simple to allow for easy code review. It exclusively uses fixed message lengths.

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 = 262144 = 2^18, r = 8, p = 1.

When not in use, the server encrypts all LUKS passphrases and PSKs in-memory. A large, 1 MiB pre-key is also kept in memory. This is to thwart cold-boot attacks, because a successful cold-boot attack would require a complete and perfect 1 MiB snapshot of the pre-key (or an acquisition in the short timeframe where the keyvault is open) something that is difficult to do because of naturally occuring bit errors during cold boot acquisition.

Dependencies

OpenSSL v1.1 is required for luksrku as well as pkg-config.

Usage

The help pages of luksrku are fairly well documented, i.e.:

$ ./luksrku
error: no command supplied

Available commands:
    ./luksrku edit     Interactively edit a key database
    ./luksrku server   Start a key server process
    ./luksrku client   Unlock LUKS volumes by querying a key server

For futher help: ./luksrku (command) --help

luksrku version v0.02-45-gf01ec97d6b-dirty

Then, for each command, you have an own help page:

$ ./luksrku edit --help
usage: luksrku edit [-v] [filename]

Edits a luksrks key database.

positional arguments:
  filename       Database file to edit.

optional arguments:
  -v, --verbose  Increase verbosity. Can be specified multiple times.
$ ./luksrku server --help
usage: luksrku server [-p port] [-s] [-v] filename

Starts a luksrku key server.

positional arguments:
  filename              Database file to load keys from.

optional arguments:
  -p port, --port port  Port that is used for both UDP and TCP communication.
                        Defaults to 23170.
  -s, --silent          Do not answer UDP queries for clients trying to find a
                        key server, only serve key database using TCP.
  -v, --verbose         Increase verbosity. Can be specified multiple times.
$ ./luksrku client --help
usage: luksrku client [-t secs] [-p port] [--no-luks] [-v] filename [hostname]

Connects to a luksrku key server and unlocks local LUKS volumes.

positional arguments:
  filename              Exported database file to load TLS-PSKs and list of
                        disks from.
  hostname              When hostname is given, auto-searching for suitable
                        servers is disabled and only a connection to the given
                        hostname is attempted.

optional arguments:
  -t secs, --timeout secs
                        When searching for a keyserver and not all volumes can
                        be unlocked, abort after this period of time, given in
                        seconds. Defaults to 60 seconds.
  -p port, --port port  Port that is used for both UDP and TCP communication.
                        Defaults to 23170.
  --no-luks             Do not call LUKS/cryptsetup. Useful for testing
                        unlocking procedure.
  -v, --verbose         Increase verbosity. Can be specified multiple times.

Example

First, you need to create a server key database. For this you use the editor:

$ ./luksrku edit
> add_host my_host

Now theres a host “my_host” in the key database. At any point you can inspect the database by using the “list” command:

Keydb version 2, server database, 1 hosts.
    Host 1: "my_host" UUID e7ff6e3d-1793-48f6-b43b-9c7bb0348622 -- 0 volumes:

Youll see that the host has no volumes associated with it. Determine the UUID of the LUKS device that you want luksrku to decrypt, then add this volume with the name you want it to have after unlocking. In our case, the UUID is 18de9f14-2914-4a8b-9b46-b7deacbfbe8a and we want it to decrypt as “crypt-root”:

> add_volume my_host crypt-root 18de9f14-2914-4a8b-9b46-b7deacbfbe8a
LUKS passphrase of crypt-root / 18de9f14-2914-4a8b-9b46-b7deacbfbe8a: 5DySDFcpVtBRoIMNv7mrLqlozPYeq7X5kPmB3M1wsW8A

At this point, luksrku will tell you, in clear text, the LUKS passphrase that you need to add to the volume. Then, you save the server database:

> save server.bin
Database passphrase:

It asks you for a passphrase that is needed to decrypt the file. On disk its always stored encrypted. Using an encrypted server database is highly recommended.

For the client, you export the client portion of the database:

> export my_host my_host.bin
Client passphrase:

Note that client databases can also be encrypted, but theyre less critical than the server database. The client database does not contain the LUKS passphrases, it only contains the required TLS-PSK so that a successful connection to a luksrku server can be established.

With these two in place, you can now start a luksrku server:

$ ./luksrku server server.bin
Database passphrase:
[I]: Serving luksrku database for 1 hosts.

And on your client, when you want the LUKS disks to be unlocked:

$ ./luksrku client my_host.bin

Integration into initramfs

Using luksrku as part of your initramfs is quite easy. Youll need a server somewhere in your network and an exported client database. On the client, you copy the client database file into /etc/luksrku-client.bin.

Then, install luksrku globally by performing make install as root and install the initramfs script by running install in the initramfs/ subdirectory. Youll only need to install that once.

# make install
strip luksrku
cp luksrku /usr/local/sbin/
chown root:root /usr/local/sbin/luksrku
chmod 755 /usr/local/sbin/luksrku
# cd initramfs
# ./install

Finally, have initramfs recreate your initial ramdisk:

# update-initramfs -u

Thats it, it should now work.

License

GNU GPL-3.