Skip to content

Commit

Permalink
Merge #245: Fix tests without secure-node
Browse files Browse the repository at this point in the history
bfed10b run-tests: add command 'all' (Erik Arvstedt)
0a6b9be run-tests: simplify setting default scenario (Erik Arvstedt)
1a32292 test: speed up clightning startup when offline (Erik Arvstedt)
7d1797c clightning: add option 'extraConfig' (Erik Arvstedt)
e0117d5 spark-wallet: fix always-on onion-chef setting (Erik Arvstedt)
480d0d3 liquid: fix bitcoin rpc settings (Erik Arvstedt)
c07e767 test: add python test requirements (Erik Arvstedt)
9aa19c3 extract operator module (Erik Arvstedt)
2dd1a74 modules: group imports (Erik Arvstedt)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK bfed10b

Tree-SHA512: caa6a38f9c9ad583fee8b4a705f5a94f037354eb49c2502c7b0aae620981df5c6630b1c862ead7fff2d9a47d0d15d3ce819567f63570e4d68ed02db7fe5f19a6
  • Loading branch information
jonasnick committed Oct 16, 2020
2 parents 7906715 + bfed10b commit 6a16f60
Show file tree
Hide file tree
Showing 14 changed files with 126 additions and 68 deletions.
1 change: 1 addition & 0 deletions modules/bitcoind.nix
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ in {
};
users.groups.${cfg.group} = {};
users.groups.bitcoinrpc = {};
nix-bitcoin.operator.groups = [ cfg.group ];

