Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverse Tang unlocking #24

Closed
anatol opened this issue Feb 9, 2021 · 6 comments
Closed

Reverse Tang unlocking #24

anatol opened this issue Feb 9, 2021 · 6 comments

Comments

@anatol
Copy link
Owner

anatol commented Feb 9, 2021

There is one use-case of a remote unlock that might be worth implementing at the booster side.

A remote host boots and reaches a locked root partition. At this point, initrd hangs and waits until the administrator enters the password. As this server is remote, there is no way to enter the password using a keyboard. Instead, the hosts expect the password is passed over the network.

Some initrd implementations have plugins to bringup ssh server at initrd stage e.g. mkinitcpio-dropbear. Setting up an sshd daemon brings a lot complexity to initramfs. It requires a full network setup, probably systemd/udev, the sshd server itself. Complexity is the enemy of maintainability. Complexity is the enemy of security. It would be great to implement the same use case with a simpler architecture.

In fact, booster already allows unlocking drives remotely with Tang technology. Tang is a simple two message protocol to derive keys securely over an insecure communication channel. It makes a lot of sense to reuse it. But instead of having a Tang server we need the initramfs to stop and wait for messages. Then administrator contacts the remote host and executes ECMR key exchange as would normal Tang does.

Here is what the unlock would look like:

  • the remote hosts opens a port and waits for incoming messages
  • administrator runs a CLI tool that initiates one ECMR key exchange. The cli would look like booster unlock server1.mycompany.com ./secret.key.
@anatol
Copy link
Owner Author

anatol commented Dec 2, 2021

@ShapeShifter499 answering your comment #114 (comment) here

The idea behind Clevis-Tang is that both parties contain some secret value and ECMR protocol allows to derive a new secret value over insecure channel. Once client (the clevis side) computes the derived key it can use it for dm-crypt or for wrapping/unwrapping another key.

With this schema Tang server runs as a TCP server and Clevis side connects to it.

With the reverse-Tang the TCP roles changed. Clevis starts up, opens a TCP port that starts listening. It basically asks "are there any Tang's here"? The Tang side connects to Clevis port and then ECMR exchange happens.

@ShapeShifter499
Copy link

I have a new concern about that reverse tang plan. Do you think a Clevis system could be exploited if it's looking for a Tang server and a malicious one responds?

@anatol
Copy link
Owner Author

anatol commented Dec 6, 2021

Do you think a Clevis system could be exploited if it's looking for a Tang server and a malicious one responds?

Malicious Tang could try to unlock the drive but it will be impossible to complete it successfully unless the user has a private key. The private key is what really needed to reconstruct the disk password. Without it the client will not be able to verify the password, it will reject the answer from malicious Tang and wait for another request.

The only problem I see here is DOS attack when a lot of malicious users try to unlock with wrong keys and make the client busy with verifying requests. At the same time, valid users get stuck because the machine's network queue is overflown.

@anatol
Copy link
Owner Author

anatol commented Dec 6, 2021

FYI I just released tang.go - library that implements the server-side of the ECMR exchange. It is needed to get the current feature implemented.

https://github.com/anatol/tang.go

@anatol anatol closed this as completed in de7ffc0 Mar 28, 2022
anatol added a commit that referenced this issue Mar 28, 2022
Unlocking an encrypted machine remotely over the network is one of the
actively used use-cases.

Add the remote unlocking using ECMR protocol, the same as used for Tang
bindings. In fact, there is not much difference between these 2 ways of
binding. The major difference is for "tang" protocol booster is the TCP
client, for "remote" protocol booster is TCP server.

To enable remote locking please follow these instructions:
 * install `clevis-extra-pins-git` `tang.go-git` packages from AUR
 * generate private keys with `tang-keys create . sig exc`.
   It creates 2 files: a signing and a keyDerive keys. Please keep these files private.
 * generate advertisement: `tang-keys adv --output advertisement.json sig.jwk exc.jwk`.
   An advertisement is the equivalent of a public signing certificate.
   This file is used later to encrypt partitions and the file can be shared with other parties.
 * encrypt the partition itself using advertisement generated above:
   `clevis luks bind -d /dev/fooo remote '{"adv":"advertisement.json", "port":34551}'`.
   This tells booster to stop at the boot and use port `34551` to listen to incoming TCP requests.

now reboot your machine. It will stop and wait for unlock requests. To unlock it run
`unlock-remote $YOURMACHINE:34551 exc.jwk sig.jwk`, where exc.jwk
sig.jwk are files generated above.

Closes #24
@anatol
Copy link
Owner Author

anatol commented Mar 28, 2022

Remote unlock support has been added to the master branch.

To enable remote locking please follow these instructions:

  • install clevis-extra-pins-git tang.go-git packages from AUR
  • generate private keys with tang-keys create . sig exc. It creates 2 files: a signing and a keyDerive keys. Please keep these files private.
  • generate advertisement: tang-keys adv --output advertisement.json sig.jwk exc.jwk. An advertisement is the equivalent of a public signing certificate. This file is used later to encrypt partitions and the file can be shared with other parties.
  • encrypt the partition itself using advertisement generated above: clevis luks bind -d /dev/fooo remote '{"adv":"advertisement.json", "port":34551}'. This tells booster to stop at the boot and use port 34551 to listen to incoming TCP requests.

now reboot your machine. It will stop and wait for unlock requests. To unlock it run unlock-remote $YOURMACHINE:34551 assets/remote/exc.jwk assets/remote/sig.jwk.

Please give it a try and let me know how does it work for you.

@anatol
Copy link
Owner Author

anatol commented Apr 1, 2022

I've made a few additional changes to simplify the command-line tool interface.

Now all tang.go functionality (tang-keys, tangd, unlock-remote ) consolidated into 1 binary - tangctl.

The tool usage looks like this now:

  1. Generate tang private key with tangctl create > key.priv. This is the key used for tangd and to unlock an encrypted machine.
  2. Generate a public key (or in tang lingo it is a "key advertisement") tangctl public key.priv > key.pub. key.pub can be distributed to a third party to encrypt their machines as clevis luks bind -d /dev/fooo remote '{"adv":"key.pub", "port":34551}'

To unlock a remote machine run tangctl unlock $YOURMACHINE:34551 priv.key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants