server: add automatic creation of v2 onion services
In this commit, we allow the daemon to use the recently introduced Tor Controller implementation. This will automatically create a v2 onion service at startup in order to listen for inbound connections over Tor. Co-Authored-By: Eugene <crypt-iq@users.noreply.github.com>
This commit is contained in:
parent
3bb1733fa2
commit
1012f876e1
75
server.go
75
server.go
@ -74,6 +74,16 @@ type server struct {
|
||||
// long-term identity private key.
|
||||
lightningID [32]byte
|
||||
|
||||
// listenAddrs is the list of addresses the server is currently
|
||||
// listening on.
|
||||
listenAddrs []string
|
||||
|
||||
// torController is a client that will communicate with a locally
|
||||
// running Tor server. This client will handle initiating and
|
||||
// authenticating the connection to the Tor server, automatically
|
||||
// creating and setting up onion services, etc.
|
||||
torController *tor.Controller
|
||||
|
||||
mu sync.RWMutex
|
||||
peersByPub map[string]*peer
|
||||
|
||||
@ -215,6 +225,8 @@ func newServer(listenAddrs []string, chanDB *channeldb.DB, cc *chainControl,
|
||||
identityPriv: privKey,
|
||||
nodeSigner: newNodeSigner(privKey),
|
||||
|
||||
listenAddrs: listenAddrs,
|
||||
|
||||
// TODO(roasbeef): derive proper onion key based on rotation
|
||||
// schedule
|
||||
sphinx: htlcswitch.NewOnionProcessor(sphinxRouter),
|
||||
@ -299,6 +311,16 @@ func newServer(listenAddrs []string, chanDB *channeldb.DB, cc *chainControl,
|
||||
selfAddrs = append(selfAddrs, addr)
|
||||
}
|
||||
|
||||
// If we were requested to route connections through Tor and to
|
||||
// automatically create an onion service, we'll initiate our Tor
|
||||
// controller and establish a connection to the Tor server.
|
||||
//
|
||||
// NOTE: v3 onion services cannot be created automatically yet. In the
|
||||
// future, this will be expanded to do so.
|
||||
if cfg.Tor.Active && cfg.Tor.V2 {
|
||||
s.torController = tor.NewController(cfg.Tor.Control)
|
||||
}
|
||||
|
||||
chanGraph := chanDB.ChannelGraph()
|
||||
|
||||
// Parse node color from configuration.
|
||||
@ -588,6 +610,12 @@ func (s *server) Start() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if s.torController != nil {
|
||||
if err := s.initTorController(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Start the notification server. This is used so channel management
|
||||
// goroutines can be notified when a funding transaction reaches a
|
||||
// sufficient number of confirmations, or when the input for the
|
||||
@ -659,6 +687,10 @@ func (s *server) Stop() error {
|
||||
|
||||
close(s.quit)
|
||||
|
||||
if s.torController != nil {
|
||||
s.torController.Stop()
|
||||
}
|
||||
|
||||
// Shutdown the wallet, funding manager, and the rpc server.
|
||||
s.cc.chainNotifier.Stop()
|
||||
s.chanRouter.Stop()
|
||||
@ -881,6 +913,49 @@ func (s *server) peerBootstrapper(numTargetPeers uint32,
|
||||
}
|
||||
}
|
||||
|
||||
// initTorController initiliazes the Tor controller backed by lnd and
|
||||
// automatically sets up a v2 onion service in order to listen for inbound
|
||||
// connections over Tor.
|
||||
func (s *server) initTorController() error {
|
||||
if err := s.torController.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Determine the different ports the server is listening on. The onion
|
||||
// service's virtual port will map to these ports and one will be picked
|
||||
// at random when the onion service is being accessed.
|
||||
listenPorts := make(map[int]struct{})
|
||||
for _, listenAddr := range s.listenAddrs {
|
||||
// At this point, the listen addresses should have already been
|
||||
// normalized, so it's safe to ignore the errors.
|
||||
_, portStr, _ := net.SplitHostPort(listenAddr)
|
||||
port, _ := strconv.Atoi(portStr)
|
||||
listenPorts[port] = struct{}{}
|
||||
}
|
||||
|
||||
// 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`.
|
||||
virtToTargPorts := tor.VirtToTargPorts{defaultPeerPort: listenPorts}
|
||||
onionServiceAddrs, err := s.torController.AddOnionV2(
|
||||
cfg.Tor.V2PrivateKeyPath, virtToTargPorts,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Now that the onion service has been created, we'll add the different
|
||||
// onion addresses it can be reached at to our list of advertised
|
||||
// addresses.
|
||||
for _, addr := range onionServiceAddrs {
|
||||
s.currentNodeAnn.Addresses = append(
|
||||
s.currentNodeAnn.Addresses, addr,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// genNodeAnnouncement generates and returns the current fully signed node
|
||||
// announcement. If refresh is true, then the time stamp of the announcement
|
||||
// will be updated in order to ensure it propagates through the network.
|
||||
|
Loading…
Reference in New Issue
Block a user