nix-bitcoin.secrets.bitcoin-rpcpassword-privileged.user = "bitcoin";
nix-bitcoin.secrets.bitcoin-rpcpassword-public = {
Expand Down
7 changes: 7 additions & 0 deletions modules/clightning.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ let
${optionalString (cfg.bitcoin-rpcconnect != null) "bitcoin-rpcconnect=${cfg.bitcoin-rpcconnect}"}
bitcoin-rpcuser=${config.services.bitcoind.rpc.users.public.name}
rpc-file-mode=0660
${cfg.extraConfig}
'';
in {
options.services.clightning = {
Expand Down Expand Up @@ -70,6 +71,11 @@ in {
default = "/var/lib/clightning";
description = "The data directory for clightning.";
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Additional lines appended to the config file.";
};
user = mkOption {
type = types.str;
default = "clightning";
Expand Down Expand Up @@ -99,6 +105,7 @@ in {
extraGroups = [ "bitcoinrpc" ];
};
users.groups.${cfg.group} = {};
nix-bitcoin.operator.groups = [ cfg.group ];

systemd.tmpfiles.rules = [
"d '${cfg.dataDir}' 0770 ${cfg.user} ${cfg.group} - -"
Expand Down
1 change: 1 addition & 0 deletions modules/hardware-wallets.nix
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ in {
usbutils
];
users.groups."${cfg.group}" = {};
nix-bitcoin.operator.groups = [ cfg.group ];
})
(mkIf cfg.ledger {

Expand Down
4 changes: 4 additions & 0 deletions modules/joinmarket.nix
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ in {
home = cfg.dataDir;
};
users.groups.${cfg.group} = {};
nix-bitcoin.operator = {
groups = [ cfg.group ];
sudoUsers = [ cfg.group ];
};

systemd.tmpfiles.rules = [
"d '${cfg.dataDir}' 0770 ${cfg.user} ${cfg.group} - -"
Expand Down
16 changes: 6 additions & 10 deletions modules/liquid.nix
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ let
${lib.concatMapStrings (rpcallowip: "rpcallowip=${rpcallowip}\n") cfg.rpcallowip}
${optionalString (cfg.rpcuser != null) "rpcuser=${cfg.rpcuser}"}
${optionalString (cfg.rpcpassword != null) "rpcpassword=${cfg.rpcpassword}"}
${optionalString (cfg.mainchainrpchost != null) "mainchainrpchost=${cfg.mainchainrpchost}"}
mainchainrpchost=${builtins.elemAt config.services.bitcoind.rpcbind 0}
mainchainrpcport=${toString config.services.bitcoind.rpc.port}
mainchainrpcuser=${config.services.bitcoind.rpc.users.public.name}
# Extra config options (from liquidd nixos service)
${cfg.extraConfig}
Expand Down Expand Up @@ -146,15 +148,6 @@ in {
default = null;
description = "Password for JSON-RPC connections";
};
mainchainrpchost = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
The address which the daemon will try to connect to the trusted
mainchain daemon to validate peg-ins.
'';
};

testnet = mkOption {
type = types.bool;
default = false;
Expand Down Expand Up @@ -263,12 +256,15 @@ in {
else nix-bitcoin-services.allowAnyIP
);
};

users.users.${cfg.user} = {
group = cfg.group;
extraGroups = [ "bitcoinrpc" ];
description = "Liquid sidechain user";
};
users.groups.${cfg.group} = {};
nix-bitcoin.operator.groups = [ cfg.group ];

nix-bitcoin.secrets.liquid-rpcpassword.user = "liquid";
};
}
6 changes: 6 additions & 0 deletions modules/lnd.nix
Original file line number Diff line number Diff line change
Expand Up @@ -259,13 +259,19 @@ in {
else nix-bitcoin-services.allowAnyIP
) // nix-bitcoin-services.allowAnyProtocol; # For ZMQ
};

users.users.lnd = {
description = "LND User";
group = "lnd";
extraGroups = [ "bitcoinrpc" ];
home = cfg.dataDir; # lnd creates .lnd dir in HOME
};
users.groups.lnd = {};
nix-bitcoin.operator = {
groups = [ "lnd" ];
sudoUsers = [ "lnd" ];
};

nix-bitcoin.secrets = {
lnd-wallet-password.user = "lnd";
lnd-key.user = "lnd";
Expand Down
24 changes: 15 additions & 9 deletions modules/modules.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,30 @@

{
imports = [
# Core modules
./secrets/secrets.nix
./operator.nix

# Main features
./bitcoind.nix
./clightning.nix
./lightning-charge.nix
./nanopos.nix
./liquid.nix
./spark-wallet.nix
./electrs.nix
./onion-chef.nix
./recurring-donations.nix
./hardware-wallets.nix
./lnd.nix
./lightning-loop.nix
./secrets/secrets.nix
./netns-isolation.nix
./security.nix
./backups.nix
./btcpayserver.nix
./electrs.nix
./liquid.nix
./joinmarket.nix
./hardware-wallets.nix
./recurring-donations.nix

# Support features
./security.nix
./netns-isolation.nix
./backups.nix
./onion-chef.nix
];

disabledModules = [ "services/networking/bitcoind.nix" ];
Expand Down
2 changes: 1 addition & 1 deletion modules/netns-isolation.nix
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ in {
User that is allowed to execute commands in the service network namespaces.
The user's group is also authorized.
'';
default = config.nix-bitcoin.operator.name;
};

netns = mkOption {
Expand Down Expand Up @@ -294,7 +295,6 @@ in {
rpcallowip = [
"127.0.0.1"
] ++ map (n: "${netns.${n}.address}") netns.liquidd.availableNetns;
mainchainrpchost = netns.bitcoind.address;
cliExec = mkCliExec "liquidd";
};

Expand Down
2 changes: 1 addition & 1 deletion modules/nodeinfo.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
with lib;

let
operatorName = config.nix-bitcoin.operatorName;
operatorName = config.nix-bitcoin.operator.name;
script = pkgs.writeScriptBin "nodeinfo" ''
set -eo pipefail
Expand Down
47 changes: 47 additions & 0 deletions modules/operator.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Define an operator user for convenient interactive access to nix-bitcoin
# features and services.
#
# When using nix-bitcoin as part of a larger system config, set
# `nix-bitcoin.operator.name` to your main user name.

{ config, lib, pkgs, options, ... }:

with lib;
let
cfg = config.nix-bitcoin.operator;
in {
options.nix-bitcoin.operator = {
enable = mkEnableOption "operator user";
name = mkOption {
type = types.str;
default = "operator";
description = "User name.";
};
groups = mkOption {
type = with types; listOf str;
default = [];
description = "Extra groups.";
};
sudoUsers = mkOption {
type = with types; listOf str;
default = [];
description = "Users as which the operator is allowed to run commands.";
};
};

config = mkIf cfg.enable {
users.users.${cfg.name} = {
isNormalUser = true;
extraGroups = [
"systemd-journal"
"proc" # Enable full /proc access and systemd-status
] ++ cfg.groups;
};

security.sudo.extraConfig = mkIf (cfg.sudoUsers != []) (let
users = builtins.concatStringsSep "," cfg.sudoUsers;
in ''
${cfg.name} ALL=(${users}) NOPASSWD: ALL
'');
};
}
43 changes: 7 additions & 36 deletions modules/presets/secure-node.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ with lib;
let
cfg = config.services;

operatorName = config.nix-bitcoin.operatorName;
operatorName = config.nix-bitcoin.operator.name;

mkHiddenService = map: {
map = [ map ];
Expand All @@ -29,11 +29,6 @@ in {
default = 9735;
description = "Port on which to listen for tor client connections.";
};
nix-bitcoin.operatorName = mkOption {
type = types.str;
default = "operator";
description = "Less-privileged user's name.";
};
};

config = {
Expand Down Expand Up @@ -107,10 +102,6 @@ in {
services.liquidd = {
rpcuser = "liquidrpc";
prune = 1000;
extraConfig = ''
mainchainrpcuser=${config.services.bitcoind.rpc.users.public.name}
mainchainrpcport=8332
'';
validatepegin = true;
listen = true;
proxy = cfg.tor.client.socksListenAddress;
Expand Down Expand Up @@ -159,35 +150,15 @@ in {
qrencode
];

# Create operator user which can access the node's services
services.onion-chef = {
enable = true;
access.${operatorName} = [ "bitcoind" "clightning" "nginx" "liquidd" "spark-wallet" "electrs" "btcpayserver" "sshd" ];
};

nix-bitcoin.operator.enable = true;
users.users.${operatorName} = {
isNormalUser = true;
extraGroups = [
"systemd-journal"
"proc" # Enable full /proc access and systemd-status
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 ])
++ (optionals cfg.joinmarket.enable [ cfg.joinmarket.group ]);
openssh.authorizedKeys.keys = config.users.users.root.openssh.authorizedKeys.keys;
};
nix-bitcoin.netns-isolation.allowedUser = operatorName;
# Give operator access to onion hostnames
services.onion-chef.enable = true;
services.onion-chef.access.${operatorName} = [ "bitcoind" "clightning" "nginx" "liquidd" "spark-wallet" "electrs" "btcpayserver" "sshd" ];

security.sudo.configFile =
(optionalString cfg.lnd.enable ''
${operatorName} ALL=(lnd) NOPASSWD: ALL
'') +
(optionalString cfg.joinmarket.enable ''
${operatorName} ALL=(${cfg.joinmarket.user}) NOPASSWD: ALL
'');

# 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) {
Expand Down
2 changes: 1 addition & 1 deletion modules/spark-wallet.nix
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ in {
User = "spark-wallet";
Restart = "on-failure";
RestartSec = "10s";
ReadWritePaths = "/var/lib/onion-chef";
ReadWritePaths = mkIf cfg.onion-service "/var/lib/onion-chef";
} // (if cfg.enforceTor
then nix-bitcoin-services.allowTor
else nix-bitcoin-services.allowAnyIP)
Expand Down
31 changes: 21 additions & 10 deletions test/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
# Example:
# ./run-tests.sh -s electrs
#
# Run test and link results to avoid garbage collection
# ./run-tests.sh [--scenario <scenario>] --out-link-prefix /tmp/nix-bitcoin-test build
# Run test(s) and link results to avoid garbage collection
# ./run-tests.sh [--scenario <scenario>] --out-link-prefix /tmp/nix-bitcoin-test
#
# Pass extra args to nix-build
# ./run-tests.sh build --builders 'ssh://mybuildhost - - 15'
Expand Down Expand Up @@ -168,23 +168,34 @@ vmTestNixExpr() {
EOF
}

# A basic subset of tests to keep the total runtime within
# manageable bounds (<3 min on desktop systems).
# These are also run on the CI server.
basic() {
scenario=default buildTest "$@"
scenario=netns buildTest "$@"
scenario=full evalTest "$@"
}

all() {
scenario=default buildTest "$@"
scenario=netns buildTest "$@"
scenario=full buildTest "$@"
}

build() {
if [[ $scenario ]]; then
buildTest "$@"
else
scenario=default buildTest "$@"
scenario=netns buildTest "$@"
scenario=full evalTest "$@"
basic "$@"
fi
}

# Set default scenario for all actions other than 'build'
if [[ $1 && $1 != build ]]; then
: ${scenario:=default}
fi

command="${1:-build}"
shift || true
if [[ $command != build ]]; then
: ${scenario:=default}
fi
if [[ $command == eval ]]; then
command=evalTest
fi
Expand Down
8 changes: 8 additions & 0 deletions test/tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ let testEnv = rec {
./lib/test-lib.nix
../modules/modules.nix
../modules/secrets/generate-secrets.nix
{
# Features required by the Python test suite
nix-bitcoin.secretsDir = "/secrets";
nix-bitcoin.operator.enable = true;
environment.systemPackages = with pkgs; [ jq ];
}
];

config = {
Expand All @@ -23,6 +29,8 @@ let testEnv = rec {
};

tests.clightning = cfg.clightning.enable;
# When WAN is disabled, DNS bootstrapping slows down service startup by ~15 s.
services.clightning.extraConfig = mkIf config.test.noConnections "disable-dns";

tests.spark-wallet = cfg.spark-wallet.enable;

Expand Down

0 comments on commit 6a16f60

Please sign in to comment.