Merge fort-nix/nix-bitcoin#586: Misc. improvements
addfa8ec6b
test: support `run`, `debug` commands in basic NixOS tests (Erik Arvstedt)ae733d887e
tests/clightning-replication: reuse `pkgs` instance (Erik Arvstedt)6cbd0d93ae
tests: rename `clightningReplication` -> `clightning-replication` (Erik Arvstedt)85310b533a
secrets: use type `lines` for `generateSecretsCmds` (Erik Arvstedt)bc2f66d4f1
bitcoind, liquid: increase start/stop timeouts (Erik Arvstedt)519ae31202
netns-isolation: improve formatting (Erik Arvstedt)a1023696e6
netns-isolation: reserve netns id for mempool (Erik Arvstedt)34fe8675bd
add option `nix-bitcoin.pkgOverlays` (Erik Arvstedt)a3bdecb10b
helper: add start-bash-session.sh (Erik Arvstedt)690a8f6256
nodeinfo: extract fn `mkInfoLong` (Erik Arvstedt)2af642f56a
improve comments (Erik Arvstedt)5634f08873
rtl: make `extraConfig` recursively mergeable (Erik Arvstedt)b76728a1ec
treewide: use bool literals for systemd (Erik Arvstedt) Pull request description: ACKs for top commit: jonasnick: ACKaddfa8ec6b
Tree-SHA512: 46f779f8477b566ffc6d0dfb024f2098757f509b2b3e0cbb509cf3308de7029e913f6e6c3d6d3d226cc72f8a5031fd5586b2efdf7c2d9d15f4bdd7ed08b27425
This commit is contained in:
commit
475af2d6cb
@ -55,7 +55,7 @@ The [nix-bitcoin test suite](../test/README.md) is also useful for exploring fea
|
|||||||
|
|
||||||
### Real-world example
|
### Real-world example
|
||||||
Check the [server repo](https://github.com/fort-nix/nixbitcoin.org) for https://nixbitcoin.org
|
Check the [server repo](https://github.com/fort-nix/nixbitcoin.org) for https://nixbitcoin.org
|
||||||
to see the configuration of a nix-bitcoin node that's used in production.
|
to see the configuration of a Flakes-based nix-bitcoin node that's used in production.
|
||||||
|
|
||||||
The commands in `shell.nix` allow you to locally run the node in a VM or container.
|
The commands in `shell.nix` allow you to locally run the node in a VM or container.
|
||||||
|
|
||||||
|
12
helper/start-bash-session.sh
Normal file
12
helper/start-bash-session.sh
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Start an interactive bash session in the current bash environment.
|
||||||
|
# This is helpful for debugging bash scripts like pkg update scripts,
|
||||||
|
# by adding `source <path-to>/start-bash-session.sh` at the location to
|
||||||
|
# be inspected.
|
||||||
|
|
||||||
|
|
||||||
|
# BASH_ENVIRONMENT contains definitions of read-only variables like 'BASHOPTS' that
|
||||||
|
# cause warnings on evaluation. Suppress these warnings while sourcing.
|
||||||
|
#
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
BASH_ENVIRONMENT=<(declare -p; declare -pf) \
|
||||||
|
bash --rcfile <(echo 'source $BASH_ENVIRONMENT 2>/dev/null')
|
@ -421,8 +421,8 @@ in {
|
|||||||
NotifyAccess = "all";
|
NotifyAccess = "all";
|
||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
Group = cfg.group;
|
Group = cfg.group;
|
||||||
TimeoutStartSec = "10min";
|
TimeoutStartSec = "30min";
|
||||||
TimeoutStopSec = "10min";
|
TimeoutStopSec = "30min";
|
||||||
ExecStart = "${cfg.package}/bin/bitcoind -datadir='${cfg.dataDir}'";
|
ExecStart = "${cfg.package}/bin/bitcoind -datadir='${cfg.dataDir}'";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
UMask = mkIf cfg.dataDirReadableByGroup "0027";
|
UMask = mkIf cfg.dataDirReadableByGroup "0027";
|
||||||
|
@ -193,7 +193,7 @@ in {
|
|||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
RestartSec = "10s";
|
RestartSec = "10s";
|
||||||
ReadWritePaths = [ cfg.nbxplorer.dataDir ];
|
ReadWritePaths = [ cfg.nbxplorer.dataDir ];
|
||||||
MemoryDenyWriteExecute = "false";
|
MemoryDenyWriteExecute = false;
|
||||||
} // nbLib.allowedIPAddresses cfg.nbxplorer.tor.enforce;
|
} // nbLib.allowedIPAddresses cfg.nbxplorer.tor.enforce;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ in {
|
|||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
RestartSec = "10s";
|
RestartSec = "10s";
|
||||||
ReadWritePaths = [ cfg.btcpayserver.dataDir ];
|
ReadWritePaths = [ cfg.btcpayserver.dataDir ];
|
||||||
MemoryDenyWriteExecute = "false";
|
MemoryDenyWriteExecute = false;
|
||||||
} // nbLib.allowedIPAddresses cfg.btcpayserver.tor.enforce;
|
} // nbLib.allowedIPAddresses cfg.btcpayserver.tor.enforce;
|
||||||
}; in self;
|
}; in self;
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@ let cfg = config.services.clightning.plugins.clboss; in
|
|||||||
default = 30000;
|
default = 30000;
|
||||||
description = mdDoc ''
|
description = mdDoc ''
|
||||||
Target amount (in satoshi) that CLBOSS will leave on-chain.
|
Target amount (in satoshi) that CLBOSS will leave on-chain.
|
||||||
clboss will only open new channels if this amount is smaller than
|
clboss will only open new channels if the funds in your clightning wallet are
|
||||||
the funds in your clightning wallet.
|
larger than this amount.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
min-channel = mkOption {
|
min-channel = mkOption {
|
||||||
|
@ -270,8 +270,8 @@ in {
|
|||||||
NotifyAccess = "all";
|
NotifyAccess = "all";
|
||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
Group = cfg.group;
|
Group = cfg.group;
|
||||||
TimeoutStartSec = "10min";
|
TimeoutStartSec = "2h";
|
||||||
TimeoutStopSec = "10min";
|
TimeoutStopSec = "2h";
|
||||||
ExecStart = "${nbPkgs.elementsd}/bin/elementsd -datadir='${cfg.dataDir}'";
|
ExecStart = "${nbPkgs.elementsd}/bin/elementsd -datadir='${cfg.dataDir}'";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
ReadWritePaths = [ cfg.dataDir ];
|
ReadWritePaths = [ cfg.dataDir ];
|
||||||
|
@ -215,9 +215,11 @@ in {
|
|||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in foldl (services: n:
|
in
|
||||||
|
foldl (services: n:
|
||||||
services // (makeNetnsServices n netns.${n})
|
services // (makeNetnsServices n netns.${n})
|
||||||
) {} (builtins.attrNames netns));
|
) {} (builtins.attrNames netns)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Service-specific config
|
# Service-specific config
|
||||||
@ -297,6 +299,7 @@ in {
|
|||||||
id = 31;
|
id = 31;
|
||||||
connections = [ "bitcoind" ];
|
connections = [ "bitcoind" ];
|
||||||
};
|
};
|
||||||
|
# id = 32 reserved for the upcoming mempool module
|
||||||
};
|
};
|
||||||
|
|
||||||
services.bitcoind = {
|
services.bitcoind = {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, options, pkgs, lib, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
@ -8,6 +8,18 @@ with lib;
|
|||||||
type = types.attrs;
|
type = types.attrs;
|
||||||
default = (import ../pkgs { inherit pkgs; }).modulesPkgs;
|
default = (import ../pkgs { inherit pkgs; }).modulesPkgs;
|
||||||
defaultText = "nix-bitcoin/pkgs.modulesPkgs";
|
defaultText = "nix-bitcoin/pkgs.modulesPkgs";
|
||||||
|
apply = base:
|
||||||
|
let
|
||||||
|
final = foldl (prev: overlay:
|
||||||
|
prev // (overlay prev final)
|
||||||
|
) base options.nix-bitcoin.pkgOverlays.definitions;
|
||||||
|
in
|
||||||
|
final;
|
||||||
|
};
|
||||||
|
|
||||||
|
pkgOverlays = mkOption {
|
||||||
|
internal = true;
|
||||||
|
type = with types; functionTo attrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
lib = mkOption {
|
lib = mkOption {
|
||||||
|
@ -73,9 +73,10 @@ let
|
|||||||
return
|
return
|
||||||
info["onion_address"] = f"{onion_address}:{port}"
|
info["onion_address"] = f"{onion_address}:{port}"
|
||||||
|
|
||||||
def add_service(service, make_info):
|
def add_service(service, make_info, systemd_service = None):
|
||||||
if not is_active(service):
|
systemd_service = systemd_service or service
|
||||||
infos[service] = "service is not running"
|
if not is_active(systemd_service):
|
||||||
|
infos[service] = f"'{systemd_service}.service' is not running"
|
||||||
else:
|
else:
|
||||||
info = OrderedDict()
|
info = OrderedDict()
|
||||||
exec(make_info, globals(), locals())
|
exec(make_info, globals(), locals())
|
||||||
@ -96,14 +97,19 @@ let
|
|||||||
) (builtins.attrNames cfg.services);
|
) (builtins.attrNames cfg.services);
|
||||||
|
|
||||||
nodeinfoLib = rec {
|
nodeinfoLib = rec {
|
||||||
mkInfo = extraCode: name: cfg: ''
|
mkInfo = extraCode: name: cfg:
|
||||||
|
mkInfoLong {
|
||||||
|
inherit extraCode name cfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
mkInfoLong = { extraCode ? "", name, cfg, systemdServiceName ? name }: ''
|
||||||
add_service("${name}", """
|
add_service("${name}", """
|
||||||
info["local_address"] = "${nbLib.addressWithPort cfg.address cfg.port}"
|
info["local_address"] = "${nbLib.addressWithPort cfg.address cfg.port}"
|
||||||
'' + mkIfOnionPort name (onionPort: ''
|
'' + mkIfOnionPort name (onionPort: ''
|
||||||
set_onion_address(info, "${name}", ${onionPort})
|
set_onion_address(info, "${name}", ${onionPort})
|
||||||
'') + extraCode + ''
|
'') + extraCode + ''
|
||||||
|
|
||||||
""")
|
""", "${systemdServiceName}")
|
||||||
'';
|
'';
|
||||||
|
|
||||||
mkIfOnionPort = name: fn:
|
mkIfOnionPort = name: fn:
|
||||||
|
@ -55,8 +55,8 @@ in {
|
|||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
StateDirectory = "onion-addresses";
|
StateDirectory = "onion-addresses";
|
||||||
StateDirectoryMode = "771";
|
StateDirectoryMode = "771";
|
||||||
PrivateNetwork = "true"; # This service needs no network access
|
PrivateNetwork = true; # This service needs no network access
|
||||||
PrivateUsers = "false";
|
PrivateUsers = false;
|
||||||
CapabilityBoundingSet = "CAP_CHOWN CAP_FSETID CAP_SETFCAP CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER CAP_IPC_OWNER";
|
CapabilityBoundingSet = "CAP_CHOWN CAP_FSETID CAP_SETFCAP CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER CAP_IPC_OWNER";
|
||||||
};
|
};
|
||||||
script = ''
|
script = ''
|
||||||
|
@ -5,7 +5,9 @@ let
|
|||||||
secretsDir = config.nix-bitcoin.secretsDir;
|
secretsDir = config.nix-bitcoin.secretsDir;
|
||||||
in {
|
in {
|
||||||
services.bitcoind = {
|
services.bitcoind = {
|
||||||
# Make the local bitcoin-cli work with the remote node
|
# Make the local bitcoin-cli work with the remote node.
|
||||||
|
# Without this, bitcoin-cli would try to use the .cookie file in the local
|
||||||
|
# bitcoind data dir for authorization, which doesn't exist.
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
rpcuser=${cfg.rpc.users.privileged.name}
|
rpcuser=${cfg.rpc.users.privileged.name}
|
||||||
'';
|
'';
|
||||||
|
@ -27,7 +27,7 @@ let
|
|||||||
description = mdDoc "Enable the clightning node interface.";
|
description = mdDoc "Enable the clightning node interface.";
|
||||||
};
|
};
|
||||||
extraConfig = mkOption {
|
extraConfig = mkOption {
|
||||||
type = types.attrs;
|
type = with types; attrsOf anything;
|
||||||
default = {};
|
default = {};
|
||||||
example = {
|
example = {
|
||||||
Settings.userPersona = "MERCHANT";
|
Settings.userPersona = "MERCHANT";
|
||||||
@ -52,7 +52,7 @@ let
|
|||||||
description = mdDoc "Enable swaps with lightning-loop.";
|
description = mdDoc "Enable swaps with lightning-loop.";
|
||||||
};
|
};
|
||||||
extraConfig = mkOption {
|
extraConfig = mkOption {
|
||||||
type = types.attrs;
|
type = with types; attrsOf anything;
|
||||||
default = {};
|
default = {};
|
||||||
example = {
|
example = {
|
||||||
Settings.userPersona = "MERCHANT";
|
Settings.userPersona = "MERCHANT";
|
||||||
|
@ -28,7 +28,7 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
generateSecretsCmds = mkOption {
|
generateSecretsCmds = mkOption {
|
||||||
type = types.attrsOf types.str;
|
type = types.attrsOf types.lines;
|
||||||
default = {};
|
default = {};
|
||||||
description = mdDoc ''
|
description = mdDoc ''
|
||||||
Bash expressions for generating secrets.
|
Bash expressions for generating secrets.
|
||||||
|
36
pkgs/lib.nix
36
pkgs/lib.nix
@ -7,28 +7,28 @@ with lib;
|
|||||||
let self = {
|
let self = {
|
||||||
# These settings roughly follow systemd's "strict" security profile
|
# These settings roughly follow systemd's "strict" security profile
|
||||||
defaultHardening = {
|
defaultHardening = {
|
||||||
PrivateTmp = "true";
|
PrivateTmp = true;
|
||||||
ProtectSystem = "strict";
|
ProtectSystem = "strict";
|
||||||
ProtectHome = "true";
|
ProtectHome = true;
|
||||||
NoNewPrivileges = "true";
|
NoNewPrivileges = true;
|
||||||
PrivateDevices = "true";
|
PrivateDevices = true;
|
||||||
MemoryDenyWriteExecute = "true";
|
MemoryDenyWriteExecute = true;
|
||||||
ProtectKernelTunables = "true";
|
ProtectKernelTunables = true;
|
||||||
ProtectKernelModules = "true";
|
ProtectKernelModules = true;
|
||||||
ProtectKernelLogs = "true";
|
ProtectKernelLogs = true;
|
||||||
ProtectClock = "true";
|
ProtectClock = true;
|
||||||
ProtectProc = "invisible";
|
ProtectProc = "invisible";
|
||||||
ProcSubset = "pid";
|
ProcSubset = "pid";
|
||||||
ProtectControlGroups = "true";
|
ProtectControlGroups = true;
|
||||||
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
|
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
|
||||||
RestrictNamespaces = "true";
|
RestrictNamespaces = true;
|
||||||
LockPersonality = "true";
|
LockPersonality = true;
|
||||||
IPAddressDeny = "any";
|
IPAddressDeny = "any";
|
||||||
PrivateUsers = "true";
|
PrivateUsers = true;
|
||||||
RestrictSUIDSGID = "true";
|
RestrictSUIDSGID = true;
|
||||||
RemoveIPC = "true";
|
RemoveIPC = true;
|
||||||
RestrictRealtime = "true";
|
RestrictRealtime = true;
|
||||||
ProtectHostname = "true";
|
ProtectHostname = true;
|
||||||
CapabilityBoundingSet = "";
|
CapabilityBoundingSet = "";
|
||||||
# @system-service whitelist and docker seccomp blacklist (except for "clone"
|
# @system-service whitelist and docker seccomp blacklist (except for "clone"
|
||||||
# which is a core requirement for systemd services)
|
# which is a core requirement for systemd services)
|
||||||
@ -42,7 +42,7 @@ let self = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
# nodejs applications require memory write execute for JIT compilation
|
# nodejs applications require memory write execute for JIT compilation
|
||||||
nodejs = { MemoryDenyWriteExecute = "false"; };
|
nodejs = { MemoryDenyWriteExecute = false; };
|
||||||
|
|
||||||
# Allow takes precedence over Deny.
|
# Allow takes precedence over Deny.
|
||||||
allowLocalIPAddresses = {
|
allowLocalIPAddresses = {
|
||||||
|
@ -39,7 +39,6 @@ rec {
|
|||||||
## Specific versions of packages that already exist in nixpkgs
|
## Specific versions of packages that already exist in nixpkgs
|
||||||
|
|
||||||
# cryptography 3.3.2, required by joinmarketdaemon
|
# cryptography 3.3.2, required by joinmarketdaemon
|
||||||
# Used in the private python package set for joinmarket (../joinmarket/default.nix)
|
|
||||||
cryptography = callPackage ./specific-versions/cryptography {
|
cryptography = callPackage ./specific-versions/cryptography {
|
||||||
openssl = super.pkgs.openssl_1_1;
|
openssl = super.pkgs.openssl_1_1;
|
||||||
cryptography_vectors = callPackage ./specific-versions/cryptography/vectors.nix {};
|
cryptography_vectors = callPackage ./specific-versions/cryptography/vectors.nix {};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# You can run this test via `run-tests.sh -s clightningReplication`
|
# You can run this test via `run-tests.sh -s clightning-replication`
|
||||||
|
|
||||||
makeTestVM: pkgs:
|
makeTestVM: pkgs:
|
||||||
with pkgs.lib;
|
with pkgs.lib;
|
||||||
@ -14,6 +14,8 @@ let
|
|||||||
clientBaseConfig = {
|
clientBaseConfig = {
|
||||||
imports = [ ../modules/modules.nix ];
|
imports = [ ../modules/modules.nix ];
|
||||||
|
|
||||||
|
nixpkgs.pkgs = pkgs;
|
||||||
|
|
||||||
nix-bitcoin.generateSecrets = true;
|
nix-bitcoin.generateSecrets = true;
|
||||||
|
|
||||||
services.clightning = {
|
services.clightning = {
|
||||||
@ -54,7 +56,9 @@ makeTestVM {
|
|||||||
services.clightning.replication.encrypt = true;
|
services.clightning.replication.encrypt = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
server = { ... }: {
|
server = {
|
||||||
|
nixpkgs.pkgs = pkgs;
|
||||||
|
|
||||||
environment.etc."ssh-host-key" = {
|
environment.etc."ssh-host-key" = {
|
||||||
source = keys.server;
|
source = keys.server;
|
||||||
mode = "400";
|
mode = "400";
|
||||||
|
@ -27,4 +27,9 @@ let
|
|||||||
inherit (test) meta passthru;
|
inherit (test) meta passthru;
|
||||||
} // test;
|
} // test;
|
||||||
in
|
in
|
||||||
runTest
|
runTest // {
|
||||||
|
# A VM runner for interactive use
|
||||||
|
run = pkgs.writers.writeBashBin "run-vm" ''
|
||||||
|
. ${./run-vm.sh} ${runTest.driver} "$@"
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
@ -52,11 +52,6 @@ let
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
# A VM runner for interactive use
|
|
||||||
run = pkgs.writers.writeBashBin "run-vm" ''
|
|
||||||
. ${./run-vm.sh} ${test.driver} "$@"
|
|
||||||
'';
|
|
||||||
|
|
||||||
mkContainer = legacyInstallDirs:
|
mkContainer = legacyInstallDirs:
|
||||||
extra-container.lib.buildContainers {
|
extra-container.lib.buildContainers {
|
||||||
inherit system legacyInstallDirs;
|
inherit system legacyInstallDirs;
|
||||||
@ -139,7 +134,6 @@ let
|
|||||||
in
|
in
|
||||||
test // {
|
test // {
|
||||||
inherit
|
inherit
|
||||||
run
|
|
||||||
vm
|
vm
|
||||||
container
|
container
|
||||||
# For NixOS with `system.stateVersion` <22.05
|
# For NixOS with `system.stateVersion` <22.05
|
||||||
|
@ -272,7 +272,7 @@ buildable=(
|
|||||||
full
|
full
|
||||||
regtest
|
regtest
|
||||||
hardened
|
hardened
|
||||||
clightningReplication
|
clightning-replication
|
||||||
lndPruned
|
lndPruned
|
||||||
)
|
)
|
||||||
buildable() { buildTests buildable "$@"; }
|
buildable() { buildTests buildable "$@"; }
|
||||||
|
@ -404,7 +404,7 @@ in {
|
|||||||
) scenarios;
|
) scenarios;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
clightningReplication = import ./clightning-replication.nix makeTestVM pkgs;
|
clightning-replication = import ./clightning-replication.nix makeTestVM pkgs;
|
||||||
} // mainTests;
|
} // mainTests;
|
||||||
|
|
||||||
tests = makeTests scenarios;
|
tests = makeTests scenarios;
|
||||||
|
Loading…
Reference in New Issue
Block a user