lnd icon indicating copy to clipboard operation
lnd copied to clipboard

tls: Add ability to encrypt TLS key on disk

Open gkrizek opened this issue 4 years ago • 3 comments

Currently LND writes the TLS private key to disk in plaintext. If you are running in an untrusted environment this could be a problem as someone could use the key to snoop on your API traffic and steal credentials. This pull request creates a way to encrypt the TLS key on disk so even if your server is compromised or others have access, they can't spy on your traffic.

In these changes, we add a new flag to lnd called --tlsencryptkey. When this is enabled, lnd encrypts the TLS key using the wallet's seed and writes the encrypted blob to disk. Because the key is encrypted to the wallet's seed, that means we can only use the TLS pair when the wallet is unlocked. This would leave the WalletUnlocker service without TLS. To fix this problem, we create a temporary TLS pair specifically for the WalletUnlocker RPC. This temporary TLS key is only stored in memory and the temporary TLS cert is written to disk at the same path as tlscertpath, but with .tmp appended to the end of the filename. After unlocking, lnd deletes the cert from disk and clears the private key from memory. Then uses the main TLS certificate for all other RPCs.

Of course, this changes the flow of unlocking/init a little bit. If you use --tlsencryptkey on lnd, then you'll need a way to access the temporary TLS cert for verification. The simplest way to do this is to use lncli on the same host lnd is running on and point --tlscertpath at the temporary cert. If that's not possible then the user will need to come up with a way to copy the temporary certificate out of the lnd server and get it to their client device.

Summary of Changes:

  • Moves the crypto.go file from chanbackup into its own package called lnencrypt. This was needed because we can't directly reference the encryptPayloadToWriter and decryptPayloadFromReader functions from the chanbackup package due to circular dependency issues. Also, I think it's very likely that future enhancements will also want to use these same functions. Thus I've moved them to their own package. (cherry-picked from #4458)

  • Creates a new flag (--tlsencryptkey) that tells lnd to encrypt the TLS private key on disk. If set, it will generate temporary TLS certs for the WalletUnlocker RPC. Allows users to prevent spying on API traffic in untrusted environments.

  • Add necessary tests and documentation

gkrizek avatar Jul 18 '20 05:07 gkrizek

I've updated this PR to be compatible with the new Unified RPC that was recently merged in. This previously relied on the WalletUnlocker RPC being shut down to know when to switch from the ephemeral certificates to the persistent ones.

I've now implemented a new TLSReloader that can change the TLS credentials on the fly without the need to restart the server. This works well with the new Unified RPC as it no longer gets shut down.

I think this could also be used to automatically regenerate TLS certificates when they're about to expire without needing to stop LND. Although that's worthy of a separate PR.

gkrizek avatar Mar 17 '21 03:03 gkrizek

ping. I think this would still be valuable.

gkrizek avatar Dec 20 '21 18:12 gkrizek

@gkrizek, remember to re-request review from reviewers when ready

lightninglabs-deploy avatar Aug 09 '22 03:08 lightninglabs-deploy

Closing in favor of https://github.com/lightningnetwork/lnd/pull/6527

gkrizek avatar Aug 16 '22 02:08 gkrizek