diff --git a/go.mod b/go.mod index 0821fad2e..21973764d 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( github.com/lightningnetwork/lnd/queue v1.1.0 github.com/lightningnetwork/lnd/ticker v1.1.0 github.com/lightningnetwork/lnd/tlv v1.0.3 - github.com/lightningnetwork/lnd/tor v1.0.2 + github.com/lightningnetwork/lnd/tor v1.1.0 github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796 github.com/miekg/dns v1.1.43 github.com/prometheus/client_golang v1.11.0 diff --git a/go.sum b/go.sum index 343dc5639..880aaf938 100644 --- a/go.sum +++ b/go.sum @@ -465,6 +465,8 @@ github.com/lightningnetwork/lnd/tlv v1.0.3/go.mod h1:dzR/aZetBri+ZY/fHbwV06fNn/3 github.com/lightningnetwork/lnd/tor v1.0.0/go.mod h1:RDtaAdwfAm+ONuPYwUhNIH1RAvKPv+75lHPOegUcz64= github.com/lightningnetwork/lnd/tor v1.0.2 h1:GlumRkKdzXCX0AIvIi2UXKpeY1Q4RT7Lz/CfGpKSLrU= github.com/lightningnetwork/lnd/tor v1.0.2/go.mod h1:RDtaAdwfAm+ONuPYwUhNIH1RAvKPv+75lHPOegUcz64= +github.com/lightningnetwork/lnd/tor v1.1.0 h1:iXO7fSzjxTI+p88KmtpbuyuRJeNfgtpl9QeaAliILXE= +github.com/lightningnetwork/lnd/tor v1.1.0/go.mod h1:RDtaAdwfAm+ONuPYwUhNIH1RAvKPv+75lHPOegUcz64= github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796 h1:sjOGyegMIhvgfq5oaue6Td+hxZuf3tDC8lAPrFldqFw= github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796/go.mod h1:3p7ZTf9V1sNPI5H8P3NkTFF4LuwMdPl2DodF60qAKqY= github.com/ltcsuite/ltcutil v0.0.0-20181217130922-17f3b04680b6/go.mod h1:8Vg/LTOO0KYa/vlHWJ6XZAevPQThGH5sufO0Hrou/lA= diff --git a/lncfg/tor.go b/lncfg/tor.go index be58e7ea5..2dcd18c93 100644 --- a/lncfg/tor.go +++ b/lncfg/tor.go @@ -13,5 +13,6 @@ type Tor struct { V2 bool `long:"v2" description:"Automatically set up a v2 onion service to listen for inbound connections"` V3 bool `long:"v3" description:"Automatically set up a v3 onion service to listen for inbound connections"` PrivateKeyPath string `long:"privatekeypath" description:"The path to the private key of the onion service being created"` + EncryptKey bool `long:"encryptkey" description:"Encrypts the Tor private key file on disk"` WatchtowerKeyPath string `long:"watchtowerkeypath" description:"The path to the private key of the watchtower onion service being created"` } diff --git a/lnd.go b/lnd.go index 05dbb8696..27ff7bb9d 100644 --- a/lnd.go +++ b/lnd.go @@ -474,6 +474,8 @@ func Main(cfg *Config, lisCfg ListenerCfg, implCfg *ImplementationCfg, if torController != nil { wtCfg.TorController = torController wtCfg.WatchtowerKeyPath = cfg.Tor.WatchtowerKeyPath + wtCfg.EncryptKey = cfg.Tor.EncryptKey + wtCfg.KeyRing = activeChainControl.KeyRing switch { case cfg.Tor.V2: diff --git a/server.go b/server.go index 3d4a3d640..62527d478 100644 --- a/server.go +++ b/server.go @@ -47,6 +47,7 @@ import ( "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lncfg" + "github.com/lightningnetwork/lnd/lnencrypt" "github.com/lightningnetwork/lnd/lnpeer" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" @@ -2766,13 +2767,21 @@ func (s *server) createNewHiddenService() error { listenPorts = append(listenPorts, port) } + encrypter, err := lnencrypt.KeyRingEncrypter(s.cc.KeyRing) + if err != nil { + return err + } + // Once the port mapping has been set, we can go ahead and automatically // create our onion service. The service's private key will be saved to // disk in order to regain access to this service when restarting `lnd`. onionCfg := tor.AddOnionConfig{ VirtualPort: defaultPeerPort, TargetPorts: listenPorts, - Store: tor.NewOnionFile(s.cfg.Tor.PrivateKeyPath, 0600), + Store: tor.NewOnionFile( + s.cfg.Tor.PrivateKeyPath, 0600, s.cfg.Tor.EncryptKey, + encrypter, + ), } switch { diff --git a/watchtower/config.go b/watchtower/config.go index 874d58416..f79de9cac 100644 --- a/watchtower/config.go +++ b/watchtower/config.go @@ -98,6 +98,12 @@ type Config struct { // for a watchtower hidden service should be stored. WatchtowerKeyPath string + // EncryptKey will encrypt the Tor private key on disk. + EncryptKey bool + + // KeyRing is the KeyRing to use when encrypting the Tor private key. + KeyRing keychain.KeyRing + // Type specifies the hidden service type (V2 or V3) that the watchtower // will create. Type tor.OnionType diff --git a/watchtower/standalone.go b/watchtower/standalone.go index fb1f365be..c652d9c76 100644 --- a/watchtower/standalone.go +++ b/watchtower/standalone.go @@ -6,6 +6,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/lightningnetwork/lnd/brontide" + "github.com/lightningnetwork/lnd/lnencrypt" "github.com/lightningnetwork/lnd/tor" "github.com/lightningnetwork/lnd/watchtower/lookout" "github.com/lightningnetwork/lnd/watchtower/wtserver" @@ -163,14 +164,22 @@ func (w *Standalone) createNewHiddenService() error { listenPorts = append(listenPorts, port) } + encrypter, err := lnencrypt.KeyRingEncrypter(w.cfg.KeyRing) + if err != nil { + return err + } + // Once we've created the port mapping, we can automatically create the // hidden service. The service's private key will be saved on disk in order // to persistently have access to this hidden service across restarts. onionCfg := tor.AddOnionConfig{ VirtualPort: DefaultPeerPort, TargetPorts: listenPorts, - Store: tor.NewOnionFile(w.cfg.WatchtowerKeyPath, 0600), - Type: w.cfg.Type, + Store: tor.NewOnionFile( + w.cfg.WatchtowerKeyPath, 0600, w.cfg.EncryptKey, + encrypter, + ), + Type: w.cfg.Type, } addr, err := w.cfg.TorController.AddOnion(onionCfg)