Skip to content
This repository was archived by the owner on Jun 25, 2024. It is now read-only.

Commit 60be908

Browse files
committed
lnd: Move TlsManager files to new files
1 parent 7e03297 commit 60be908

File tree

4 files changed

+423
-392
lines changed

4 files changed

+423
-392
lines changed

lnd.go

Lines changed: 0 additions & 251 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ package lnd
66

77
import (
88
"context"
9-
"crypto/tls"
10-
"crypto/x509"
119
"errors"
1210
"fmt"
1311
"io/ioutil"
@@ -24,7 +22,6 @@ import (
2422
proxy "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
2523
"github.com/lightningnetwork/lnd/autopilot"
2624
"github.com/lightningnetwork/lnd/build"
27-
"github.com/lightningnetwork/lnd/cert"
2825
"github.com/lightningnetwork/lnd/chanacceptor"
2926
"github.com/lightningnetwork/lnd/channeldb"
3027
"github.com/lightningnetwork/lnd/keychain"
@@ -38,7 +35,6 @@ import (
3835
"github.com/lightningnetwork/lnd/tor"
3936
"github.com/lightningnetwork/lnd/walletunlocker"
4037
"github.com/lightningnetwork/lnd/watchtower"
41-
"golang.org/x/crypto/acme/autocert"
4238
"google.golang.org/grpc"
4339
"google.golang.org/grpc/credentials"
4440
"google.golang.org/protobuf/encoding/protojson"
@@ -633,253 +629,6 @@ func Main(cfg *Config, lisCfg ListenerCfg, implCfg *ImplementationCfg,
633629
return nil
634630
}
635631

636-
// TLSManager generates/renews a TLS certificate when needed and returns the
637-
// certificate configuration options needed for gRPC and REST.
638-
type TLSManager struct {
639-
cfg *Config
640-
}
641-
642-
// NewTLSManager returns a reference to a new TLSManager.
643-
func NewTLSManager(cfg *Config) *TLSManager {
644-
return &TLSManager{
645-
cfg: cfg,
646-
}
647-
}
648-
649-
// getConfig returns a TLS configuration for the gRPC server and credentials
650-
// and a proxy destination for the REST reverse proxy.
651-
func (t *TLSManager) getConfig() ([]grpc.ServerOption, []grpc.DialOption,
652-
func(net.Addr) (net.Listener, error), func(), error) {
653-
654-
tlsCfg, cleanUp, err := t.generateOrRenewCert()
655-
if err != nil {
656-
return nil, nil, nil, nil, err
657-
}
658-
659-
// Now that we know that we have a ceritificate, let's generate the
660-
// required config options.
661-
restCreds, err := credentials.NewClientTLSFromFile(
662-
t.cfg.TLSCertPath, "",
663-
)
664-
if err != nil {
665-
return nil, nil, nil, nil, err
666-
}
667-
668-
serverCreds := credentials.NewTLS(tlsCfg)
669-
serverOpts := []grpc.ServerOption{grpc.Creds(serverCreds)}
670-
671-
// For our REST dial options, we'll still use TLS, but also increase
672-
// the max message size that we'll decode to allow clients to hit
673-
// endpoints which return more data such as the DescribeGraph call.
674-
// We set this to 200MiB atm. Should be the same value as maxMsgRecvSize
675-
// in cmd/lncli/main.go.
676-
restDialOpts := []grpc.DialOption{
677-
grpc.WithTransportCredentials(restCreds),
678-
grpc.WithDefaultCallOptions(
679-
grpc.MaxCallRecvMsgSize(lnrpc.MaxGrpcMsgSize),
680-
),
681-
}
682-
683-
// Return a function closure that can be used to listen on a given
684-
// address with the current TLS config.
685-
restListen := func(addr net.Addr) (net.Listener, error) {
686-
// For restListen we will call ListenOnAddress if TLS is
687-
// disabled.
688-
if t.cfg.DisableRestTLS {
689-
return lncfg.ListenOnAddress(addr)
690-
}
691-
692-
return lncfg.TLSListenOnAddress(addr, tlsCfg)
693-
}
694-
695-
return serverOpts, restDialOpts, restListen, cleanUp, nil
696-
}
697-
698-
// generateOrRenewCert generates a new TLS certificate if we're not using one
699-
// yet or renews it if it's outdated.
700-
func (t *TLSManager) generateOrRenewCert() (*tls.Config, func(), error) {
701-
// Genereate a TLS pair if we don't have one yet.
702-
err := t.createTLSPair()
703-
if err != nil {
704-
return nil, nil, err
705-
}
706-
707-
certData, parsedCert, err := cert.LoadCert(
708-
t.cfg.TLSCertPath, t.cfg.TLSKeyPath,
709-
)
710-
if err != nil {
711-
return nil, nil, err
712-
}
713-
714-
// Check to see if the certificate needs to be renewed. If it does, we
715-
// return the newly generated certificate data instead.
716-
reloadedCertData, err := t.certMaintenance(parsedCert)
717-
if err != nil {
718-
return nil, nil, err
719-
}
720-
if reloadedCertData != nil {
721-
certData = *reloadedCertData
722-
}
723-
724-
tlsCfg := cert.TLSConfFromCert(certData)
725-
726-
cleanUp := t.setUpLetsEncrypt(&certData, tlsCfg)
727-
728-
return tlsCfg, cleanUp, nil
729-
}
730-
731-
// If a TLS pair doesn't exist yet, create them and write them to disk.
732-
func (t *TLSManager) createTLSPair() error {
733-
// Ensure we create TLS key and certificate if they don't exist.
734-
if fileExists(t.cfg.TLSCertPath) || fileExists(t.cfg.TLSKeyPath) {
735-
return nil
736-
}
737-
738-
rpcsLog.Infof("Generating TLS certificates...")
739-
err := cert.GenCertPair(
740-
"lnd autogenerated cert", t.cfg.TLSCertPath,
741-
t.cfg.TLSKeyPath, t.cfg.TLSExtraIPs,
742-
t.cfg.TLSExtraDomains, t.cfg.TLSDisableAutofill,
743-
t.cfg.TLSCertDuration,
744-
)
745-
rpcsLog.Infof("Done generating TLS certificates")
746-
747-
return err
748-
}
749-
750-
// certMaintenance checks if the certificate IP and domains matches the config,
751-
// and renews the certificate if either this data is outdated or the
752-
// certificate is expired.
753-
func (t *TLSManager) certMaintenance(
754-
parsedCert *x509.Certificate) (*tls.Certificate, error) {
755-
756-
// We check whether the certificate we have on disk match the IPs and
757-
// domains specified by the config. If the extra IPs or domains have
758-
// changed from when the certificate was created, we will refresh the
759-
// certificate if auto refresh is active.
760-
refresh := false
761-
var err error
762-
if t.cfg.TLSAutoRefresh {
763-
refresh, err = cert.IsOutdated(
764-
parsedCert, t.cfg.TLSExtraIPs,
765-
t.cfg.TLSExtraDomains, t.cfg.TLSDisableAutofill,
766-
)
767-
if err != nil {
768-
return nil, err
769-
}
770-
}
771-
772-
// If the certificate expired or it was outdated, delete it and the TLS
773-
// key and generate a new pair.
774-
if !time.Now().After(parsedCert.NotAfter) && !refresh {
775-
return nil, nil
776-
}
777-
778-
ltndLog.Info("TLS certificate is expired or outdated, " +
779-
"generating a new one")
780-
781-
err = os.Remove(t.cfg.TLSCertPath)
782-
if err != nil {
783-
return nil, err
784-
}
785-
786-
err = os.Remove(t.cfg.TLSKeyPath)
787-
if err != nil {
788-
return nil, err
789-
}
790-
791-
rpcsLog.Infof("Renewing TLS certificates...")
792-
err = cert.GenCertPair(
793-
"lnd autogenerated cert", t.cfg.TLSCertPath,
794-
t.cfg.TLSKeyPath, t.cfg.TLSExtraIPs,
795-
t.cfg.TLSExtraDomains, t.cfg.TLSDisableAutofill,
796-
t.cfg.TLSCertDuration,
797-
)
798-
if err != nil {
799-
return nil, err
800-
}
801-
rpcsLog.Infof("Done renewing TLS certificates")
802-
803-
// Reload the certificate data.
804-
reloadedCertData, _, err := cert.LoadCert(
805-
t.cfg.TLSCertPath, t.cfg.TLSKeyPath,
806-
)
807-
if err != nil {
808-
return nil, err
809-
}
810-
811-
return &reloadedCertData, nil
812-
}
813-
814-
// setUpLetsEncrypt automatically generates a Let's Encrypt certificate if the
815-
// option is set.
816-
func (t *TLSManager) setUpLetsEncrypt(certData *tls.Certificate,
817-
tlsCfg *tls.Config) func() {
818-
819-
// If Let's Encrypt is enabled, instantiate autocert to request/renew
820-
// the certificates.
821-
cleanUp := func() {}
822-
if t.cfg.LetsEncryptDomain == "" {
823-
return cleanUp
824-
}
825-
826-
ltndLog.Infof("Using Let's Encrypt certificate for domain %v",
827-
t.cfg.LetsEncryptDomain)
828-
829-
manager := autocert.Manager{
830-
Cache: autocert.DirCache(t.cfg.LetsEncryptDir),
831-
Prompt: autocert.AcceptTOS,
832-
HostPolicy: autocert.HostWhitelist(
833-
t.cfg.LetsEncryptDomain,
834-
),
835-
}
836-
837-
srv := &http.Server{
838-
Addr: t.cfg.LetsEncryptListen,
839-
Handler: manager.HTTPHandler(nil),
840-
}
841-
shutdownCompleted := make(chan struct{})
842-
cleanUp = func() {
843-
err := srv.Shutdown(context.Background())
844-
if err != nil {
845-
ltndLog.Errorf("Autocert listener shutdown "+
846-
" error: %v", err)
847-
848-
return
849-
}
850-
<-shutdownCompleted
851-
ltndLog.Infof("Autocert challenge listener stopped")
852-
}
853-
854-
go func() {
855-
ltndLog.Infof("Autocert challenge listener started "+
856-
"at %v", t.cfg.LetsEncryptListen)
857-
858-
err := srv.ListenAndServe()
859-
if err != http.ErrServerClosed {
860-
ltndLog.Errorf("autocert http: %v", err)
861-
}
862-
close(shutdownCompleted)
863-
}()
864-
865-
getCertificate := func(h *tls.ClientHelloInfo) (
866-
*tls.Certificate, error) {
867-
868-
lecert, err := manager.GetCertificate(h)
869-
if err != nil {
870-
ltndLog.Errorf("GetCertificate: %v", err)
871-
return certData, nil
872-
}
873-
874-
return lecert, err
875-
}
876-
877-
// The self-signed tls.cert remains available as fallback.
878-
tlsCfg.GetCertificate = getCertificate
879-
880-
return cleanUp
881-
}
882-
883632
// fileExists reports whether the named file or directory exists.
884633
// This function is taken from https://github.com/btcsuite/btcd
885634
func fileExists(name string) bool {

0 commit comments

Comments
 (0)