tls_manager.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. package lnd
  2. import (
  3. "bytes"
  4. "context"
  5. "crypto/tls"
  6. "crypto/x509"
  7. "errors"
  8. "fmt"
  9. "net"
  10. "net/http"
  11. "os"
  12. "time"
  13. "github.com/lightningnetwork/lnd/cert"
  14. "github.com/lightningnetwork/lnd/keychain"
  15. "github.com/lightningnetwork/lnd/lncfg"
  16. "github.com/lightningnetwork/lnd/lnencrypt"
  17. "github.com/lightningnetwork/lnd/lnrpc"
  18. "golang.org/x/crypto/acme/autocert"
  19. "google.golang.org/grpc"
  20. "google.golang.org/grpc/credentials"
  21. )
  22. const (
  23. // modifyFilePermissons is the file permission used for writing
  24. // encrypted tls files.
  25. modifyFilePermissions = 0600
  26. // validityHours is the number of hours the ephemeral tls certificate
  27. // will be valid, if encrypting tls certificates is turned on.
  28. validityHours = 24
  29. )
  30. var (
  31. // privateKeyPrefix is the prefix to a plaintext TLS key.
  32. // It should match these two key formats:
  33. // - `-----BEGIN PRIVATE KEY-----` (PKCS8).
  34. // - `-----BEGIN EC PRIVATE KEY-----` (SEC1/rfc5915, the legacy format).
  35. privateKeyPrefix = []byte("-----BEGIN ")
  36. )
  37. // TLSManagerCfg houses a set of values and methods that is passed to the
  38. // TLSManager for it to properly manage LND's TLS options.
  39. type TLSManagerCfg struct {
  40. TLSCertPath string
  41. TLSKeyPath string
  42. TLSEncryptKey bool
  43. TLSExtraIPs []string
  44. TLSExtraDomains []string
  45. TLSAutoRefresh bool
  46. TLSDisableAutofill bool
  47. TLSCertDuration time.Duration
  48. LetsEncryptDir string
  49. LetsEncryptDomain string
  50. LetsEncryptListen string
  51. DisableRestTLS bool
  52. HTTPHeaderTimeout time.Duration
  53. }
  54. // TLSManager generates/renews a TLS cert/key pair when needed. When required,
  55. // it encrypts the TLS key. It also returns the certificate configuration
  56. // options needed for gRPC and REST.
  57. type TLSManager struct {
  58. cfg *TLSManagerCfg
  59. // tlsReloader is able to reload the certificate with the
  60. // GetCertificate function. In getConfig, tlsCfg.GetCertificate is
  61. // pointed towards t.tlsReloader.GetCertificateFunc(). When
  62. // TLSReloader's AttemptReload is called, the cert that tlsReloader
  63. // holds is changed, in turn changing the cert data
  64. // tlsCfg.GetCertificate will return.
  65. tlsReloader *cert.TLSReloader
  66. // These options are only used if we're currently using an ephemeral
  67. // TLS certificate, used when we're encrypting the TLS key.
  68. ephemeralKey []byte
  69. ephemeralCert []byte
  70. ephemeralCertPath string
  71. }
  72. // NewTLSManager returns a reference to a new TLSManager.
  73. func NewTLSManager(cfg *TLSManagerCfg) *TLSManager {
  74. return &TLSManager{
  75. cfg: cfg,
  76. }
  77. }
  78. // getConfig returns a TLS configuration for the gRPC server and credentials
  79. // and a proxy destination for the REST reverse proxy.
  80. func (t *TLSManager) getConfig() ([]grpc.ServerOption, []grpc.DialOption,
  81. func(net.Addr) (net.Listener, error), func(), error) {
  82. var (
  83. keyBytes, certBytes []byte
  84. err error
  85. )
  86. if t.ephemeralKey != nil {
  87. keyBytes = t.ephemeralKey
  88. certBytes = t.ephemeralCert
  89. } else {
  90. certBytes, keyBytes, err = cert.GetCertBytesFromPath(
  91. t.cfg.TLSCertPath, t.cfg.TLSKeyPath,
  92. )
  93. if err != nil {
  94. return nil, nil, nil, nil, err
  95. }
  96. }
  97. certData, _, err := cert.LoadCertFromBytes(certBytes, keyBytes)
  98. if err != nil {
  99. return nil, nil, nil, nil, err
  100. }
  101. if t.tlsReloader == nil {
  102. tlsr, err := cert.NewTLSReloader(certBytes, keyBytes)
  103. if err != nil {
  104. return nil, nil, nil, nil, err
  105. }
  106. t.tlsReloader = tlsr
  107. }
  108. tlsCfg := cert.TLSConfFromCert(certData)
  109. tlsCfg.GetCertificate = t.tlsReloader.GetCertificateFunc()
  110. // If Let's Encrypt is enabled, we need to set up the autocert manager
  111. // and override the TLS config's GetCertificate function.
  112. cleanUp := t.setUpLetsEncrypt(&certData, tlsCfg)
  113. // Now that we know that we have a certificate, let's generate the
  114. // required config options.
  115. serverCreds := credentials.NewTLS(tlsCfg)
  116. serverOpts := []grpc.ServerOption{grpc.Creds(serverCreds)}
  117. // For our REST dial options, we skip TLS verification, and we also
  118. // increase the max message size that we'll decode to allow clients to
  119. // hit endpoints which return more data such as the DescribeGraph call.
  120. // We set this to 200MiB atm. Should be the same value as maxMsgRecvSize
  121. // in cmd/lncli/main.go.
  122. restDialOpts := []grpc.DialOption{
  123. // We are forwarding the requests directly to the address of our
  124. // own local listener. To not need to mess with the TLS
  125. // certificate (which might be tricky if we're using Let's
  126. // Encrypt or if the ephemeral tls cert is being used), we just
  127. // skip the certificate verification. Injecting a malicious
  128. // hostname into the listener address will result in an error
  129. // on startup so this should be quite safe.
  130. grpc.WithTransportCredentials(credentials.NewTLS(
  131. &tls.Config{InsecureSkipVerify: true},
  132. )),
  133. grpc.WithDefaultCallOptions(
  134. grpc.MaxCallRecvMsgSize(lnrpc.MaxGrpcMsgSize),
  135. ),
  136. }
  137. // Return a function closure that can be used to listen on a given
  138. // address with the current TLS config.
  139. restListen := func(addr net.Addr) (net.Listener, error) {
  140. // For restListen we will call ListenOnAddress if TLS is
  141. // disabled.
  142. if t.cfg.DisableRestTLS {
  143. return lncfg.ListenOnAddress(addr)
  144. }
  145. return lncfg.TLSListenOnAddress(addr, tlsCfg)
  146. }
  147. return serverOpts, restDialOpts, restListen, cleanUp, nil
  148. }
  149. // generateOrRenewCert generates a new TLS certificate if we're not using one
  150. // yet or renews it if it's outdated.
  151. func (t *TLSManager) generateOrRenewCert() (*tls.Config, error) {
  152. // Generete a TLS pair if we don't have one yet.
  153. var emptyKeyRing keychain.SecretKeyRing
  154. err := t.generateCertPair(emptyKeyRing)
  155. if err != nil {
  156. return nil, err
  157. }
  158. certData, parsedCert, err := cert.LoadCert(
  159. t.cfg.TLSCertPath, t.cfg.TLSKeyPath,
  160. )
  161. if err != nil {
  162. return nil, err
  163. }
  164. // Check to see if the certificate needs to be renewed. If it does, we
  165. // return the newly generated certificate data instead.
  166. reloadedCertData, err := t.maintainCert(parsedCert)
  167. if err != nil {
  168. return nil, err
  169. }
  170. if reloadedCertData != nil {
  171. certData = *reloadedCertData
  172. }
  173. tlsCfg := cert.TLSConfFromCert(certData)
  174. return tlsCfg, nil
  175. }
  176. // generateCertPair creates and writes a TLS pair to disk if the pair
  177. // doesn't exist yet. If the TLSEncryptKey setting is on, and a plaintext key
  178. // is already written to disk, this function overwrites the plaintext key with
  179. // the encrypted form.
  180. func (t *TLSManager) generateCertPair(keyRing keychain.SecretKeyRing) error {
  181. // Ensure we create TLS key and certificate if they don't exist.
  182. if lnrpc.FileExists(t.cfg.TLSCertPath) ||
  183. lnrpc.FileExists(t.cfg.TLSKeyPath) {
  184. // Handle discrepencies related to the TLSEncryptKey setting.
  185. return t.ensureEncryption(keyRing)
  186. }
  187. rpcsLog.Infof("Generating TLS certificates...")
  188. certBytes, keyBytes, err := cert.GenCertPair(
  189. "lnd autogenerated cert", t.cfg.TLSExtraIPs,
  190. t.cfg.TLSExtraDomains, t.cfg.TLSDisableAutofill,
  191. t.cfg.TLSCertDuration,
  192. )
  193. if err != nil {
  194. return err
  195. }
  196. if t.cfg.TLSEncryptKey {
  197. var b bytes.Buffer
  198. e, err := lnencrypt.KeyRingEncrypter(keyRing)
  199. if err != nil {
  200. return fmt.Errorf("unable to create "+
  201. "encrypt key %v", err)
  202. }
  203. err = e.EncryptPayloadToWriter(
  204. keyBytes, &b,
  205. )
  206. if err != nil {
  207. return err
  208. }
  209. keyBytes = b.Bytes()
  210. }
  211. err = cert.WriteCertPair(
  212. t.cfg.TLSCertPath, t.cfg.TLSKeyPath, certBytes, keyBytes,
  213. )
  214. rpcsLog.Infof("Done generating TLS certificates")
  215. return err
  216. }
  217. // ensureEncryption takes a look at a couple of things:
  218. // 1) If the TLS key is in plaintext, but TLSEncryptKey is set, we need to
  219. // encrypt the file and rewrite it to disk.
  220. // 2) On the flip side, if TLSEncryptKey is not set, but the key on disk
  221. // is encrypted, we need to error out and warn the user.
  222. func (t *TLSManager) ensureEncryption(keyRing keychain.SecretKeyRing) error {
  223. _, keyBytes, err := cert.GetCertBytesFromPath(
  224. t.cfg.TLSCertPath, t.cfg.TLSKeyPath,
  225. )
  226. if err != nil {
  227. return err
  228. }
  229. if t.cfg.TLSEncryptKey && bytes.HasPrefix(keyBytes, privateKeyPrefix) {
  230. var b bytes.Buffer
  231. e, err := lnencrypt.KeyRingEncrypter(keyRing)
  232. if err != nil {
  233. return fmt.Errorf("unable to generate encrypt key %w",
  234. err)
  235. }
  236. err = e.EncryptPayloadToWriter(keyBytes, &b)
  237. if err != nil {
  238. return err
  239. }
  240. err = os.WriteFile(
  241. t.cfg.TLSKeyPath, b.Bytes(), modifyFilePermissions,
  242. )
  243. if err != nil {
  244. return err
  245. }
  246. }
  247. // If the private key is encrypted but the user didn't pass
  248. // --tlsencryptkey we error out. This is because the wallet is not
  249. // unlocked yet and we don't have access to the keys yet for decryption.
  250. if !t.cfg.TLSEncryptKey && !bytes.HasPrefix(keyBytes,
  251. privateKeyPrefix) {
  252. ltndLog.Errorf("The TLS private key is encrypted on disk.")
  253. return errors.New("the TLS key is encrypted but the " +
  254. "--tlsencryptkey flag is not passed. Please either " +
  255. "restart lnd with the --tlsencryptkey flag or delete " +
  256. "the TLS files for regeneration")
  257. }
  258. return nil
  259. }
  260. // decryptTLSKeyBytes decrypts the TLS key.
  261. func decryptTLSKeyBytes(keyRing keychain.SecretKeyRing,
  262. encryptedData []byte) ([]byte, error) {
  263. reader := bytes.NewReader(encryptedData)
  264. encrypter, err := lnencrypt.KeyRingEncrypter(keyRing)
  265. if err != nil {
  266. return nil, err
  267. }
  268. plaintext, err := encrypter.DecryptPayloadFromReader(
  269. reader,
  270. )
  271. if err != nil {
  272. return nil, err
  273. }
  274. return plaintext, nil
  275. }
  276. // maintainCert checks if the certificate IP and domains matches the config,
  277. // and renews the certificate if either this data is outdated or the
  278. // certificate is expired.
  279. func (t *TLSManager) maintainCert(
  280. parsedCert *x509.Certificate) (*tls.Certificate, error) {
  281. // We check whether the certificate we have on disk match the IPs and
  282. // domains specified by the config. If the extra IPs or domains have
  283. // changed from when the certificate was created, we will refresh the
  284. // certificate if auto refresh is active.
  285. refresh := false
  286. var err error
  287. if t.cfg.TLSAutoRefresh {
  288. refresh, err = cert.IsOutdated(
  289. parsedCert, t.cfg.TLSExtraIPs,
  290. t.cfg.TLSExtraDomains, t.cfg.TLSDisableAutofill,
  291. )
  292. if err != nil {
  293. return nil, err
  294. }
  295. }
  296. // If the certificate expired or it was outdated, delete it and the TLS
  297. // key and generate a new pair.
  298. if !time.Now().After(parsedCert.NotAfter) && !refresh {
  299. return nil, nil
  300. }
  301. ltndLog.Info("TLS certificate is expired or outdated, " +
  302. "generating a new one")
  303. err = os.Remove(t.cfg.TLSCertPath)
  304. if err != nil {
  305. return nil, err
  306. }
  307. err = os.Remove(t.cfg.TLSKeyPath)
  308. if err != nil {
  309. return nil, err
  310. }
  311. rpcsLog.Infof("Renewing TLS certificates...")
  312. certBytes, keyBytes, err := cert.GenCertPair(
  313. "lnd autogenerated cert", t.cfg.TLSExtraIPs,
  314. t.cfg.TLSExtraDomains, t.cfg.TLSDisableAutofill,
  315. t.cfg.TLSCertDuration,
  316. )
  317. if err != nil {
  318. return nil, err
  319. }
  320. err = cert.WriteCertPair(
  321. t.cfg.TLSCertPath, t.cfg.TLSKeyPath, certBytes, keyBytes,
  322. )
  323. if err != nil {
  324. return nil, err
  325. }
  326. rpcsLog.Infof("Done renewing TLS certificates")
  327. // Reload the certificate data.
  328. reloadedCertData, _, err := cert.LoadCert(
  329. t.cfg.TLSCertPath, t.cfg.TLSKeyPath,
  330. )
  331. return &reloadedCertData, err
  332. }
  333. // setUpLetsEncrypt automatically generates a Let's Encrypt certificate if the
  334. // option is set.
  335. func (t *TLSManager) setUpLetsEncrypt(certData *tls.Certificate,
  336. tlsCfg *tls.Config) func() {
  337. // If Let's Encrypt is enabled, instantiate autocert to request/renew
  338. // the certificates.
  339. cleanUp := func() {}
  340. if t.cfg.LetsEncryptDomain == "" {
  341. return cleanUp
  342. }
  343. ltndLog.Infof("Using Let's Encrypt certificate for domain %v",
  344. t.cfg.LetsEncryptDomain)
  345. manager := autocert.Manager{
  346. Cache: autocert.DirCache(t.cfg.LetsEncryptDir),
  347. Prompt: autocert.AcceptTOS,
  348. HostPolicy: autocert.HostWhitelist(
  349. t.cfg.LetsEncryptDomain,
  350. ),
  351. }
  352. srv := &http.Server{
  353. Addr: t.cfg.LetsEncryptListen,
  354. Handler: manager.HTTPHandler(nil),
  355. ReadHeaderTimeout: t.cfg.HTTPHeaderTimeout,
  356. }
  357. shutdownCompleted := make(chan struct{})
  358. cleanUp = func() {
  359. err := srv.Shutdown(context.Background())
  360. if err != nil {
  361. ltndLog.Errorf("Autocert listener shutdown "+
  362. " error: %v", err)
  363. return
  364. }
  365. <-shutdownCompleted
  366. ltndLog.Infof("Autocert challenge listener stopped")
  367. }
  368. go func() {
  369. ltndLog.Infof("Autocert challenge listener started "+
  370. "at %v", t.cfg.LetsEncryptListen)
  371. err := srv.ListenAndServe()
  372. if err != http.ErrServerClosed {
  373. ltndLog.Errorf("autocert http: %v", err)
  374. }
  375. close(shutdownCompleted)
  376. }()
  377. getCertificate := func(h *tls.ClientHelloInfo) (
  378. *tls.Certificate, error) {
  379. lecert, err := manager.GetCertificate(h)
  380. if err != nil {
  381. ltndLog.Errorf("GetCertificate: %v", err)
  382. return certData, nil
  383. }
  384. return lecert, err
  385. }
  386. // The self-signed tls.cert remains available as fallback.
  387. tlsCfg.GetCertificate = getCertificate
  388. return cleanUp
  389. }
  390. // SetCertificateBeforeUnlock takes care of loading the certificate before
  391. // the wallet is unlocked. If the TLSEncryptKey setting is on, we need to
  392. // generate an ephemeral certificate we're able to use until the wallet is
  393. // unlocked and a new TLS pair can be encrypted to disk. Otherwise we can
  394. // process the certificate normally.
  395. func (t *TLSManager) SetCertificateBeforeUnlock() ([]grpc.ServerOption,
  396. []grpc.DialOption, func(net.Addr) (net.Listener, error), func(),
  397. error) {
  398. if t.cfg.TLSEncryptKey {
  399. _, err := t.loadEphemeralCertificate()
  400. if err != nil {
  401. return nil, nil, nil, nil, fmt.Errorf("unable to load "+
  402. "ephemeral certificate: %v", err)
  403. }
  404. } else {
  405. _, err := t.generateOrRenewCert()
  406. if err != nil {
  407. return nil, nil, nil, nil, fmt.Errorf("unable to "+
  408. "generate or renew TLS certificate: %v", err)
  409. }
  410. }
  411. serverOpts, restDialOpts, restListen, cleanUp, err := t.getConfig()
  412. if err != nil {
  413. return nil, nil, nil, nil, fmt.Errorf("unable to load TLS "+
  414. "credentials: %v", err)
  415. }
  416. return serverOpts, restDialOpts, restListen, cleanUp, nil
  417. }
  418. // loadEphemeralCertificate creates and loads the ephemeral certificate which
  419. // is used temporarily for secure communications before the wallet is unlocked.
  420. func (t *TLSManager) loadEphemeralCertificate() ([]byte, error) {
  421. rpcsLog.Infof("Generating ephemeral TLS certificates...")
  422. tmpValidity := validityHours * time.Hour
  423. // Append .tmp to the end of the cert for differentiation.
  424. tmpCertPath := t.cfg.TLSCertPath + ".tmp"
  425. // Pass in a blank string for the key path so the
  426. // function doesn't write them to disk.
  427. certBytes, keyBytes, err := cert.GenCertPair(
  428. "lnd ephemeral autogenerated cert", t.cfg.TLSExtraIPs,
  429. t.cfg.TLSExtraDomains, t.cfg.TLSDisableAutofill, tmpValidity,
  430. )
  431. if err != nil {
  432. return nil, err
  433. }
  434. t.setEphemeralSettings(keyBytes, certBytes)
  435. err = cert.WriteCertPair(tmpCertPath, "", certBytes, keyBytes)
  436. if err != nil {
  437. return nil, err
  438. }
  439. rpcsLog.Infof("Done generating ephemeral TLS certificates")
  440. return keyBytes, nil
  441. }
  442. // LoadPermanentCertificate deletes the ephemeral certificate file and
  443. // generates a new one with the real keyring.
  444. func (t *TLSManager) LoadPermanentCertificate(
  445. keyRing keychain.SecretKeyRing) error {
  446. if !t.cfg.TLSEncryptKey {
  447. return nil
  448. }
  449. tmpCertPath := t.cfg.TLSCertPath + ".tmp"
  450. err := os.Remove(tmpCertPath)
  451. if err != nil {
  452. ltndLog.Warn("Unable to delete temp cert at %v",
  453. tmpCertPath)
  454. }
  455. err = t.generateCertPair(keyRing)
  456. if err != nil {
  457. return err
  458. }
  459. certBytes, encryptedKeyBytes, err := cert.GetCertBytesFromPath(
  460. t.cfg.TLSCertPath, t.cfg.TLSKeyPath,
  461. )
  462. if err != nil {
  463. return err
  464. }
  465. reader := bytes.NewReader(encryptedKeyBytes)
  466. e, err := lnencrypt.KeyRingEncrypter(keyRing)
  467. if err != nil {
  468. return fmt.Errorf("unable to generate encrypt key %w",
  469. err)
  470. }
  471. keyBytes, err := e.DecryptPayloadFromReader(reader)
  472. if err != nil {
  473. return err
  474. }
  475. // Switch the server's TLS certificate to the persistent one. By
  476. // changing the cert data the TLSReloader points to,
  477. err = t.tlsReloader.AttemptReload(certBytes, keyBytes)
  478. if err != nil {
  479. return err
  480. }
  481. t.deleteEphemeralSettings()
  482. return nil
  483. }
  484. // setEphemeralSettings sets the TLSManager settings needed when an ephemeral
  485. // certificate is created.
  486. func (t *TLSManager) setEphemeralSettings(keyBytes, certBytes []byte) {
  487. t.ephemeralKey = keyBytes
  488. t.ephemeralCert = certBytes
  489. t.ephemeralCertPath = t.cfg.TLSCertPath + ".tmp"
  490. }
  491. // deleteEphemeralSettings deletes the TLSManager ephemeral settings that are
  492. // no longer needed when the ephemeral certificate is deleted so the Manager
  493. // knows we're no longer using it.
  494. func (t *TLSManager) deleteEphemeralSettings() {
  495. t.ephemeralKey = nil
  496. t.ephemeralCert = nil
  497. t.ephemeralCertPath = ""
  498. }
  499. // IsCertExpired checks if the current TLS certificate is expired.
  500. func (t *TLSManager) IsCertExpired(keyRing keychain.SecretKeyRing) (bool,
  501. time.Time, error) {
  502. certBytes, keyBytes, err := cert.GetCertBytesFromPath(
  503. t.cfg.TLSCertPath, t.cfg.TLSKeyPath,
  504. )
  505. if err != nil {
  506. return false, time.Time{}, err
  507. }
  508. // If TLSEncryptKey is set, there are two states the
  509. // certificate can be in: ephemeral or permanent.
  510. // Retrieve the key depending on which state it is in.
  511. if t.ephemeralKey != nil {
  512. keyBytes = t.ephemeralKey
  513. } else if t.cfg.TLSEncryptKey {
  514. keyBytes, err = decryptTLSKeyBytes(keyRing, keyBytes)
  515. if err != nil {
  516. return false, time.Time{}, err
  517. }
  518. }
  519. _, parsedCert, err := cert.LoadCertFromBytes(
  520. certBytes, keyBytes,
  521. )
  522. if err != nil {
  523. return false, time.Time{}, err
  524. }
  525. // If the current time is passed the certificate's
  526. // expiry time, then it is considered expired
  527. if time.Now().After(parsedCert.NotAfter) {
  528. return true, parsedCert.NotAfter, nil
  529. }
  530. return false, parsedCert.NotAfter, nil
  531. }