github.com/decred/dcrlnd@v0.7.6/lnd.go (about) 1 // Copyright (c) 2013-2017 The btcsuite developers 2 // Copyright (c) 2015-2019 The Decred developers 3 // Copyright (C) 2015-2017 The Lightning Network Developers 4 5 package dcrlnd 6 7 import ( 8 "context" 9 "crypto/tls" 10 "errors" 11 "fmt" 12 "io/ioutil" 13 "net" 14 "net/http" 15 _ "net/http/pprof" // Blank import to set up profiling HTTP handlers. 16 "os" 17 "runtime/pprof" 18 "strings" 19 "sync" 20 "time" 21 22 proxy "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" 23 "golang.org/x/crypto/acme/autocert" 24 "google.golang.org/grpc" 25 "google.golang.org/grpc/credentials" 26 "google.golang.org/protobuf/encoding/protojson" 27 "gopkg.in/macaroon-bakery.v2/bakery" 28 "gopkg.in/macaroon.v2" 29 30 "github.com/decred/dcrd/txscript/v4/stdaddr" 31 "github.com/decred/dcrlnd/automation" 32 "github.com/decred/dcrlnd/autopilot" 33 "github.com/decred/dcrlnd/build" 34 "github.com/decred/dcrlnd/cert" 35 "github.com/decred/dcrlnd/chanacceptor" 36 "github.com/decred/dcrlnd/channeldb" 37 "github.com/decred/dcrlnd/keychain" 38 "github.com/decred/dcrlnd/lncfg" 39 "github.com/decred/dcrlnd/lnrpc" 40 "github.com/decred/dcrlnd/lnrpc/initchainsyncrpc" 41 "github.com/decred/dcrlnd/lnwallet" 42 "github.com/decred/dcrlnd/macaroons" 43 "github.com/decred/dcrlnd/monitoring" 44 "github.com/decred/dcrlnd/rpcperms" 45 "github.com/decred/dcrlnd/signal" 46 "github.com/decred/dcrlnd/tor" 47 "github.com/decred/dcrlnd/walletunlocker" 48 "github.com/decred/dcrlnd/watchtower" 49 ) 50 51 const ( 52 // adminMacaroonFilePermissions is the file permission that is used for 53 // creating the admin macaroon file. 54 // 55 // Why 640 is safe: 56 // Assuming a reasonably secure Linux system, it will have a 57 // separate group for each user. E.g. a new user lnd gets assigned group 58 // lnd which nothing else belongs to. A system that does not do this is 59 // inherently broken already. 60 // 61 // Since there is no other user in the group, no other user can read 62 // admin macaroon unless the administrator explicitly allowed it. Thus 63 // there's no harm allowing group read. 64 adminMacaroonFilePermissions = 0640 65 ) 66 67 // AdminAuthOptions returns a list of DialOptions that can be used to 68 // authenticate with the RPC server with admin capabilities. 69 // skipMacaroons=true should be set if we don't want to include macaroons with 70 // the auth options. This is needed for instance for the WalletUnlocker 71 // service, which must be usable also before macaroons are created. 72 // 73 // NOTE: This should only be called after the RPCListener has signaled it is 74 // ready. 75 func AdminAuthOptions(cfg *Config, skipMacaroons bool) ([]grpc.DialOption, 76 error) { 77 78 creds, err := credentials.NewClientTLSFromFile(cfg.TLSCertPath, "") 79 if err != nil { 80 return nil, fmt.Errorf("unable to read TLS cert: %v", err) 81 } 82 83 // Create a dial options array. 84 opts := []grpc.DialOption{ 85 grpc.WithTransportCredentials(creds), 86 } 87 88 // Get the admin macaroon if macaroons are active. 89 if !skipMacaroons && !cfg.NoMacaroons { 90 // Load the adming macaroon file. 91 macBytes, err := ioutil.ReadFile(cfg.AdminMacPath) 92 if err != nil { 93 return nil, fmt.Errorf("unable to read macaroon "+ 94 "path (check the network setting!): %v", err) 95 } 96 97 mac := &macaroon.Macaroon{} 98 if err = mac.UnmarshalBinary(macBytes); err != nil { 99 return nil, fmt.Errorf("unable to decode macaroon: %v", 100 err) 101 } 102 103 // Now we append the macaroon credentials to the dial options. 104 cred, err := macaroons.NewMacaroonCredential(mac) 105 if err != nil { 106 return nil, fmt.Errorf("error cloning mac: %v", err) 107 } 108 opts = append(opts, grpc.WithPerRPCCredentials(cred)) 109 } 110 111 return opts, nil 112 } 113 114 // ListenerWithSignal is a net.Listener that has an additional Ready channel 115 // that will be closed when a server starts listening. 116 type ListenerWithSignal struct { 117 net.Listener 118 119 // Ready will be closed by the server listening on Listener. 120 Ready chan struct{} 121 122 // MacChan is an optional way to pass the admin macaroon to the program 123 // that started lnd. The channel should be buffered to avoid lnd being 124 // blocked on sending to the channel. 125 MacChan chan []byte 126 } 127 128 // ListenerCfg is a wrapper around custom listeners that can be passed to lnd 129 // when calling its main method. 130 type ListenerCfg struct { 131 // RPCListeners can be set to the listeners to use for the RPC server. 132 // If empty a regular network listener will be created. 133 RPCListeners []*ListenerWithSignal 134 } 135 136 var errStreamIsolationWithProxySkip = errors.New( 137 "while stream isolation is enabled, the TOR proxy may not be skipped", 138 ) 139 140 // Main is the true entry point for lnd. It accepts a fully populated and 141 // validated main configuration struct and an optional listener config struct. 142 // This function starts all main system components then blocks until a signal 143 // is received on the shutdownChan at which point everything is shut down again. 144 func Main(cfg *Config, lisCfg ListenerCfg, implCfg *ImplementationCfg, 145 interceptor signal.Interceptor) error { 146 147 defer func() { 148 ltndLog.Info("Shutdown complete\n") 149 err := cfg.LogWriter.Close() 150 if err != nil { 151 ltndLog.Errorf("Could not close log rotator: %v", err) 152 } 153 }() 154 155 mkErr := func(format string, args ...interface{}) error { 156 ltndLog.Errorf("Shutting down because error in main "+ 157 "method: "+format, args...) 158 return fmt.Errorf(format, args...) 159 } 160 161 // Show version at startup. 162 ltndLog.Infof("Version: %s, build=%s, logging=%s, debuglevel=%s", 163 build.Version(), build.Deployment, build.LoggingType, cfg.DebugLevel) 164 165 // Read IPC messages from the read end of a pipe created and passed by the 166 // parent process, if any. When this pipe is closed, shutdown is 167 // initialized. 168 if cfg.PipeRx != nil { 169 go serviceControlPipeRx(uintptr(*cfg.PipeRx), &interceptor) 170 } 171 if cfg.PipeTx != nil { 172 go serviceControlPipeTx(uintptr(*cfg.PipeTx)) 173 } else { 174 go drainOutgoingPipeMessages() 175 } 176 177 // We default to mainnet if none are specified. 178 network := "mainnet" 179 switch { 180 case cfg.Decred.TestNet3: 181 network = "testnet" 182 183 case cfg.Decred.SimNet: 184 network = "simnet" 185 186 case cfg.Decred.RegTest: 187 network = "regtest" 188 } 189 190 ltndLog.Infof("Active chain: %v (network=%v)", 191 strings.Title(cfg.registeredChains.PrimaryChain().String()), 192 network, 193 ) 194 195 // Enable http profiling server if requested. 196 if cfg.Profile != "" { 197 go func() { 198 profileRedirect := http.RedirectHandler("/debug/pprof", 199 http.StatusSeeOther) 200 http.Handle("/", profileRedirect) 201 ltndLog.Infof("Pprof listening on %v", cfg.Profile) 202 fmt.Println(http.ListenAndServe(cfg.Profile, nil)) 203 }() 204 } 205 206 // Write cpu profile if requested. 207 if cfg.CPUProfile != "" { 208 f, err := os.Create(cfg.CPUProfile) 209 if err != nil { 210 return mkErr("unable to create CPU profile: %v", err) 211 } 212 pprof.StartCPUProfile(f) 213 defer f.Close() 214 defer pprof.StopCPUProfile() 215 } 216 217 // Write memory profile if requested. 218 if cfg.MemProfile != "" { 219 f, err := os.Create(cfg.MemProfile) 220 if err != nil { 221 err := fmt.Errorf("unable to create memory profile: %v", 222 err) 223 ltndLog.Error(err) 224 return err 225 } 226 defer f.Close() 227 defer pprof.WriteHeapProfile(f) 228 } 229 230 if cfg.DB.Backend != "bolt" && network == "mainnet" { 231 err := fmt.Errorf("Only bbolt db backend has been tested in production " + 232 "for dcrlnd.") 233 ltndLog.Error(err) 234 return err 235 } 236 237 ctx := context.Background() 238 ctx, cancel := context.WithCancel(ctx) 239 defer cancel() 240 241 // Run configuration dependent DB pre-initialization. Note that this 242 // needs to be done early and once during the startup process, before 243 // any DB access. 244 if err := cfg.DB.Init(ctx, cfg.graphDatabaseDir()); err != nil { 245 return mkErr("error initializing DBs: %v", err) 246 } 247 248 // Only process macaroons if --no-macaroons isn't set. 249 serverOpts, restDialOpts, restListen, cleanUp, err := getTLSConfig(cfg) 250 if err != nil { 251 return mkErr("unable to load TLS credentials: %v", err) 252 } 253 254 defer cleanUp() 255 256 // If we have chosen to start with a dedicated listener for the 257 // rpc server, we set it directly. 258 grpcListeners := append([]*ListenerWithSignal{}, lisCfg.RPCListeners...) 259 if len(grpcListeners) == 0 { 260 // Otherwise we create listeners from the RPCListeners defined 261 // in the config. 262 for _, grpcEndpoint := range cfg.RPCListeners { 263 // Start a gRPC server listening for HTTP/2 264 // connections. 265 lis, err := lncfg.ListenOnAddress(grpcEndpoint) 266 if err != nil { 267 return mkErr("unable to listen on %s: %v", 268 grpcEndpoint, err) 269 } 270 defer lis.Close() 271 272 grpcListeners = append( 273 grpcListeners, &ListenerWithSignal{ 274 Listener: lis, 275 Ready: make(chan struct{}), 276 }, 277 ) 278 } 279 } 280 281 // Create a new RPC interceptor that we'll add to the GRPC server. This 282 // will be used to log the API calls invoked on the GRPC server. 283 interceptorChain := rpcperms.NewInterceptorChain( 284 rpcsLog, cfg.NoMacaroons, cfg.RPCMiddleware.Mandatory, 285 ) 286 if err := interceptorChain.Start(); err != nil { 287 return mkErr("error starting interceptor chain: %v", err) 288 } 289 defer func() { 290 err := interceptorChain.Stop() 291 if err != nil { 292 ltndLog.Warnf("error stopping RPC interceptor "+ 293 "chain: %v", err) 294 } 295 }() 296 297 rpcServerOpts := interceptorChain.CreateServerOpts() 298 serverOpts = append(serverOpts, rpcServerOpts...) 299 300 grpcServer := grpc.NewServer(serverOpts...) 301 defer grpcServer.Stop() 302 303 // We'll also register the RPC interceptor chain as the StateServer, as 304 // it can be used to query for the current state of the wallet. 305 lnrpc.RegisterStateServer(grpcServer, interceptorChain) 306 307 // Initialize, and register our implementation of the gRPC interface 308 // exported by the rpcServer. 309 rpcServer := newRPCServer(cfg, interceptorChain, implCfg, interceptor) 310 err = rpcServer.RegisterWithGrpcServer(grpcServer) 311 if err != nil { 312 return mkErr("error registering gRPC server: %v", err) 313 } 314 315 // Initialize and register the syncer gRPC server. This is a dcrlnd 316 // only service. 317 syncerServer := initchainsyncrpc.New() 318 initchainsyncrpc.RegisterInitialChainSyncServer(grpcServer, syncerServer) 319 for k, v := range initChainSyncPermissions { 320 err := interceptorChain.AddPermission(k, v) 321 if err != nil { 322 return err 323 } 324 } 325 326 // Now that both the WalletUnlocker and LightningService have been 327 // registered with the GRPC server, we can start listening. 328 err = startGrpcListen(cfg, grpcServer, grpcListeners) 329 if err != nil { 330 return mkErr("error starting gRPC listener: %v", err) 331 } 332 333 // Now start the REST proxy for our gRPC server above. We'll ensure 334 // we direct LND to connect to its loopback address rather than a 335 // wildcard to prevent certificate issues when accessing the proxy 336 // externally. 337 stopProxy, err := startRestProxy( 338 cfg, rpcServer, restDialOpts, restListen, 339 ) 340 if err != nil { 341 return mkErr("error starting REST proxy: %v", err) 342 } 343 defer stopProxy() 344 345 // Start leader election if we're running on etcd. Continuation will be 346 // blocked until this instance is elected as the current leader or 347 // shutting down. 348 elected := false 349 if cfg.Cluster.EnableLeaderElection { 350 electionCtx, cancelElection := context.WithCancel(ctx) 351 352 go func() { 353 <-interceptor.ShutdownChannel() 354 cancelElection() 355 }() 356 357 ltndLog.Infof("Using %v leader elector", 358 cfg.Cluster.LeaderElector) 359 360 leaderElector, err := cfg.Cluster.MakeLeaderElector( 361 electionCtx, cfg.DB, 362 ) 363 if err != nil { 364 return err 365 } 366 367 defer func() { 368 if !elected { 369 return 370 } 371 372 ltndLog.Infof("Attempting to resign from leader role "+ 373 "(%v)", cfg.Cluster.ID) 374 375 if err := leaderElector.Resign(); err != nil { 376 ltndLog.Errorf("Leader elector failed to "+ 377 "resign: %v", err) 378 } 379 }() 380 381 ltndLog.Infof("Starting leadership campaign (%v)", 382 cfg.Cluster.ID) 383 384 if err := leaderElector.Campaign(electionCtx); err != nil { 385 return mkErr("leadership campaign failed: %v", err) 386 } 387 388 elected = true 389 ltndLog.Infof("Elected as leader (%v)", cfg.Cluster.ID) 390 } 391 392 dbs, cleanUp, err := implCfg.DatabaseBuilder.BuildDatabase(ctx) 393 switch { 394 case err == channeldb.ErrDryRunMigrationOK: 395 ltndLog.Infof("%v, exiting", err) 396 return nil 397 case err != nil: 398 return mkErr("unable to open databases: %v", err) 399 } 400 401 defer cleanUp() 402 403 partialChainControl, walletConfig, cleanUp, err := implCfg.BuildWalletConfig( 404 ctx, dbs, interceptorChain, grpcListeners, 405 ) 406 if err != nil { 407 return mkErr("error creating wallet config: %v", err) 408 } 409 410 defer cleanUp() 411 412 activeChainControl, cleanUp, err := implCfg.BuildChainControl( 413 partialChainControl, walletConfig, 414 ) 415 if err != nil { 416 return mkErr("error loading chain control: %v", err) 417 } 418 defer cleanUp() 419 420 // Wait until we're fully synced to continue the start up of the remainder 421 // of the daemon. This ensures that we don't accept any possibly invalid 422 // state transitions, or accept channels with spent funds. 423 // 424 // This is also required on decred due to various things dcrwallet does at 425 // startup (mainly, slip0044 upgrade, account and address discovery) which 426 // may race if we try to start using it to (e.g.) derive the node's id 427 // private key before the wallet is fully synced for the first time. 428 err = waitForInitialChainSync(activeChainControl, &interceptor, syncerServer) 429 if errors.Is(err, errShutdownRequested) { 430 return nil 431 } else if err != nil { 432 return err 433 } 434 435 // Finally before we start the server, we'll register the "holy 436 // trinity" of interface for our current "home chain" with the active 437 // chainRegistry interface. 438 primaryChain := cfg.registeredChains.PrimaryChain() 439 cfg.registeredChains.RegisterChain(primaryChain, activeChainControl) 440 441 // TODO(roasbeef): add rotation 442 idKeyDesc, err := activeChainControl.KeyRing.DeriveKey( 443 keychain.KeyLocator{ 444 Family: keychain.KeyFamilyNodeKey, 445 Index: 0, 446 }, 447 ) 448 if err != nil { 449 return mkErr("error deriving node key: %v", err) 450 } 451 452 if cfg.Tor.StreamIsolation && cfg.Tor.SkipProxyForClearNetTargets { 453 return errStreamIsolationWithProxySkip 454 } 455 456 if cfg.Tor.Active { 457 if cfg.Tor.SkipProxyForClearNetTargets { 458 srvrLog.Info("Onion services are accessible via Tor! " + 459 "NOTE: Traffic to clearnet services is not " + 460 "routed via Tor.") 461 } else { 462 srvrLog.Infof("Proxying all network traffic via Tor "+ 463 "(stream_isolation=%v)! NOTE: Ensure the "+ 464 "backend node is proxying over Tor as well", 465 cfg.Tor.StreamIsolation) 466 } 467 } 468 469 // If tor is active and either v2 or v3 onion services have been 470 // specified, make a tor controller and pass it into both the watchtower 471 // server and the regular lnd server. 472 var torController *tor.Controller 473 if cfg.Tor.Active && (cfg.Tor.V2 || cfg.Tor.V3) { 474 torController = tor.NewController( 475 cfg.Tor.Control, cfg.Tor.TargetIPAddress, 476 cfg.Tor.Password, 477 ) 478 479 // Start the tor controller before giving it to any other 480 // subsystems. 481 if err := torController.Start(); err != nil { 482 return mkErr("unable to initialize tor controller: %v", 483 err) 484 } 485 defer func() { 486 if err := torController.Stop(); err != nil { 487 ltndLog.Errorf("error stopping tor "+ 488 "controller: %v", err) 489 } 490 }() 491 } 492 493 var tower *watchtower.Standalone 494 if cfg.Watchtower.Active { 495 towerKeyDesc, err := activeChainControl.KeyRing.DeriveKey( 496 keychain.KeyLocator{ 497 Family: keychain.KeyFamilyTowerID, 498 Index: 0, 499 }, 500 ) 501 if err != nil { 502 return mkErr("error deriving tower key: %v", err) 503 } 504 505 wtCfg := &watchtower.Config{ 506 NetParams: cfg.ActiveNetParams.Params, 507 BlockFetcher: activeChainControl.ChainIO, 508 DB: dbs.TowerServerDB, 509 EpochRegistrar: activeChainControl.ChainNotifier, 510 Net: cfg.net, 511 NewAddress: func() (stdaddr.Address, error) { 512 return activeChainControl.Wallet.NewAddress( 513 lnwallet.WitnessPubKey, false, 514 lnwallet.DefaultAccountName, 515 ) 516 }, 517 NodeKeyECDH: keychain.NewPubKeyECDH( 518 towerKeyDesc, activeChainControl.KeyRing, 519 ), 520 PublishTx: activeChainControl.Wallet.PublishTransaction, 521 ChainHash: cfg.ActiveNetParams.GenesisHash, 522 } 523 524 // If there is a tor controller (user wants auto hidden 525 // services), then store a pointer in the watchtower config. 526 if torController != nil { 527 wtCfg.TorController = torController 528 wtCfg.WatchtowerKeyPath = cfg.Tor.WatchtowerKeyPath 529 530 switch { 531 case cfg.Tor.V2: 532 wtCfg.Type = tor.V2 533 case cfg.Tor.V3: 534 wtCfg.Type = tor.V3 535 } 536 } 537 538 wtConfig, err := cfg.Watchtower.Apply( 539 wtCfg, lncfg.NormalizeAddresses, 540 ) 541 if err != nil { 542 return mkErr("unable to configure watchtower: %v", err) 543 } 544 545 tower, err = watchtower.New(wtConfig) 546 if err != nil { 547 return mkErr("unable to create watchtower: %v", err) 548 } 549 } 550 551 // Initialize the ChainedAcceptor. 552 chainedAcceptor := chanacceptor.NewChainedAcceptor() 553 554 // Set up the core server which will listen for incoming peer 555 // connections. 556 server, err := newServer( 557 cfg, cfg.Listeners, dbs, activeChainControl, &idKeyDesc, 558 activeChainControl.Cfg.WalletUnlockParams.ChansToRestore, 559 chainedAcceptor, torController, 560 ) 561 if err != nil { 562 return mkErr("unable to create server: %v", err) 563 } 564 565 // Set up an autopilot manager from the current config. This will be 566 // used to manage the underlying autopilot agent, starting and stopping 567 // it at will. 568 atplCfg, err := initAutoPilot( 569 server, cfg.Autopilot, activeChainControl.MinHtlcIn, 570 cfg.ActiveNetParams, 571 ) 572 if err != nil { 573 return mkErr("unable to initialize autopilot: %v", err) 574 } 575 576 atplManager, err := autopilot.NewManager(atplCfg) 577 if err != nil { 578 return mkErr("unable to create autopilot manager: %v", err) 579 } 580 if err := atplManager.Start(); err != nil { 581 return mkErr("unable to start autopilot manager: %v", err) 582 } 583 defer atplManager.Stop() 584 585 // Now we have created all dependencies necessary to populate and 586 // start the RPC server. 587 err = rpcServer.addDeps( 588 server, interceptorChain.MacaroonService(), cfg.SubRPCServers, 589 atplManager, server.invoices, tower, chainedAcceptor, 590 ) 591 if err != nil { 592 return mkErr("unable to add deps to RPC server: %v", err) 593 } 594 if err := rpcServer.Start(); err != nil { 595 return mkErr("unable to start RPC server: %v", err) 596 } 597 598 defer rpcServer.Stop() 599 600 // We transition the RPC state to Active, as the RPC server is up. 601 interceptorChain.SetRPCActive() 602 603 if err := interceptor.Notifier.NotifyReady(true); err != nil { 604 return mkErr("error notifying ready: %v", err) 605 } 606 607 // With all the relevant chains initialized, we can finally start the 608 // server itself. 609 if err := server.Start(); err != nil { 610 return mkErr("unable to start server: %v", err) 611 } 612 defer server.Stop() 613 614 // We transition the server state to Active, as the server is up. 615 interceptorChain.SetServerActive() 616 617 // Now that the server has started, if the autopilot mode is currently 618 // active, then we'll start the autopilot agent immediately. It will be 619 // stopped together with the autopilot service. 620 if cfg.Autopilot.Active { 621 if err := atplManager.StartAgent(); err != nil { 622 return mkErr("unable to start autopilot agent: %v", err) 623 } 624 } 625 626 if cfg.Watchtower.Active { 627 if err := tower.Start(); err != nil { 628 return mkErr("unable to start watchtower: %v", err) 629 } 630 defer tower.Stop() 631 } 632 633 // Start the dcrlnd specific automation services. 634 autoServer := automation.NewServer(&automation.Config{ 635 Automation: cfg.Automation, 636 CloseChannel: rpcServer.CloseChannel, 637 DB: dbs.ChanStateDB, 638 }) 639 if err := autoServer.Start(); err != nil { 640 return err 641 } 642 defer autoServer.Stop() 643 644 // Wait for shutdown signal from either a graceful server stop or from 645 // the interrupt handler. 646 <-interceptor.ShutdownChannel() 647 return nil 648 } 649 650 // getTLSConfig returns a TLS configuration for the gRPC server and credentials 651 // and a proxy destination for the REST reverse proxy. 652 func getTLSConfig(cfg *Config) ([]grpc.ServerOption, []grpc.DialOption, 653 func(net.Addr) (net.Listener, error), func(), error) { 654 655 // Ensure we create TLS key and certificate if they don't exist. 656 if !fileExists(cfg.TLSCertPath) && !fileExists(cfg.TLSKeyPath) { 657 rpcsLog.Infof("Generating TLS certificates...") 658 err := cert.GenCertPair( 659 "lnd autogenerated cert", cfg.TLSCertPath, 660 cfg.TLSKeyPath, cfg.TLSExtraIPs, cfg.TLSExtraDomains, 661 cfg.TLSDisableAutofill, cfg.TLSCertDuration, 662 ) 663 if err != nil { 664 return nil, nil, nil, nil, err 665 } 666 rpcsLog.Infof("Done generating TLS certificates") 667 } 668 669 certData, parsedCert, err := cert.LoadCert( 670 cfg.TLSCertPath, cfg.TLSKeyPath, 671 ) 672 if err != nil { 673 return nil, nil, nil, nil, err 674 } 675 676 // We check whether the certifcate we have on disk match the IPs and 677 // domains specified by the config. If the extra IPs or domains have 678 // changed from when the certificate was created, we will refresh the 679 // certificate if auto refresh is active. 680 refresh := false 681 if cfg.TLSAutoRefresh { 682 refresh, err = cert.IsOutdated( 683 parsedCert, cfg.TLSExtraIPs, 684 cfg.TLSExtraDomains, cfg.TLSDisableAutofill, 685 ) 686 if err != nil { 687 return nil, nil, nil, nil, err 688 } 689 } 690 691 // If the certificate expired or it was outdated, delete it and the TLS 692 // key and generate a new pair. 693 if time.Now().After(parsedCert.NotAfter) || refresh { 694 ltndLog.Info("TLS certificate is expired or outdated, " + 695 "generating a new one") 696 697 err := os.Remove(cfg.TLSCertPath) 698 if err != nil { 699 return nil, nil, nil, nil, err 700 } 701 702 err = os.Remove(cfg.TLSKeyPath) 703 if err != nil { 704 return nil, nil, nil, nil, err 705 } 706 707 rpcsLog.Infof("Renewing TLS certificates...") 708 err = cert.GenCertPair( 709 "lnd autogenerated cert", cfg.TLSCertPath, 710 cfg.TLSKeyPath, cfg.TLSExtraIPs, cfg.TLSExtraDomains, 711 cfg.TLSDisableAutofill, cfg.TLSCertDuration, 712 ) 713 if err != nil { 714 return nil, nil, nil, nil, err 715 } 716 rpcsLog.Infof("Done renewing TLS certificates") 717 718 // Reload the certificate data. 719 certData, _, err = cert.LoadCert( 720 cfg.TLSCertPath, cfg.TLSKeyPath, 721 ) 722 if err != nil { 723 return nil, nil, nil, nil, err 724 } 725 } 726 727 tlsCfg := cert.TLSConfFromCert(certData) 728 729 restCreds, err := credentials.NewClientTLSFromFile(cfg.TLSCertPath, "") 730 if err != nil { 731 return nil, nil, nil, nil, err 732 } 733 734 // If Let's Encrypt is enabled, instantiate autocert to request/renew 735 // the certificates. 736 cleanUp := func() {} 737 if cfg.LetsEncryptDomain != "" { 738 ltndLog.Infof("Using Let's Encrypt certificate for domain %v", 739 cfg.LetsEncryptDomain) 740 741 manager := autocert.Manager{ 742 Cache: autocert.DirCache(cfg.LetsEncryptDir), 743 Prompt: autocert.AcceptTOS, 744 HostPolicy: autocert.HostWhitelist(cfg.LetsEncryptDomain), 745 } 746 747 srv := &http.Server{ 748 Addr: cfg.LetsEncryptListen, 749 Handler: manager.HTTPHandler(nil), 750 } 751 shutdownCompleted := make(chan struct{}) 752 cleanUp = func() { 753 err := srv.Shutdown(context.Background()) 754 if err != nil { 755 ltndLog.Errorf("Autocert listener shutdown "+ 756 " error: %v", err) 757 758 return 759 } 760 <-shutdownCompleted 761 ltndLog.Infof("Autocert challenge listener stopped") 762 } 763 764 go func() { 765 ltndLog.Infof("Autocert challenge listener started "+ 766 "at %v", cfg.LetsEncryptListen) 767 768 err := srv.ListenAndServe() 769 if err != http.ErrServerClosed { 770 ltndLog.Errorf("autocert http: %v", err) 771 } 772 close(shutdownCompleted) 773 }() 774 775 getCertificate := func(h *tls.ClientHelloInfo) ( 776 *tls.Certificate, error) { 777 778 lecert, err := manager.GetCertificate(h) 779 if err != nil { 780 ltndLog.Errorf("GetCertificate: %v", err) 781 return &certData, nil 782 } 783 784 return lecert, err 785 } 786 787 // The self-signed tls.cert remains available as fallback. 788 tlsCfg.GetCertificate = getCertificate 789 } 790 791 serverCreds := credentials.NewTLS(tlsCfg) 792 serverOpts := []grpc.ServerOption{grpc.Creds(serverCreds)} 793 794 // For our REST dial options, we'll still use TLS, but also increase 795 // the max message size that we'll decode to allow clients to hit 796 // endpoints which return more data such as the DescribeGraph call. 797 // We set this to 200MiB atm. Should be the same value as maxMsgRecvSize 798 // in cmd/lncli/main.go. 799 restDialOpts := []grpc.DialOption{ 800 grpc.WithTransportCredentials(restCreds), 801 grpc.WithDefaultCallOptions( 802 grpc.MaxCallRecvMsgSize(1 * 1024 * 1024 * 200), 803 ), 804 } 805 806 // Return a function closure that can be used to listen on a given 807 // address with the current TLS config. 808 restListen := func(addr net.Addr) (net.Listener, error) { 809 // For restListen we will call ListenOnAddress if TLS is 810 // disabled. 811 if cfg.DisableRestTLS { 812 return lncfg.ListenOnAddress(addr) 813 } 814 815 return lncfg.TLSListenOnAddress(addr, tlsCfg) 816 } 817 818 return serverOpts, restDialOpts, restListen, cleanUp, nil 819 } 820 821 // fileExists reports whether the named file or directory exists. 822 // This function is taken from https://github.com/decred/dcrd 823 func fileExists(name string) bool { 824 if _, err := os.Stat(name); err != nil { 825 if os.IsNotExist(err) { 826 return false 827 } 828 } 829 return true 830 } 831 832 // bakeMacaroon creates a new macaroon with newest version and the given 833 // permissions then returns it binary serialized. 834 func bakeMacaroon(ctx context.Context, svc *macaroons.Service, 835 permissions []bakery.Op) ([]byte, error) { 836 837 mac, err := svc.NewMacaroon( 838 ctx, macaroons.DefaultRootKeyID, permissions..., 839 ) 840 if err != nil { 841 return nil, err 842 } 843 844 return mac.M().MarshalBinary() 845 } 846 847 // genMacaroons generates three macaroon files; one admin-level, one for 848 // invoice access and one read-only. These can also be used to generate more 849 // granular macaroons. 850 func genMacaroons(ctx context.Context, svc *macaroons.Service, 851 admFile, roFile, invoiceFile string) error { 852 853 // First, we'll generate a macaroon that only allows the caller to 854 // access invoice related calls. This is useful for merchants and other 855 // services to allow an isolated instance that can only query and 856 // modify invoices. 857 invoiceMacBytes, err := bakeMacaroon(ctx, svc, invoicePermissions) 858 if err != nil { 859 return err 860 } 861 err = ioutil.WriteFile(invoiceFile, invoiceMacBytes, 0644) 862 if err != nil { 863 _ = os.Remove(invoiceFile) 864 return err 865 } 866 867 // Generate the read-only macaroon and write it to a file. 868 roBytes, err := bakeMacaroon(ctx, svc, readPermissions) 869 if err != nil { 870 return err 871 } 872 if err = ioutil.WriteFile(roFile, roBytes, 0644); err != nil { 873 _ = os.Remove(roFile) 874 return err 875 } 876 877 // Generate the admin macaroon and write it to a file. 878 admBytes, err := bakeMacaroon(ctx, svc, adminPermissions()) 879 if err != nil { 880 return err 881 } 882 883 err = ioutil.WriteFile(admFile, admBytes, adminMacaroonFilePermissions) 884 if err != nil { 885 _ = os.Remove(admFile) 886 return err 887 } 888 889 return nil 890 } 891 892 // adminPermissions returns a list of all permissions in a safe way that doesn't 893 // modify any of the source lists. 894 func adminPermissions() []bakery.Op { 895 admin := make([]bakery.Op, len(readPermissions)+len(writePermissions)) 896 copy(admin[:len(readPermissions)], readPermissions) 897 copy(admin[len(readPermissions):], writePermissions) 898 return admin 899 } 900 901 // createWalletUnlockerService creates a WalletUnlockerService from the passed 902 // config. 903 func createWalletUnlockerService(cfg *Config) *walletunlocker.UnlockerService { 904 chainConfig := cfg.Decred 905 906 // The macaroonFiles are passed to the wallet unlocker so they can be 907 // deleted and recreated in case the root macaroon key is also changed 908 // during the change password operation. 909 macaroonFiles := []string{ 910 cfg.AdminMacPath, cfg.ReadMacPath, cfg.InvoiceMacPath, 911 } 912 913 return walletunlocker.New( 914 chainConfig.ChainDir, cfg.ActiveNetParams.Params, 915 macaroonFiles, cfg.DB.Bolt.DBTimeout, 916 cfg.Dcrwallet.GRPCHost, cfg.Dcrwallet.CertPath, 917 cfg.Dcrwallet.ClientKeyPath, cfg.Dcrwallet.ClientCertPath, 918 cfg.Dcrwallet.AccountNumber, 919 ) 920 } 921 922 // startGrpcListen starts the GRPC server on the passed listeners. 923 func startGrpcListen(cfg *Config, grpcServer *grpc.Server, 924 listeners []*ListenerWithSignal) error { 925 926 var grpcAddrNotifier grpcListenerEventServer 927 if cfg.RPCListenerEvents { 928 grpcAddrNotifier = newGRPCListenerEventServer(outgoingPipeMessages) 929 } 930 931 // Use a WaitGroup so we can be sure the instructions on how to input the 932 // password is the last thing to be printed to the console. 933 var wg sync.WaitGroup 934 935 for _, lis := range listeners { 936 wg.Add(1) 937 go func(lis *ListenerWithSignal) { 938 rpcsLog.Infof("RPC server listening on %s", lis.Addr()) 939 940 // Close the ready chan to indicate we are listening. 941 close(lis.Ready) 942 grpcAddrNotifier.notify(lis.Addr().String()) 943 944 wg.Done() 945 _ = grpcServer.Serve(lis) 946 }(lis) 947 } 948 949 // If Prometheus monitoring is enabled, start the Prometheus exporter. 950 if cfg.Prometheus.Enabled() { 951 err := monitoring.ExportPrometheusMetrics( 952 grpcServer, cfg.Prometheus, 953 ) 954 if err != nil { 955 return err 956 } 957 } 958 959 // Wait for gRPC servers to be up running. 960 wg.Wait() 961 962 return nil 963 } 964 965 // startRestProxy starts the given REST proxy on the listeners found in the 966 // config. 967 func startRestProxy(cfg *Config, rpcServer *rpcServer, restDialOpts []grpc.DialOption, 968 restListen func(net.Addr) (net.Listener, error)) (func(), error) { 969 970 var jsonrpcAddrNotifier jsonrpcListenerEventServer 971 if cfg.RPCListenerEvents { 972 jsonrpcAddrNotifier = newJSONRPCListenerEventServer(outgoingPipeMessages) 973 } 974 975 // We use the first RPC listener as the destination for our REST proxy. 976 // If the listener is set to listen on all interfaces, we replace it 977 // with localhost, as we cannot dial it directly. 978 restProxyDest := cfg.RPCListeners[0].String() 979 switch { 980 case strings.Contains(restProxyDest, "0.0.0.0"): 981 restProxyDest = strings.Replace( 982 restProxyDest, "0.0.0.0", "127.0.0.1", 1, 983 ) 984 985 case strings.Contains(restProxyDest, "[::]"): 986 restProxyDest = strings.Replace( 987 restProxyDest, "[::]", "[::1]", 1, 988 ) 989 } 990 991 var shutdownFuncs []func() 992 shutdown := func() { 993 for _, shutdownFn := range shutdownFuncs { 994 shutdownFn() 995 } 996 } 997 998 // Start a REST proxy for our gRPC server. 999 ctx := context.Background() 1000 ctx, cancel := context.WithCancel(ctx) 1001 shutdownFuncs = append(shutdownFuncs, cancel) 1002 1003 // We'll set up a proxy that will forward REST calls to the GRPC 1004 // server. 1005 // 1006 // The default JSON marshaler of the REST proxy only sets OrigName to 1007 // true, which instructs it to use the same field names as specified in 1008 // the proto file and not switch to camel case. What we also want is 1009 // that the marshaler prints all values, even if they are falsey. 1010 customMarshalerOption := proxy.WithMarshalerOption( 1011 proxy.MIMEWildcard, &proxy.JSONPb{ 1012 MarshalOptions: protojson.MarshalOptions{ 1013 UseProtoNames: true, 1014 EmitUnpopulated: true, 1015 }, 1016 }, 1017 ) 1018 mux := proxy.NewServeMux( 1019 customMarshalerOption, 1020 1021 // Don't allow falling back to other HTTP methods, we want exact 1022 // matches only. The actual method to be used can be overwritten 1023 // by setting X-HTTP-Method-Override so there should be no 1024 // reason for not specifying the correct method in the first 1025 // place. 1026 proxy.WithDisablePathLengthFallback(), 1027 ) 1028 1029 // Register our services with the REST proxy. 1030 err := lnrpc.RegisterWalletUnlockerHandlerFromEndpoint( 1031 ctx, mux, restProxyDest, restDialOpts, 1032 ) 1033 if err != nil { 1034 return nil, err 1035 } 1036 1037 err = lnrpc.RegisterStateHandlerFromEndpoint( 1038 ctx, mux, restProxyDest, restDialOpts, 1039 ) 1040 if err != nil { 1041 return nil, err 1042 } 1043 1044 err = rpcServer.RegisterWithRestProxy( 1045 ctx, mux, restDialOpts, restProxyDest, 1046 ) 1047 if err != nil { 1048 return nil, err 1049 } 1050 1051 // Wrap the default grpc-gateway handler with the WebSocket handler. 1052 restHandler := lnrpc.NewWebSocketProxy( 1053 mux, rpcsLog, cfg.WSPingInterval, cfg.WSPongWait, 1054 lnrpc.LndClientStreamingURIs, 1055 ) 1056 1057 // Use a WaitGroup so we can be sure the instructions on how to input the 1058 // password is the last thing to be printed to the console. 1059 var wg sync.WaitGroup 1060 1061 // Now spin up a network listener for each requested port and start a 1062 // goroutine that serves REST with the created mux there. 1063 for _, restEndpoint := range cfg.RESTListeners { 1064 lis, err := restListen(restEndpoint) 1065 if err != nil { 1066 ltndLog.Errorf("gRPC proxy unable to listen on %s", 1067 restEndpoint) 1068 return nil, err 1069 } 1070 1071 shutdownFuncs = append(shutdownFuncs, func() { 1072 err := lis.Close() 1073 if err != nil { 1074 rpcsLog.Errorf("Error closing listener: %v", 1075 err) 1076 } 1077 }) 1078 1079 wg.Add(1) 1080 go func() { 1081 rpcsLog.Infof("gRPC proxy started at %s", lis.Addr()) 1082 1083 // Create our proxy chain now. A request will pass 1084 // through the following chain: 1085 // req ---> CORS handler --> WS proxy ---> 1086 // REST proxy --> gRPC endpoint 1087 corsHandler := allowCORS(restHandler, cfg.RestCORS) 1088 jsonrpcAddrNotifier.notify(lis.Addr().String()) 1089 1090 wg.Done() 1091 err := http.Serve(lis, corsHandler) 1092 if err != nil && !lnrpc.IsClosedConnError(err) { 1093 rpcsLog.Error(err) 1094 } 1095 }() 1096 } 1097 1098 // Wait for REST servers to be up running. 1099 wg.Wait() 1100 1101 return shutdown, nil 1102 }