From edfbe700e7c06fb771bba9e646a2f823f82d9554 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Thu, 7 Jul 2022 16:08:27 +0200 Subject: [PATCH] lnd: add certificate options `extraIPs` and `extraDomains` This is useful for non-local access to the lnd REST server. --- modules/lnd.nix | 24 +++++++++++++++++++++++- pkgs/lib.nix | 6 ++++++ test/tests.nix | 17 ++++++++++++++--- test/tests.py | 14 +++++++++++--- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/modules/lnd.nix b/modules/lnd.nix index e5a807c..8e57a1f 100644 --- a/modules/lnd.nix +++ b/modules/lnd.nix @@ -70,6 +70,26 @@ let Extra macaroon definitions. ''; }; + certificate = { + extraIPs = mkOption { + type = with types; listOf str; + default = []; + example = [ "60.100.0.1" ]; + description = '' + Extra `subjectAltName` IPs added to the certificate. + This works the same as lnd option `tlsextraip`. + ''; + }; + extraDomains = mkOption { + type = with types; listOf str; + default = []; + example = [ "example.com" ]; + description = '' + Extra `subjectAltName` domain names added to the certificate. + This works the same as lnd option `tlsextradomain`. + ''; + }; + }; extraConfig = mkOption { type = types.lines; default = ""; @@ -195,6 +215,8 @@ in { "d '${cfg.dataDir}' 0770 ${cfg.user} ${cfg.group} - -" ]; + services.lnd.certificate.extraIPs = mkIf (cfg.rpcAddress != "localhost") [ "${cfg.rpcAddress}" ]; + systemd.services.lnd = { wantedBy = [ "multi-user.target" ]; requires = [ "bitcoind.service" ]; @@ -282,7 +304,7 @@ in { # - Enables deployment of a mesh of server plus client nodes with predefined certs nix-bitcoin.generateSecretsCmds.lnd = '' makePasswordSecret lnd-wallet-password - makeCert lnd '${optionalString (cfg.rpcAddress != "localhost") "IP:${cfg.rpcAddress}"}' + makeCert lnd '${nbLib.mkCertExtraAltNames cfg.certificate}' ''; }; } diff --git a/pkgs/lib.nix b/pkgs/lib.nix index ff4d44f..07a105d 100644 --- a/pkgs/lib.nix +++ b/pkgs/lib.nix @@ -109,4 +109,10 @@ let self = { optionalAttr = cond: name: if cond then name else null; + mkCertExtraAltNames = cert: + builtins.concatStringsSep "," ( + (map (domain: "DNS:${domain}") cert.extraDomains) ++ + (map (ip: "IP:${ip}") cert.extraIPs) + ); + }; in self diff --git a/test/tests.nix b/test/tests.nix index 77e367a..b10d016 100644 --- a/test/tests.nix +++ b/test/tests.nix @@ -35,6 +35,13 @@ let # Share the same pkgs instance among tests nixpkgs.pkgs = mkDefault globalPkgs; + environment.systemPackages = mkMerge (with pkgs; [ + # Needed to test macaroon creation + (mkIfTest "btcpayserver" [ openssl xxd ]) + # Needed to test certificate creation + (mkIfTest "lnd" [ openssl ]) + ]); + tests.bitcoind = cfg.bitcoind.enable; services.bitcoind = { enable = true; @@ -81,7 +88,13 @@ let tests.spark-wallet = cfg.spark-wallet.enable; tests.lnd = cfg.lnd.enable; - services.lnd.port = 9736; + services.lnd = { + port = 9736; + certificate = { + extraIPs = [ "10.0.0.1" "20.0.0.1" ]; + extraDomains = [ "example.com" ]; + }; + }; tests.lndconnect-onion-lnd = cfg.lnd.lndconnectOnion.enable; tests.lndconnect-onion-clightning = cfg.clightning-rest.lndconnectOnion.enable; @@ -103,8 +116,6 @@ let lightningBackend = mkDefault "lnd"; lbtc = mkDefault true; }; - # Needed to test macaroon creation - environment.systemPackages = mkIfTest "btcpayserver" (with pkgs; [ openssl xxd ]); test.data.btcpayserver-lbtc = config.services.btcpayserver.lbtc; tests.joinmarket = cfg.joinmarket.enable; diff --git a/test/tests.py b/test/tests.py index 3b20aa1..35ce34b 100644 --- a/test/tests.py +++ b/test/tests.py @@ -7,9 +7,11 @@ def succeed(*cmds): return machine.succeed(*cmds) def assert_matches(cmd, regexp): - out = succeed(cmd) - if not re.search(regexp, out): - raise Exception(f"Pattern '{regexp}' not found in '{out}'") + assert_str_matches(succeed(cmd), regexp) + +def assert_str_matches(str, regexp): + if not re.search(regexp, str): + raise Exception(f"Pattern '{regexp}' not found in '{str}'") def assert_full_match(cmd, regexp): out = succeed(cmd) @@ -152,6 +154,12 @@ def _(): assert_matches("runuser -u operator -- lncli getinfo | jq", '"version"') assert_no_failure("lnd") + # Test certificate generation + cert_alt_names = succeed("