From 28792f79dc1ff0a581dee8dd30f4d49950b2cef7 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Tue, 7 Apr 2020 22:47:32 +0200 Subject: [PATCH 01/16] rename nix-bitcoin.nix -> presets/secure-node.nix --- examples/configuration.nix | 4 ++-- modules/default.nix | 2 +- modules/{nix-bitcoin.nix => presets/secure-node.nix} | 4 ++-- test/test.nix | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename modules/{nix-bitcoin.nix => presets/secure-node.nix} (98%) diff --git a/examples/configuration.nix b/examples/configuration.nix index 85bd665..a72ebdc 100644 --- a/examples/configuration.nix +++ b/examples/configuration.nix @@ -4,7 +4,7 @@ { config, pkgs, lib, ... }: { imports = [ - + # FIXME: The hardened kernel profile improves security but # decreases performance by ~50%. @@ -26,7 +26,7 @@ ### BITCOIND # Bitcoind is enabled by default if nix-bitcoin is enabled # - # You can override default settings from nix-bitcoin.nix as follows + # You can override default settings from secure-node.nix as follows # services.bitcoind.prune = lib.mkForce 100000; # # You can add options that are not defined in modules/bitcoind.nix as follows diff --git a/modules/default.nix b/modules/default.nix index 6664741..2ca1ebe 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -7,7 +7,7 @@ lightning-charge = ./lightning-charge.nix; liquid = ./liquid.nix; nanopos = ./nanopos.nix; - nix-bitcoin = ./nix-bitcoin.nix; + presets.secure-node = ./presets/secure-node.nix; nix-bitcoin-webindex = ./nix-bitcoin-webindex.nix; spark-wallet = ./spark-wallet.nix; recurring-donations = ./recurring-donations.nix; diff --git a/modules/nix-bitcoin.nix b/modules/presets/secure-node.nix similarity index 98% rename from modules/nix-bitcoin.nix rename to modules/presets/secure-node.nix index 1b71e42..aae32f5 100644 --- a/modules/nix-bitcoin.nix +++ b/modules/presets/secure-node.nix @@ -4,7 +4,7 @@ with lib; let cfg = config.services.nix-bitcoin; - operatorCopySSH = pkgs.writeText "operator-copy-ssh.sh" '' + operatorCopySSH = pkgs.writeText "operator-copy-ssh.sh" '' mkdir -p ${config.users.users.operator.home}/.ssh if [ -e "${config.users.users.root.home}/.vbox-nixops-client-key" ]; then cp ${config.users.users.root.home}/.vbox-nixops-client-key ${config.users.users.operator.home}/.ssh/authorized_keys @@ -15,7 +15,7 @@ let chown -R operator ${config.users.users.operator.home}/.ssh ''; in { - imports = [ ./modules.nix ]; + imports = [ ../modules.nix ]; options.services.nix-bitcoin = { enable = mkOption { diff --git a/test/test.nix b/test/test.nix index 918ce38..d8557c5 100644 --- a/test/test.nix +++ b/test/test.nix @@ -10,7 +10,7 @@ import ./make-test.nix rec { machine = { pkgs, lib, ... }: with lib; { imports = [ - ../modules/nix-bitcoin.nix + ../modules/presets/secure-node.nix ../modules/secrets/generate-secrets.nix # using the hardened profile increases total test duration by ~50%, so disable it for now # hardened From 0f8b2e91fd02676e380d8a6298766c873fbb6618 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Tue, 7 Apr 2020 22:47:33 +0200 Subject: [PATCH 02/16] add nix-bitcoin.nix for backwards compatibility --- modules/nix-bitcoin.nix | 3 +++ modules/presets/secure-node.nix | 13 ++----------- 2 files changed, 5 insertions(+), 11 deletions(-) create mode 100644 modules/nix-bitcoin.nix diff --git a/modules/nix-bitcoin.nix b/modules/nix-bitcoin.nix new file mode 100644 index 0000000..3063ad9 --- /dev/null +++ b/modules/nix-bitcoin.nix @@ -0,0 +1,3 @@ +# This file exists only for backwards compatibility + +import ./presets/secure-node.nix diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index aae32f5..818bf7f 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -17,17 +17,8 @@ let in { imports = [ ../modules.nix ]; - options.services.nix-bitcoin = { - enable = mkOption { - type = types.bool; - default = false; - description = '' - If enabled, the nix-bitcoin service will be installed. - ''; - }; - }; - - config = mkIf cfg.enable { + config = { + # For backwards compatibility only nix-bitcoin.secretsDir = mkDefault "/secrets"; networking.firewall.enable = true; From 1a63f0ca6acaebdfc6448424e155aaf5d96d61fe Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Tue, 7 Apr 2020 22:47:34 +0200 Subject: [PATCH 03/16] remove option 'services.nix-bitcoin.enable' Users can enable the node config just by importing secure-node.nix --- examples/configuration.nix | 5 +---- modules/nix-bitcoin.nix | 8 +++++++- modules/presets/secure-node.nix | 1 - test/test.nix | 1 - 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/examples/configuration.nix b/examples/configuration.nix index a72ebdc..ee24f4f 100644 --- a/examples/configuration.nix +++ b/examples/configuration.nix @@ -18,10 +18,7 @@ #./hardware-configuration.nix ]; # FIXME: Enable modules by uncommenting their respective line. Disable - # modules by commenting out their respective line. Enable this module to - # use the nix-bitcoin node configuration. Only disable this if you know what - # you are doing. - services.nix-bitcoin.enable = true; + # modules by commenting out their respective line. ### BITCOIND # Bitcoind is enabled by default if nix-bitcoin is enabled diff --git a/modules/nix-bitcoin.nix b/modules/nix-bitcoin.nix index 3063ad9..64879d0 100644 --- a/modules/nix-bitcoin.nix +++ b/modules/nix-bitcoin.nix @@ -1,3 +1,9 @@ # This file exists only for backwards compatibility -import ./presets/secure-node.nix +{ lib, ... }: +{ + imports = [ + ./presets/secure-node.nix + (lib.mkRemovedOptionModule [ "services" "nix-bitcoin" "enable" ] "Please directly import ./presets/secure-node.nix") + ] +} diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index 818bf7f..d454ddf 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -3,7 +3,6 @@ with lib; let - cfg = config.services.nix-bitcoin; operatorCopySSH = pkgs.writeText "operator-copy-ssh.sh" '' mkdir -p ${config.users.users.operator.home}/.ssh if [ -e "${config.users.users.root.home}/.vbox-nixops-client-key" ]; then diff --git a/test/test.nix b/test/test.nix index d8557c5..d609d3d 100644 --- a/test/test.nix +++ b/test/test.nix @@ -16,7 +16,6 @@ import ./make-test.nix rec { # hardened ]; - services.nix-bitcoin.enable = true; services.bitcoind.extraConfig = mkForce "connect=0"; services.clightning.enable = true; From 85e52a06cb610f0b755472137b6b1ad4da0a2f73 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Tue, 7 Apr 2020 22:47:35 +0200 Subject: [PATCH 04/16] improve grouping of suboptions --- modules/presets/secure-node.nix | 95 ++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index d454ddf..ff1d9be 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -23,35 +23,36 @@ in { networking.firewall.enable = true; # Tor - services.tor.enable = true; - services.tor.client.enable = true; - # LND uses ControlPort to create onion services - services.tor.controlPort = if config.services.lnd.enable then 9051 else null; + services.tor = { + enable = true; + client.enable = true; + # LND uses ControlPort to create onion services + controlPort = if config.services.lnd.enable then 9051 else null; - # Tor SSH service - services.tor.hiddenServices.sshd = { - map = [{ - port = 22; - }]; - version = 3; + hiddenServices.sshd = { + map = [ { port = 22; } ]; + version = 3; + }; }; # bitcoind - services.bitcoind.enable = true; - services.bitcoind.listen = true; - services.bitcoind.sysperms = if config.services.electrs.enable then true else null; - services.bitcoind.disablewallet = if config.services.electrs.enable then true else null; - services.bitcoind.proxy = config.services.tor.client.socksListenAddress; - services.bitcoind.enforceTor = true; - services.bitcoind.port = 8333; - services.bitcoind.zmqpubrawblock = "tcp://127.0.0.1:28332"; - services.bitcoind.zmqpubrawtx = "tcp://127.0.0.1:28333"; - services.bitcoind.assumevalid = "00000000000000000000e5abc3a74fe27dc0ead9c70ea1deb456f11c15fd7bc6"; - services.bitcoind.addnodes = [ "ecoc5q34tmbq54wl.onion" ]; - services.bitcoind.discover = false; - services.bitcoind.addresstype = "bech32"; - services.bitcoind.prune = 0; - services.bitcoind.dbCache = 1000; + services.bitcoind = { + enable = true; + listen = true; + sysperms = if config.services.electrs.enable then true else null; + disablewallet = if config.services.electrs.enable then true else null; + proxy = config.services.tor.client.socksListenAddress; + enforceTor = true; + port = 8333; + zmqpubrawblock = "tcp://127.0.0.1:28332"; + zmqpubrawtx = "tcp://127.0.0.1:28333"; + assumevalid = "00000000000000000000e5abc3a74fe27dc0ead9c70ea1deb456f11c15fd7bc6"; + addnodes = [ "ecoc5q34tmbq54wl.onion" ]; + discover = false; + addresstype = "bech32"; + prune = 0; + dbCache = 1000; + }; services.tor.hiddenServices.bitcoind = { map = [{ port = config.services.bitcoind.port; @@ -60,11 +61,13 @@ in { }; # clightning - services.clightning.bitcoin-rpcuser = config.services.bitcoind.rpcuser; - services.clightning.proxy = config.services.tor.client.socksListenAddress; - services.clightning.enforceTor = true; - services.clightning.always-use-proxy = true; - services.clightning.bind-addr = "127.0.0.1:9735"; + services.clightning = { + bitcoin-rpcuser = config.services.bitcoind.rpcuser; + proxy = config.services.tor.client.socksListenAddress; + enforceTor = true; + always-use-proxy = true; + bind-addr = "127.0.0.1:9735"; + }; services.tor.hiddenServices.clightning = { map = [{ port = 9735; toPort = 9735; @@ -112,17 +115,19 @@ in { services.nix-bitcoin-webindex.enforceTor = true; - services.liquidd.rpcuser = "liquidrpc"; - services.liquidd.prune = 1000; - services.liquidd.extraConfig = " + services.liquidd = { + rpcuser = "liquidrpc"; + prune = 1000; + extraConfig = " mainchainrpcuser=${config.services.bitcoind.rpcuser} mainchainrpcport=8332 "; - services.liquidd.validatepegin = true; - services.liquidd.listen = true; - services.liquidd.proxy = config.services.tor.client.socksListenAddress; - services.liquidd.enforceTor = true; - services.liquidd.port = 7042; + validatepegin = true; + listen = true; + proxy = config.services.tor.client.socksListenAddress; + enforceTor = true; + port = 7042; + }; services.tor.hiddenServices.liquidd = { map = [{ port = config.services.liquidd.port; toPort = config.services.liquidd.port; @@ -131,17 +136,21 @@ in { }; services.spark-wallet.onion-service = true; - services.electrs.port = 50001; - services.electrs.enforceTor = true; - services.electrs.onionport = 50002; - services.electrs.TLSProxy.enable = true; - services.electrs.TLSProxy.port = 50003; + + services.electrs = { + port = 50001; + enforceTor = true; + onionport = 50002; + TLSProxy.enable = true; + TLSProxy.port = 50003; + }; services.tor.hiddenServices.electrs = { map = [{ port = config.services.electrs.onionport; toPort = config.services.electrs.TLSProxy.port; }]; version = 3; }; + environment.systemPackages = with pkgs; with nix-bitcoin; let s = config.services; in From 89d3d58850cae43279828cf9b717e24d1abaff84 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Tue, 7 Apr 2020 22:47:36 +0200 Subject: [PATCH 05/16] use mkIf --- modules/presets/secure-node.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index ff1d9be..13aa57d 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -27,7 +27,7 @@ in { enable = true; client.enable = true; # LND uses ControlPort to create onion services - controlPort = if config.services.lnd.enable then 9051 else null; + controlPort = mkIf config.services.lnd.enable 9051; hiddenServices.sshd = { map = [ { port = 22; } ]; From e16ddc9c771b3757eb11c07be7bfa92d7a2a9e23 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Tue, 7 Apr 2020 22:47:37 +0200 Subject: [PATCH 06/16] extract 'mkHiddenService' toPort equals port by default. --- modules/presets/secure-node.nix | 39 ++++++++++----------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index 13aa57d..3817313 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -3,6 +3,11 @@ with lib; let + mkHiddenService = map: { + map = [ map ]; + version = 3; + }; + operatorCopySSH = pkgs.writeText "operator-copy-ssh.sh" '' mkdir -p ${config.users.users.operator.home}/.ssh if [ -e "${config.users.users.root.home}/.vbox-nixops-client-key" ]; then @@ -29,10 +34,7 @@ in { # LND uses ControlPort to create onion services controlPort = mkIf config.services.lnd.enable 9051; - hiddenServices.sshd = { - map = [ { port = 22; } ]; - version = 3; - }; + hiddenServices.sshd = mkHiddenService { port = 22; }; }; # bitcoind @@ -53,12 +55,7 @@ in { prune = 0; dbCache = 1000; }; - services.tor.hiddenServices.bitcoind = { - map = [{ - port = config.services.bitcoind.port; - }]; - version = 3; - }; + services.tor.hiddenServices.bitcoind = mkHiddenService { port = config.services.bitcoind.port; }; # clightning services.clightning = { @@ -68,12 +65,7 @@ in { always-use-proxy = true; bind-addr = "127.0.0.1:9735"; }; - services.tor.hiddenServices.clightning = { - map = [{ - port = 9735; toPort = 9735; - }]; - version = 3; - }; + services.tor.hiddenServices.clightning = mkHiddenService { port = 9735; }; # lnd services.lnd.enforceTor = true; @@ -128,12 +120,7 @@ in { enforceTor = true; port = 7042; }; - services.tor.hiddenServices.liquidd = { - map = [{ - port = config.services.liquidd.port; toPort = config.services.liquidd.port; - }]; - version = 3; - }; + services.tor.hiddenServices.liquidd = mkHiddenService { port = config.services.liquidd.port; }; services.spark-wallet.onion-service = true; @@ -144,11 +131,9 @@ in { TLSProxy.enable = true; TLSProxy.port = 50003; }; - services.tor.hiddenServices.electrs = { - map = [{ - port = config.services.electrs.onionport; toPort = config.services.electrs.TLSProxy.port; - }]; - version = 3; + services.tor.hiddenServices.electrs = mkHiddenService { + port = config.services.electrs.onionport; + toPort = config.services.electrs.TLSProxy.port; }; environment.systemPackages = with pkgs; with nix-bitcoin; let From ec6d33fbb6e992413b00e0361ea87d25d1e4de06 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Tue, 7 Apr 2020 22:47:38 +0200 Subject: [PATCH 07/16] rearrange code sections Move services to the top, operator account setup to the bottom. --- modules/presets/secure-node.nix | 121 ++++++++++++++++---------------- 1 file changed, 62 insertions(+), 59 deletions(-) diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index 3817313..8d4f33a 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -70,6 +70,68 @@ in { # lnd services.lnd.enforceTor = true; + # liquidd + services.liquidd = { + rpcuser = "liquidrpc"; + prune = 1000; + extraConfig = " + mainchainrpcuser=${config.services.bitcoind.rpcuser} + mainchainrpcport=8332 + "; + validatepegin = true; + listen = true; + proxy = config.services.tor.client.socksListenAddress; + enforceTor = true; + port = 7042; + }; + services.tor.hiddenServices.liquidd = mkHiddenService { port = config.services.liquidd.port; }; + + # electrs + services.electrs = { + port = 50001; + enforceTor = true; + onionport = 50002; + TLSProxy.enable = true; + TLSProxy.port = 50003; + }; + services.tor.hiddenServices.electrs = mkHiddenService { + port = config.services.electrs.onionport; + toPort = config.services.electrs.TLSProxy.port; + }; + + services.spark-wallet.onion-service = true; + + services.nix-bitcoin-webindex.enforceTor = true; + + + environment.systemPackages = with pkgs; with nix-bitcoin; let + s = config.services; + in + [ + tor + bitcoind + (hiPrio s.bitcoind.cli) + nodeinfo + jq + qrencode + ] + ++ optionals s.clightning.enable [clightning (hiPrio s.clightning.cli)] + ++ optionals s.lnd.enable [lnd (hiPrio s.lnd.cli)] + ++ optionals s.lightning-charge.enable [lightning-charge] + ++ optionals s.nanopos.enable [nanopos] + ++ optionals s.nix-bitcoin-webindex.enable [nginx] + ++ optionals s.liquidd.enable [elementsd (hiPrio s.liquidd.cli) (hiPrio s.liquidd.swap-cli)] + ++ optionals s.spark-wallet.enable [spark-wallet] + ++ optionals s.electrs.enable [electrs] + ++ optionals (s.hardware-wallets.ledger || s.hardware-wallets.trezor) [ + hwi + # To allow debugging issues with lsusb + usbutils + ] + ++ optionals s.hardware-wallets.trezor [ + python3.pkgs.trezor + ]; + # Create user operator which can use bitcoin-cli and lightning-cli users.users.operator = { isNormalUser = true; @@ -104,64 +166,5 @@ in { type = "oneshot"; }; }; - - services.nix-bitcoin-webindex.enforceTor = true; - - services.liquidd = { - rpcuser = "liquidrpc"; - prune = 1000; - extraConfig = " - mainchainrpcuser=${config.services.bitcoind.rpcuser} - mainchainrpcport=8332 - "; - validatepegin = true; - listen = true; - proxy = config.services.tor.client.socksListenAddress; - enforceTor = true; - port = 7042; - }; - services.tor.hiddenServices.liquidd = mkHiddenService { port = config.services.liquidd.port; }; - - services.spark-wallet.onion-service = true; - - services.electrs = { - port = 50001; - enforceTor = true; - onionport = 50002; - TLSProxy.enable = true; - TLSProxy.port = 50003; - }; - services.tor.hiddenServices.electrs = mkHiddenService { - port = config.services.electrs.onionport; - toPort = config.services.electrs.TLSProxy.port; - }; - - environment.systemPackages = with pkgs; with nix-bitcoin; let - s = config.services; - in - [ - tor - bitcoind - (hiPrio s.bitcoind.cli) - nodeinfo - jq - qrencode - ] - ++ optionals s.clightning.enable [clightning (hiPrio s.clightning.cli)] - ++ optionals s.lnd.enable [lnd (hiPrio s.lnd.cli)] - ++ optionals s.lightning-charge.enable [lightning-charge] - ++ optionals s.nanopos.enable [nanopos] - ++ optionals s.nix-bitcoin-webindex.enable [nginx] - ++ optionals s.liquidd.enable [elementsd (hiPrio s.liquidd.cli) (hiPrio s.liquidd.swap-cli)] - ++ optionals s.spark-wallet.enable [spark-wallet] - ++ optionals s.electrs.enable [electrs] - ++ optionals (s.hardware-wallets.ledger || s.hardware-wallets.trezor) [ - hwi - # To allow debugging issues with lsusb - usbutils - ] - ++ optionals s.hardware-wallets.trezor [ - python3.pkgs.trezor - ]; }; } From 74fbfa3a5da2c503d8e14267366500b65fb9e878 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Tue, 7 Apr 2020 22:47:39 +0200 Subject: [PATCH 08/16] use lib.optionals --- modules/presets/secure-node.nix | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index 8d4f33a..56b44e6 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -136,11 +136,11 @@ in { users.users.operator = { isNormalUser = true; extraGroups = [ config.services.bitcoind.group ] - ++ (if config.services.clightning.enable then [ "clightning" ] else [ ]) - ++ (if config.services.lnd.enable then [ "lnd" ] else [ ]) - ++ (if config.services.liquidd.enable then [ config.services.liquidd.group ] else [ ]) - ++ (if (config.services.hardware-wallets.ledger || config.services.hardware-wallets.trezor) - then [ config.services.hardware-wallets.group ] else [ ]); + ++ (optionals config.services.clightning.enable [ "clightning" ]) + ++ (optionals config.services.lnd.enable [ "lnd" ]) + ++ (optionals config.services.liquidd.enable [ config.services.liquidd.group ]) + ++ (optionals (config.services.hardware-wallets.ledger || config.services.hardware-wallets.trezor) + [ config.services.hardware-wallets.group ]); }; # Give operator access to onion hostnames services.onion-chef.enable = true; From 681dbaf328eabb5590e8893048acd3391896c115 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Tue, 7 Apr 2020 22:47:40 +0200 Subject: [PATCH 09/16] move electrs.onionport option Only used in secure-node.nix --- modules/electrs.nix | 5 ----- modules/presets/secure-node.nix | 9 ++++++++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/electrs.nix b/modules/electrs.nix index 4ca1cda..1d538f3 100644 --- a/modules/electrs.nix +++ b/modules/electrs.nix @@ -44,11 +44,6 @@ in { default = 50001; description = "RPC port."; }; - onionport = mkOption { - type = types.ints.u16; - default = 50002; - description = "Port on which to listen for tor client connections."; - }; extraArgs = mkOption { type = types.separatedString " "; default = ""; diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index 56b44e6..ff69bf1 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -21,6 +21,14 @@ let in { imports = [ ../modules.nix ]; + options = { + services.electrs.onionport = mkOption { + type = types.ints.u16; + default = 50002; + description = "Port on which to listen for tor client connections."; + }; + }; + config = { # For backwards compatibility only nix-bitcoin.secretsDir = mkDefault "/secrets"; @@ -90,7 +98,6 @@ in { services.electrs = { port = 50001; enforceTor = true; - onionport = 50002; TLSProxy.enable = true; TLSProxy.port = 50003; }; From 36c84d83601b3e9687b0a0727a00ab18f9b843a6 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Tue, 7 Apr 2020 22:47:41 +0200 Subject: [PATCH 10/16] add option clightning.onionport Analogous to electrs.onionport --- modules/presets/secure-node.nix | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index ff69bf1..77b8ad2 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -22,6 +22,12 @@ in { imports = [ ../modules.nix ]; options = { + services.clightning.onionport = mkOption { + type = types.ints.u16; + default = 9735; + description = "Port on which to listen for tor client connections."; + }; + services.electrs.onionport = mkOption { type = types.ints.u16; default = 50002; @@ -71,9 +77,9 @@ in { proxy = config.services.tor.client.socksListenAddress; enforceTor = true; always-use-proxy = true; - bind-addr = "127.0.0.1:9735"; + bind-addr = "127.0.0.1:${toString config.services.clightning.onionport}"; }; - services.tor.hiddenServices.clightning = mkHiddenService { port = 9735; }; + services.tor.hiddenServices.clightning = mkHiddenService { port = config.services.clightning.onionport; }; # lnd services.lnd.enforceTor = true; From ab617946a9d041d28d10a9f5416ba9c3ea7906f4 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Tue, 7 Apr 2020 22:47:42 +0200 Subject: [PATCH 11/16] extract variable 'cfg' --- modules/presets/secure-node.nix | 72 ++++++++++++++++----------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index 77b8ad2..29464a1 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -3,6 +3,8 @@ with lib; let + cfg = config.services; + mkHiddenService = map: { map = [ map ]; version = 3; @@ -46,7 +48,7 @@ in { enable = true; client.enable = true; # LND uses ControlPort to create onion services - controlPort = mkIf config.services.lnd.enable 9051; + controlPort = mkIf cfg.lnd.enable 9051; hiddenServices.sshd = mkHiddenService { port = 22; }; }; @@ -55,9 +57,9 @@ in { services.bitcoind = { enable = true; listen = true; - sysperms = if config.services.electrs.enable then true else null; - disablewallet = if config.services.electrs.enable then true else null; - proxy = config.services.tor.client.socksListenAddress; + sysperms = if cfg.electrs.enable then true else null; + disablewallet = if cfg.electrs.enable then true else null; + proxy = cfg.tor.client.socksListenAddress; enforceTor = true; port = 8333; zmqpubrawblock = "tcp://127.0.0.1:28332"; @@ -69,17 +71,17 @@ in { prune = 0; dbCache = 1000; }; - services.tor.hiddenServices.bitcoind = mkHiddenService { port = config.services.bitcoind.port; }; + services.tor.hiddenServices.bitcoind = mkHiddenService { port = cfg.bitcoind.port; }; # clightning services.clightning = { - bitcoin-rpcuser = config.services.bitcoind.rpcuser; - proxy = config.services.tor.client.socksListenAddress; + bitcoin-rpcuser = cfg.bitcoind.rpcuser; + proxy = cfg.tor.client.socksListenAddress; enforceTor = true; always-use-proxy = true; - bind-addr = "127.0.0.1:${toString config.services.clightning.onionport}"; + bind-addr = "127.0.0.1:${toString cfg.clightning.onionport}"; }; - services.tor.hiddenServices.clightning = mkHiddenService { port = config.services.clightning.onionport; }; + services.tor.hiddenServices.clightning = mkHiddenService { port = cfg.clightning.onionport; }; # lnd services.lnd.enforceTor = true; @@ -89,16 +91,16 @@ in { rpcuser = "liquidrpc"; prune = 1000; extraConfig = " - mainchainrpcuser=${config.services.bitcoind.rpcuser} + mainchainrpcuser=${cfg.bitcoind.rpcuser} mainchainrpcport=8332 "; validatepegin = true; listen = true; - proxy = config.services.tor.client.socksListenAddress; + proxy = cfg.tor.client.socksListenAddress; enforceTor = true; port = 7042; }; - services.tor.hiddenServices.liquidd = mkHiddenService { port = config.services.liquidd.port; }; + services.tor.hiddenServices.liquidd = mkHiddenService { port = cfg.liquidd.port; }; # electrs services.electrs = { @@ -108,8 +110,8 @@ in { TLSProxy.port = 50003; }; services.tor.hiddenServices.electrs = mkHiddenService { - port = config.services.electrs.onionport; - toPort = config.services.electrs.TLSProxy.port; + port = cfg.electrs.onionport; + toPort = cfg.electrs.TLSProxy.port; }; services.spark-wallet.onion-service = true; @@ -117,43 +119,41 @@ in { services.nix-bitcoin-webindex.enforceTor = true; - environment.systemPackages = with pkgs; with nix-bitcoin; let - s = config.services; - in + environment.systemPackages = with pkgs; with nix-bitcoin; [ tor bitcoind - (hiPrio s.bitcoind.cli) + (hiPrio cfg.bitcoind.cli) nodeinfo jq qrencode ] - ++ optionals s.clightning.enable [clightning (hiPrio s.clightning.cli)] - ++ optionals s.lnd.enable [lnd (hiPrio s.lnd.cli)] - ++ optionals s.lightning-charge.enable [lightning-charge] - ++ optionals s.nanopos.enable [nanopos] - ++ optionals s.nix-bitcoin-webindex.enable [nginx] - ++ optionals s.liquidd.enable [elementsd (hiPrio s.liquidd.cli) (hiPrio s.liquidd.swap-cli)] - ++ optionals s.spark-wallet.enable [spark-wallet] - ++ optionals s.electrs.enable [electrs] - ++ optionals (s.hardware-wallets.ledger || s.hardware-wallets.trezor) [ + ++ optionals cfg.clightning.enable [clightning (hiPrio cfg.clightning.cli)] + ++ optionals cfg.lnd.enable [lnd (hiPrio cfg.lnd.cli)] + ++ optionals cfg.lightning-charge.enable [lightning-charge] + ++ optionals cfg.nanopos.enable [nanopos] + ++ optionals cfg.nix-bitcoin-webindex.enable [nginx] + ++ optionals cfg.liquidd.enable [elementsd (hiPrio cfg.liquidd.cli) (hiPrio cfg.liquidd.swap-cli)] + ++ optionals cfg.spark-wallet.enable [spark-wallet] + ++ optionals cfg.electrs.enable [electrs] + ++ optionals (cfg.hardware-wallets.ledger || cfg.hardware-wallets.trezor) [ hwi # To allow debugging issues with lsusb usbutils ] - ++ optionals s.hardware-wallets.trezor [ + ++ optionals cfg.hardware-wallets.trezor [ python3.pkgs.trezor ]; # Create user operator which can use bitcoin-cli and lightning-cli users.users.operator = { isNormalUser = true; - extraGroups = [ config.services.bitcoind.group ] - ++ (optionals config.services.clightning.enable [ "clightning" ]) - ++ (optionals config.services.lnd.enable [ "lnd" ]) - ++ (optionals config.services.liquidd.enable [ config.services.liquidd.group ]) - ++ (optionals (config.services.hardware-wallets.ledger || config.services.hardware-wallets.trezor) - [ config.services.hardware-wallets.group ]); + extraGroups = [ cfg.bitcoind.group ] + ++ (optionals cfg.clightning.enable [ "clightning" ]) + ++ (optionals cfg.lnd.enable [ "lnd" ]) + ++ (optionals cfg.liquidd.enable [ cfg.liquidd.group ]) + ++ (optionals (cfg.hardware-wallets.ledger || cfg.hardware-wallets.trezor) + [ cfg.hardware-wallets.group ]); }; # Give operator access to onion hostnames services.onion-chef.enable = true; @@ -162,10 +162,10 @@ in { # Unfortunately c-lightning doesn't allow setting the permissions of the rpc socket # https://github.com/ElementsProject/lightning/issues/1366 security.sudo.configFile = - (optionalString config.services.clightning.enable '' + (optionalString cfg.clightning.enable '' operator ALL=(clightning) NOPASSWD: ALL '') + - (optionalString config.services.lnd.enable '' + (optionalString cfg.lnd.enable '' operator ALL=(lnd) NOPASSWD: ALL ''); From 63c6fe3213c7bed068ac49596b6fcd79cf410c11 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Tue, 7 Apr 2020 22:47:43 +0200 Subject: [PATCH 12/16] fixup! use '' for multi-line string --- modules/presets/secure-node.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index 29464a1..0688a67 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -90,10 +90,10 @@ in { services.liquidd = { rpcuser = "liquidrpc"; prune = 1000; - extraConfig = " - mainchainrpcuser=${cfg.bitcoind.rpcuser} - mainchainrpcport=8332 - "; + extraConfig = '' + mainchainrpcuser=${cfg.bitcoind.rpcuser} + mainchainrpcport=8332 + ''; validatepegin = true; listen = true; proxy = cfg.tor.client.socksListenAddress; From 6c22e13b7f431eddab26e50e05f67039ee8f6b7a Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Tue, 7 Apr 2020 22:47:44 +0200 Subject: [PATCH 13/16] copy-root-authorized-keys: use inline script definition --- modules/presets/secure-node.nix | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index 0688a67..a9ad064 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -9,17 +9,6 @@ let map = [ map ]; version = 3; }; - - operatorCopySSH = pkgs.writeText "operator-copy-ssh.sh" '' - mkdir -p ${config.users.users.operator.home}/.ssh - if [ -e "${config.users.users.root.home}/.vbox-nixops-client-key" ]; then - cp ${config.users.users.root.home}/.vbox-nixops-client-key ${config.users.users.operator.home}/.ssh/authorized_keys - fi - if [ -e "/etc/ssh/authorized_keys.d/root" ]; then - cat /etc/ssh/authorized_keys.d/root >> ${config.users.users.operator.home}/.ssh/authorized_keys - fi - chown -R operator ${config.users.users.operator.home}/.ssh - ''; in { imports = [ ../modules.nix ]; @@ -170,14 +159,24 @@ in { ''); # Give root ssh access to the operator account + # FIXME: move this to deployment/nixops.nix after merging PR 'nix-bitcoin-as-module' systemd.services.copy-root-authorized-keys = { description = "Copy root authorized keys"; wantedBy = [ "multi-user.target" ]; - serviceConfig = { - ExecStart = "${pkgs.bash}/bin/bash \"${operatorCopySSH}\""; - user = "root"; - type = "oneshot"; - }; + serviceConfig.type = "oneshot"; + script = let + operator = config.users.users.operator.home; + root = config.users.users.root.home; + in '' + mkdir -p ${operator}/.ssh + if [[ -e "${root}/.vbox-nixops-client-key" ]]; then + cp ${root}/.vbox-nixops-client-key ${operator}/.ssh/authorized_keys + fi + if [[ -e "/etc/ssh/authorized_keys.d/root" ]]; then + cat /etc/ssh/authorized_keys.d/root >> ${operator}/.ssh/authorized_keys + fi + chown -R operator ${operator}/.ssh + ''; }; }; } From 37b2faf63cf2a7ae1ad95fff2b2db6e314c83c4c Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Tue, 7 Apr 2020 22:47:45 +0200 Subject: [PATCH 14/16] move systemPackages definitions to services These are generally useful and shouldn't be limited to secure-node.nix. Also, only add the hardware-wallets group when hardware wallets are enabled. --- modules/bitcoind.nix | 2 +- modules/clightning.nix | 1 + modules/electrs.nix | 2 ++ modules/hardware-wallets.nix | 12 +++++++++--- modules/lightning-charge.nix | 1 + modules/liquid.nix | 6 +++++- modules/lnd.nix | 2 +- modules/nanopos.nix | 2 +- modules/presets/secure-node.nix | 23 ++--------------------- modules/spark-wallet.nix | 1 + 10 files changed, 24 insertions(+), 28 deletions(-) diff --git a/modules/bitcoind.nix b/modules/bitcoind.nix index edc1db8..409d264 100644 --- a/modules/bitcoind.nix +++ b/modules/bitcoind.nix @@ -256,7 +256,7 @@ in { }; config = mkIf cfg.enable { - environment.systemPackages = [ cfg.package ]; + environment.systemPackages = [ cfg.package (hiPrio cfg.cli) ]; systemd.services.bitcoind = { description = "Bitcoin daemon"; requires = [ "nix-bitcoin-secrets.target" ]; diff --git a/modules/clightning.nix b/modules/clightning.nix index 9a561c3..607f9e7 100644 --- a/modules/clightning.nix +++ b/modules/clightning.nix @@ -71,6 +71,7 @@ in { }; config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.nix-bitcoin.clightning (hiPrio cfg.cli) ]; users.users.clightning = { description = "clightning User"; group = "clightning"; diff --git a/modules/electrs.nix b/modules/electrs.nix index 1d538f3..3d30187 100644 --- a/modules/electrs.nix +++ b/modules/electrs.nix @@ -61,6 +61,8 @@ in { }; config = mkIf cfg.enable (mkMerge [{ + environment.systemPackages = [ pkgs.nix-bitcoin.electrs ]; + systemd.services.electrs = { description = "Electrs Electrum Server"; wantedBy = [ "multi-user.target" ]; diff --git a/modules/hardware-wallets.nix b/modules/hardware-wallets.nix index 33d3a3c..8337e5c 100644 --- a/modules/hardware-wallets.nix +++ b/modules/hardware-wallets.nix @@ -32,11 +32,16 @@ in { }; config = mkMerge [ - { - # Create group + (mkIf (cfg.ledger || cfg.trezor) { + environment.systemPackages = with pkgs; [ + nix-bitcoin.hwi + # Provides lsusb for debugging + usbutils + ]; users.groups."${cfg.group}" = {}; - } + }) (mkIf cfg.ledger { + # Ledger Nano S according to https://github.com/LedgerHQ/udev-rules/blob/master/add_udev_rules.sh # Don't use rules from nixpkgs because we want to use our own group. services.udev.packages = lib.singleton (pkgs.writeTextFile { @@ -48,6 +53,7 @@ in { }); }) (mkIf cfg.trezor { + environment.systemPackages = [ pkgs.python3.pkgs.trezor ]; # Don't use rules from nixpkgs because we want to use our own group. services.udev.packages = lib.singleton (pkgs.writeTextFile { name = "trezord-udev-rules"; diff --git a/modules/lightning-charge.nix b/modules/lightning-charge.nix index 0d0061a..9566402 100644 --- a/modules/lightning-charge.nix +++ b/modules/lightning-charge.nix @@ -24,6 +24,7 @@ in { }; config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.nix-bitcoin.lightning-charge ]; systemd.services.lightning-charge = { description = "Run lightning-charge"; wantedBy = [ "multi-user.target" ]; diff --git a/modules/liquid.nix b/modules/liquid.nix index 3dce19a..5716230 100644 --- a/modules/liquid.nix +++ b/modules/liquid.nix @@ -195,7 +195,11 @@ in { }; config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.nix-bitcoin.elementsd ]; + environment.systemPackages = [ + pkgs.nix-bitcoin.elementsd + (hiPrio cfg.cli) + (hiPrio cfg.swap-cli) + ]; systemd.services.liquidd = { description = "Elements daemon providing access to the Liquid sidechain"; requires = [ "bitcoind.service" ]; diff --git a/modules/lnd.nix b/modules/lnd.nix index 7cead2e..878a4ec 100644 --- a/modules/lnd.nix +++ b/modules/lnd.nix @@ -77,7 +77,7 @@ in { }; config = mkIf cfg.enable { - environment.systemPackages = [ cfg.package ]; + environment.systemPackages = [ cfg.package (hiPrio cfg.cli) ]; systemd.services.lnd = { description = "Run LND"; path = [ pkgs.nix-bitcoin.bitcoind ]; diff --git a/modules/nanopos.nix b/modules/nanopos.nix index b34cf6d..2fa5894 100644 --- a/modules/nanopos.nix +++ b/modules/nanopos.nix @@ -52,6 +52,7 @@ in { }; config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.nix-bitcoin.nanopos ]; systemd.services.nanopos = { description = "Run nanopos"; wantedBy = [ "multi-user.target" ]; @@ -60,7 +61,6 @@ in { serviceConfig = { EnvironmentFile = "${config.nix-bitcoin.secretsDir}/nanopos-env"; ExecStart = "${pkgs.nix-bitcoin.nanopos}/bin/nanopos -y ${cfg.itemsFile} -p ${toString cfg.port} --show-bolt11"; - User = "nanopos"; Restart = "on-failure"; RestartSec = "10s"; diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index a9ad064..aff5114 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -108,30 +108,11 @@ in { services.nix-bitcoin-webindex.enforceTor = true; - environment.systemPackages = with pkgs; with nix-bitcoin; - [ + environment.systemPackages = with pkgs; [ tor - bitcoind - (hiPrio cfg.bitcoind.cli) - nodeinfo jq qrencode - ] - ++ optionals cfg.clightning.enable [clightning (hiPrio cfg.clightning.cli)] - ++ optionals cfg.lnd.enable [lnd (hiPrio cfg.lnd.cli)] - ++ optionals cfg.lightning-charge.enable [lightning-charge] - ++ optionals cfg.nanopos.enable [nanopos] - ++ optionals cfg.nix-bitcoin-webindex.enable [nginx] - ++ optionals cfg.liquidd.enable [elementsd (hiPrio cfg.liquidd.cli) (hiPrio cfg.liquidd.swap-cli)] - ++ optionals cfg.spark-wallet.enable [spark-wallet] - ++ optionals cfg.electrs.enable [electrs] - ++ optionals (cfg.hardware-wallets.ledger || cfg.hardware-wallets.trezor) [ - hwi - # To allow debugging issues with lsusb - usbutils - ] - ++ optionals cfg.hardware-wallets.trezor [ - python3.pkgs.trezor + nix-bitcoin.nodeinfo ]; # Create user operator which can use bitcoin-cli and lightning-cli diff --git a/modules/spark-wallet.nix b/modules/spark-wallet.nix index c1565ea..13a5cca 100644 --- a/modules/spark-wallet.nix +++ b/modules/spark-wallet.nix @@ -47,6 +47,7 @@ in { }; config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.nix-bitcoin.spark-wallet ]; services.tor.enable = cfg.onion-service; # requires client functionality for Bitcoin rate lookup services.tor.client.enable = true; From 145961c2de1265425dbd3200e1fa4b6e9e75eb8c Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Wed, 8 Apr 2020 21:51:31 +0200 Subject: [PATCH 15/16] fix operator authorized keys setup This fixes these flaws in `copy-root-authorized-keys`: - When `.vbox-nixops-client-key` is missing, operator's authorized_keys file is always appended to, growing the file indefinitely. - Service is always added and not restricted to nixops-vbox deployments. --- modules/presets/secure-node.nix | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index aff5114..9b2ef95 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -115,7 +115,7 @@ in { nix-bitcoin.nodeinfo ]; - # Create user operator which can use bitcoin-cli and lightning-cli + # Create user 'operator' which can access the node's services users.users.operator = { isNormalUser = true; extraGroups = [ cfg.bitcoind.group ] @@ -124,6 +124,7 @@ in { ++ (optionals cfg.liquidd.enable [ cfg.liquidd.group ]) ++ (optionals (cfg.hardware-wallets.ledger || cfg.hardware-wallets.trezor) [ cfg.hardware-wallets.group ]); + openssh.authorizedKeys.keys = config.users.users.root.openssh.authorizedKeys.keys; }; # Give operator access to onion hostnames services.onion-chef.enable = true; @@ -139,25 +140,12 @@ in { operator ALL=(lnd) NOPASSWD: ALL ''); - # Give root ssh access to the operator account - # FIXME: move this to deployment/nixops.nix after merging PR 'nix-bitcoin-as-module' - systemd.services.copy-root-authorized-keys = { - description = "Copy root authorized keys"; - wantedBy = [ "multi-user.target" ]; - serviceConfig.type = "oneshot"; - script = let - operator = config.users.users.operator.home; - root = config.users.users.root.home; - in '' - mkdir -p ${operator}/.ssh - if [[ -e "${root}/.vbox-nixops-client-key" ]]; then - cp ${root}/.vbox-nixops-client-key ${operator}/.ssh/authorized_keys - fi - if [[ -e "/etc/ssh/authorized_keys.d/root" ]]; then - cat /etc/ssh/authorized_keys.d/root >> ${operator}/.ssh/authorized_keys - fi - chown -R operator ${operator}/.ssh - ''; - }; + # Enable nixops ssh for operator (`nixops ssh operator@mynode`) on nixops-vbox deployments + systemd.services.get-vbox-nixops-client-key = + mkIf (builtins.elem ".vbox-nixops-client-key" config.services.openssh.authorizedKeysFiles) { + postStart = '' + cp "${config.users.users.root.home}/.vbox-nixops-client-key" "${config.users.users.operator.home}" + ''; + }; }; } From bceaa361cab2a3008bba93abd918de4594b27b12 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Wed, 8 Apr 2020 23:30:10 +0200 Subject: [PATCH 16/16] operator: allow reading systemd journal --- modules/presets/secure-node.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix index 9b2ef95..0d2b666 100644 --- a/modules/presets/secure-node.nix +++ b/modules/presets/secure-node.nix @@ -118,7 +118,10 @@ in { # Create user 'operator' which can access the node's services users.users.operator = { isNormalUser = true; - extraGroups = [ cfg.bitcoind.group ] + extraGroups = [ + "systemd-journal" + cfg.bitcoind.group + ] ++ (optionals cfg.clightning.enable [ "clightning" ]) ++ (optionals cfg.lnd.enable [ "lnd" ]) ++ (optionals cfg.liquidd.enable [ cfg.liquidd.group ])