rpcserver: move TLS listen config to closure
This commit is contained in:
parent
36556cb772
commit
a2a924e1e5
91
lnd.go
91
lnd.go
@ -270,7 +270,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
|
|||||||
defer cleanUp()
|
defer cleanUp()
|
||||||
|
|
||||||
// Only process macaroons if --no-macaroons isn't set.
|
// Only process macaroons if --no-macaroons isn't set.
|
||||||
tlsCfg, restCreds, restProxyDest, cleanUp, err := getTLSConfig(cfg)
|
serverOpts, restDialOpts, restListen, cleanUp, err := getTLSConfig(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := fmt.Errorf("unable to load TLS credentials: %v", err)
|
err := fmt.Errorf("unable to load TLS credentials: %v", err)
|
||||||
ltndLog.Error(err)
|
ltndLog.Error(err)
|
||||||
@ -279,19 +279,20 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
|
|||||||
|
|
||||||
defer cleanUp()
|
defer cleanUp()
|
||||||
|
|
||||||
serverCreds := credentials.NewTLS(tlsCfg)
|
// We use the first RPC listener as the destination for our REST proxy.
|
||||||
serverOpts := []grpc.ServerOption{grpc.Creds(serverCreds)}
|
// If the listener is set to listen on all interfaces, we replace it
|
||||||
|
// with localhost, as we cannot dial it directly.
|
||||||
|
restProxyDest := cfg.RPCListeners[0].String()
|
||||||
|
switch {
|
||||||
|
case strings.Contains(restProxyDest, "0.0.0.0"):
|
||||||
|
restProxyDest = strings.Replace(
|
||||||
|
restProxyDest, "0.0.0.0", "127.0.0.1", 1,
|
||||||
|
)
|
||||||
|
|
||||||
// For our REST dial options, we'll still use TLS, but also increase
|
case strings.Contains(restProxyDest, "[::]"):
|
||||||
// the max message size that we'll decode to allow clients to hit
|
restProxyDest = strings.Replace(
|
||||||
// endpoints which return more data such as the DescribeGraph call.
|
restProxyDest, "[::]", "[::1]", 1,
|
||||||
// We set this to 200MiB atm. Should be the same value as maxMsgRecvSize
|
)
|
||||||
// in cmd/lncli/main.go.
|
|
||||||
restDialOpts := []grpc.DialOption{
|
|
||||||
grpc.WithTransportCredentials(*restCreds),
|
|
||||||
grpc.WithDefaultCallOptions(
|
|
||||||
grpc.MaxCallRecvMsgSize(1 * 1024 * 1024 * 200),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before starting the wallet, we'll create and start our Neutrino
|
// Before starting the wallet, we'll create and start our Neutrino
|
||||||
@ -380,7 +381,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
|
|||||||
if !cfg.NoSeedBackup {
|
if !cfg.NoSeedBackup {
|
||||||
params, shutdown, err := waitForWalletPassword(
|
params, shutdown, err := waitForWalletPassword(
|
||||||
cfg, cfg.RESTListeners, serverOpts, restDialOpts,
|
cfg, cfg.RESTListeners, serverOpts, restDialOpts,
|
||||||
restProxyDest, tlsCfg, walletUnlockerListeners,
|
restProxyDest, restListen, walletUnlockerListeners,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := fmt.Errorf("unable to set up wallet password "+
|
err := fmt.Errorf("unable to set up wallet password "+
|
||||||
@ -730,7 +731,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
|
|||||||
rpcServer, err := newRPCServer(
|
rpcServer, err := newRPCServer(
|
||||||
cfg, server, macaroonService, cfg.SubRPCServers, serverOpts,
|
cfg, server, macaroonService, cfg.SubRPCServers, serverOpts,
|
||||||
restDialOpts, restProxyDest, atplManager, server.invoices,
|
restDialOpts, restProxyDest, atplManager, server.invoices,
|
||||||
tower, tlsCfg, rpcListeners, chainedAcceptor,
|
tower, restListen, rpcListeners, chainedAcceptor,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := fmt.Errorf("unable to create RPC server: %v", err)
|
err := fmt.Errorf("unable to create RPC server: %v", err)
|
||||||
@ -832,8 +833,8 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
|
|||||||
|
|
||||||
// getTLSConfig returns a TLS configuration for the gRPC server and credentials
|
// getTLSConfig returns a TLS configuration for the gRPC server and credentials
|
||||||
// and a proxy destination for the REST reverse proxy.
|
// and a proxy destination for the REST reverse proxy.
|
||||||
func getTLSConfig(cfg *Config) (*tls.Config, *credentials.TransportCredentials,
|
func getTLSConfig(cfg *Config) ([]grpc.ServerOption, []grpc.DialOption,
|
||||||
string, func(), error) {
|
func(net.Addr) (net.Listener, error), func(), error) {
|
||||||
|
|
||||||
// Ensure we create TLS key and certificate if they don't exist.
|
// Ensure we create TLS key and certificate if they don't exist.
|
||||||
if !fileExists(cfg.TLSCertPath) && !fileExists(cfg.TLSKeyPath) {
|
if !fileExists(cfg.TLSCertPath) && !fileExists(cfg.TLSKeyPath) {
|
||||||
@ -844,7 +845,7 @@ func getTLSConfig(cfg *Config) (*tls.Config, *credentials.TransportCredentials,
|
|||||||
cfg.TLSDisableAutofill, cert.DefaultAutogenValidity,
|
cfg.TLSDisableAutofill, cert.DefaultAutogenValidity,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, "", nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
rpcsLog.Infof("Done generating TLS certificates")
|
rpcsLog.Infof("Done generating TLS certificates")
|
||||||
}
|
}
|
||||||
@ -853,7 +854,7 @@ func getTLSConfig(cfg *Config) (*tls.Config, *credentials.TransportCredentials,
|
|||||||
cfg.TLSCertPath, cfg.TLSKeyPath,
|
cfg.TLSCertPath, cfg.TLSKeyPath,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, "", nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// We check whether the certifcate we have on disk match the IPs and
|
// We check whether the certifcate we have on disk match the IPs and
|
||||||
@ -867,7 +868,7 @@ func getTLSConfig(cfg *Config) (*tls.Config, *credentials.TransportCredentials,
|
|||||||
cfg.TLSExtraDomains, cfg.TLSDisableAutofill,
|
cfg.TLSExtraDomains, cfg.TLSDisableAutofill,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, "", nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -879,12 +880,12 @@ func getTLSConfig(cfg *Config) (*tls.Config, *credentials.TransportCredentials,
|
|||||||
|
|
||||||
err := os.Remove(cfg.TLSCertPath)
|
err := os.Remove(cfg.TLSCertPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, "", nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = os.Remove(cfg.TLSKeyPath)
|
err = os.Remove(cfg.TLSKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, "", nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rpcsLog.Infof("Renewing TLS certificates...")
|
rpcsLog.Infof("Renewing TLS certificates...")
|
||||||
@ -894,7 +895,7 @@ func getTLSConfig(cfg *Config) (*tls.Config, *credentials.TransportCredentials,
|
|||||||
cfg.TLSDisableAutofill, cert.DefaultAutogenValidity,
|
cfg.TLSDisableAutofill, cert.DefaultAutogenValidity,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, "", nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
rpcsLog.Infof("Done renewing TLS certificates")
|
rpcsLog.Infof("Done renewing TLS certificates")
|
||||||
|
|
||||||
@ -903,7 +904,7 @@ func getTLSConfig(cfg *Config) (*tls.Config, *credentials.TransportCredentials,
|
|||||||
cfg.TLSCertPath, cfg.TLSKeyPath,
|
cfg.TLSCertPath, cfg.TLSKeyPath,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, "", nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -911,20 +912,7 @@ func getTLSConfig(cfg *Config) (*tls.Config, *credentials.TransportCredentials,
|
|||||||
|
|
||||||
restCreds, err := credentials.NewClientTLSFromFile(cfg.TLSCertPath, "")
|
restCreds, err := credentials.NewClientTLSFromFile(cfg.TLSCertPath, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, "", nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
|
||||||
|
|
||||||
restProxyDest := cfg.RPCListeners[0].String()
|
|
||||||
switch {
|
|
||||||
case strings.Contains(restProxyDest, "0.0.0.0"):
|
|
||||||
restProxyDest = strings.Replace(
|
|
||||||
restProxyDest, "0.0.0.0", "127.0.0.1", 1,
|
|
||||||
)
|
|
||||||
|
|
||||||
case strings.Contains(restProxyDest, "[::]"):
|
|
||||||
restProxyDest = strings.Replace(
|
|
||||||
restProxyDest, "[::]", "[::1]", 1,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If Let's Encrypt is enabled, instantiate autocert to request/renew
|
// If Let's Encrypt is enabled, instantiate autocert to request/renew
|
||||||
@ -984,7 +972,28 @@ func getTLSConfig(cfg *Config) (*tls.Config, *credentials.TransportCredentials,
|
|||||||
tlsCfg.GetCertificate = getCertificate
|
tlsCfg.GetCertificate = getCertificate
|
||||||
}
|
}
|
||||||
|
|
||||||
return tlsCfg, &restCreds, restProxyDest, cleanUp, nil
|
serverCreds := credentials.NewTLS(tlsCfg)
|
||||||
|
serverOpts := []grpc.ServerOption{grpc.Creds(serverCreds)}
|
||||||
|
|
||||||
|
// For our REST dial options, we'll still use TLS, but also increase
|
||||||
|
// the max message size that we'll decode to allow clients to hit
|
||||||
|
// endpoints which return more data such as the DescribeGraph call.
|
||||||
|
// We set this to 200MiB atm. Should be the same value as maxMsgRecvSize
|
||||||
|
// in cmd/lncli/main.go.
|
||||||
|
restDialOpts := []grpc.DialOption{
|
||||||
|
grpc.WithTransportCredentials(restCreds),
|
||||||
|
grpc.WithDefaultCallOptions(
|
||||||
|
grpc.MaxCallRecvMsgSize(1 * 1024 * 1024 * 200),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a function closure that can be used to listen on a given
|
||||||
|
// address with the current TLS config.
|
||||||
|
restListen := func(addr net.Addr) (net.Listener, error) {
|
||||||
|
return lncfg.TLSListenOnAddress(addr, tlsCfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return serverOpts, restDialOpts, restListen, cleanUp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// fileExists reports whether the named file or directory exists.
|
// fileExists reports whether the named file or directory exists.
|
||||||
@ -1109,7 +1118,7 @@ type WalletUnlockParams struct {
|
|||||||
// the user to this RPC server.
|
// the user to this RPC server.
|
||||||
func waitForWalletPassword(cfg *Config, restEndpoints []net.Addr,
|
func waitForWalletPassword(cfg *Config, restEndpoints []net.Addr,
|
||||||
serverOpts []grpc.ServerOption, restDialOpts []grpc.DialOption,
|
serverOpts []grpc.ServerOption, restDialOpts []grpc.DialOption,
|
||||||
restProxyDest string, tlsConf *tls.Config,
|
restProxyDest string, restListen func(net.Addr) (net.Listener, error),
|
||||||
getListeners rpcListeners) (*WalletUnlockParams, func(), error) {
|
getListeners rpcListeners) (*WalletUnlockParams, func(), error) {
|
||||||
|
|
||||||
chainConfig := cfg.Bitcoin
|
chainConfig := cfg.Bitcoin
|
||||||
@ -1188,7 +1197,7 @@ func waitForWalletPassword(cfg *Config, restEndpoints []net.Addr,
|
|||||||
srv := &http.Server{Handler: allowCORS(mux, cfg.RestCORS)}
|
srv := &http.Server{Handler: allowCORS(mux, cfg.RestCORS)}
|
||||||
|
|
||||||
for _, restEndpoint := range restEndpoints {
|
for _, restEndpoint := range restEndpoints {
|
||||||
lis, err := lncfg.TLSListenOnAddress(restEndpoint, tlsConf)
|
lis, err := restListen(restEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ltndLog.Errorf("Password gRPC proxy unable to listen "+
|
ltndLog.Errorf("Password gRPC proxy unable to listen "+
|
||||||
"on %s", restEndpoint)
|
"on %s", restEndpoint)
|
||||||
|
16
rpcserver.go
16
rpcserver.go
@ -3,12 +3,12 @@ package lnd
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
@ -512,9 +512,10 @@ type rpcServer struct {
|
|||||||
// restProxyDest is the address to forward REST requests to.
|
// restProxyDest is the address to forward REST requests to.
|
||||||
restProxyDest string
|
restProxyDest string
|
||||||
|
|
||||||
// tlsCfg is the TLS config that allows the REST server proxy to
|
// restListen is a function closure that allows the REST server proxy to
|
||||||
// connect to the main gRPC server to proxy all incoming requests.
|
// connect to the main gRPC server to proxy all incoming requests,
|
||||||
tlsCfg *tls.Config
|
// applying the current TLS configuration, if any.
|
||||||
|
restListen func(net.Addr) (net.Listener, error)
|
||||||
|
|
||||||
// routerBackend contains the backend implementation of the router
|
// routerBackend contains the backend implementation of the router
|
||||||
// rpc sub server.
|
// rpc sub server.
|
||||||
@ -551,7 +552,8 @@ func newRPCServer(cfg *Config, s *server, macService *macaroons.Service,
|
|||||||
subServerCgs *subRPCServerConfigs, serverOpts []grpc.ServerOption,
|
subServerCgs *subRPCServerConfigs, serverOpts []grpc.ServerOption,
|
||||||
restDialOpts []grpc.DialOption, restProxyDest string,
|
restDialOpts []grpc.DialOption, restProxyDest string,
|
||||||
atpl *autopilot.Manager, invoiceRegistry *invoices.InvoiceRegistry,
|
atpl *autopilot.Manager, invoiceRegistry *invoices.InvoiceRegistry,
|
||||||
tower *watchtower.Standalone, tlsCfg *tls.Config,
|
tower *watchtower.Standalone,
|
||||||
|
restListen func(net.Addr) (net.Listener, error),
|
||||||
getListeners rpcListeners,
|
getListeners rpcListeners,
|
||||||
chanPredicate *chanacceptor.ChainedAcceptor) (*rpcServer, error) {
|
chanPredicate *chanacceptor.ChainedAcceptor) (*rpcServer, error) {
|
||||||
|
|
||||||
@ -754,7 +756,7 @@ func newRPCServer(cfg *Config, s *server, macService *macaroons.Service,
|
|||||||
listenerCleanUp: []func(){cleanup},
|
listenerCleanUp: []func(){cleanup},
|
||||||
restProxyDest: restProxyDest,
|
restProxyDest: restProxyDest,
|
||||||
subServers: subServers,
|
subServers: subServers,
|
||||||
tlsCfg: tlsCfg,
|
restListen: restListen,
|
||||||
grpcServer: grpcServer,
|
grpcServer: grpcServer,
|
||||||
server: s,
|
server: s,
|
||||||
routerBackend: routerBackend,
|
routerBackend: routerBackend,
|
||||||
@ -901,7 +903,7 @@ func (r *rpcServer) Start() error {
|
|||||||
// Now spin up a network listener for each requested port and start a
|
// Now spin up a network listener for each requested port and start a
|
||||||
// goroutine that serves REST with the created mux there.
|
// goroutine that serves REST with the created mux there.
|
||||||
for _, restEndpoint := range r.cfg.RESTListeners {
|
for _, restEndpoint := range r.cfg.RESTListeners {
|
||||||
lis, err := lncfg.TLSListenOnAddress(restEndpoint, r.tlsCfg)
|
lis, err := r.restListen(restEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ltndLog.Errorf("gRPC proxy unable to listen on %s",
|
ltndLog.Errorf("gRPC proxy unable to listen on %s",
|
||||||
restEndpoint)
|
restEndpoint)
|
||||||
|
Loading…
Reference in New Issue
Block a user