lnd
lnd copied to clipboard
tls: Add ability to encrypt TLS key on disk
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 tellslnd
to encrypt the TLS private key on disk. If set, it will generate temporary TLS certs for theWalletUnlocker
RPC. Allows users to prevent spying on API traffic in untrusted environments. -
Add necessary tests and documentation
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.
ping. I think this would still be valuable.
@gkrizek, remember to re-request review from reviewers when ready
Closing in favor of https://github.com/lightningnetwork/lnd/pull/6527