Merge #152: Rename nix-bitcoin.nix to presets/secure-node.nix

bceaa361ca operator: allow reading systemd journal (Erik Arvstedt)
145961c2de fix operator authorized keys setup (Erik Arvstedt)
37b2faf63c move systemPackages definitions to services (Erik Arvstedt)
6c22e13b7f copy-root-authorized-keys: use inline script definition (Erik Arvstedt)
63c6fe3213 fixup! use '' for multi-line string (Erik Arvstedt)
ab617946a9 extract variable 'cfg' (Erik Arvstedt)
36c84d8360 add option clightning.onionport (Erik Arvstedt)
681dbaf328 move electrs.onionport option (Erik Arvstedt)
74fbfa3a5d use lib.optionals (Erik Arvstedt)
ec6d33fbb6 rearrange code sections (Erik Arvstedt)
e16ddc9c77 extract 'mkHiddenService' (Erik Arvstedt)
89d3d58850 use mkIf (Erik Arvstedt)
85e52a06cb improve grouping of suboptions (Erik Arvstedt)
1a63f0ca6a remove option 'services.nix-bitcoin.enable' (Erik Arvstedt)
0f8b2e91fd add nix-bitcoin.nix for backwards compatibility (Erik Arvstedt)
28792f79dc rename nix-bitcoin.nix -> presets/secure-node.nix (Erik Arvstedt)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK bceaa361ca

Tree-SHA512: d9c691d862c73f47399c97a50d9fa70ca934f82e8d9664bedacd5cc013fea040ec0431981aba78ade7f607d30809a5bab68effd627904e2cfa990e9d2612bf11
This commit is contained in:
Jonas Nick 2020-04-12 14:48:51 +00:00
commit 1131c795dc
No known key found for this signature in database
GPG Key ID: 4861DBF262123605
14 changed files with 188 additions and 202 deletions

View File

@ -4,7 +4,7 @@
{ config, pkgs, lib, ... }: { { config, pkgs, lib, ... }: {
imports = [ imports = [
<nix-bitcoin/modules/nix-bitcoin.nix> <nix-bitcoin/modules/presets/secure-node.nix>
# FIXME: The hardened kernel profile improves security but # FIXME: The hardened kernel profile improves security but
# decreases performance by ~50%. # decreases performance by ~50%.
@ -18,15 +18,12 @@
#./hardware-configuration.nix #./hardware-configuration.nix
]; ];
# FIXME: Enable modules by uncommenting their respective line. Disable # FIXME: Enable modules by uncommenting their respective line. Disable
# modules by commenting out their respective line. Enable this module to # modules by commenting out their respective line.
# use the nix-bitcoin node configuration. Only disable this if you know what
# you are doing.
services.nix-bitcoin.enable = true;
### BITCOIND ### BITCOIND
# Bitcoind is enabled by default if nix-bitcoin is enabled # 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; # services.bitcoind.prune = lib.mkForce 100000;
# #
# You can add options that are not defined in modules/bitcoind.nix as follows # You can add options that are not defined in modules/bitcoind.nix as follows

View File

@ -256,7 +256,7 @@ in {
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ cfg.package ]; environment.systemPackages = [ cfg.package (hiPrio cfg.cli) ];
systemd.services.bitcoind = { systemd.services.bitcoind = {
description = "Bitcoin daemon"; description = "Bitcoin daemon";
requires = [ "nix-bitcoin-secrets.target" ]; requires = [ "nix-bitcoin-secrets.target" ];

View File

@ -71,6 +71,7 @@ in {
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.nix-bitcoin.clightning (hiPrio cfg.cli) ];
users.users.clightning = { users.users.clightning = {
description = "clightning User"; description = "clightning User";
group = "clightning"; group = "clightning";

View File

@ -7,7 +7,7 @@
lightning-charge = ./lightning-charge.nix; lightning-charge = ./lightning-charge.nix;
liquid = ./liquid.nix; liquid = ./liquid.nix;
nanopos = ./nanopos.nix; nanopos = ./nanopos.nix;
nix-bitcoin = ./nix-bitcoin.nix; presets.secure-node = ./presets/secure-node.nix;
nix-bitcoin-webindex = ./nix-bitcoin-webindex.nix; nix-bitcoin-webindex = ./nix-bitcoin-webindex.nix;
spark-wallet = ./spark-wallet.nix; spark-wallet = ./spark-wallet.nix;
recurring-donations = ./recurring-donations.nix; recurring-donations = ./recurring-donations.nix;

View File

@ -44,11 +44,6 @@ in {
default = 50001; default = 50001;
description = "RPC port."; description = "RPC port.";
}; };
onionport = mkOption {
type = types.ints.u16;
default = 50002;
description = "Port on which to listen for tor client connections.";
};
extraArgs = mkOption { extraArgs = mkOption {
type = types.separatedString " "; type = types.separatedString " ";
default = ""; default = "";
@ -66,6 +61,8 @@ in {
}; };
config = mkIf cfg.enable (mkMerge [{ config = mkIf cfg.enable (mkMerge [{
environment.systemPackages = [ pkgs.nix-bitcoin.electrs ];
systemd.services.electrs = { systemd.services.electrs = {
description = "Electrs Electrum Server"; description = "Electrs Electrum Server";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];

View File

@ -32,11 +32,16 @@ in {
}; };
config = mkMerge [ config = mkMerge [
{ (mkIf (cfg.ledger || cfg.trezor) {
# Create group environment.systemPackages = with pkgs; [
nix-bitcoin.hwi
# Provides lsusb for debugging
usbutils
];
users.groups."${cfg.group}" = {}; users.groups."${cfg.group}" = {};
} })
(mkIf cfg.ledger { (mkIf cfg.ledger {
# Ledger Nano S according to https://github.com/LedgerHQ/udev-rules/blob/master/add_udev_rules.sh # 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. # Don't use rules from nixpkgs because we want to use our own group.
services.udev.packages = lib.singleton (pkgs.writeTextFile { services.udev.packages = lib.singleton (pkgs.writeTextFile {
@ -48,6 +53,7 @@ in {
}); });
}) })
(mkIf cfg.trezor { (mkIf cfg.trezor {
environment.systemPackages = [ pkgs.python3.pkgs.trezor ];
# Don't use rules from nixpkgs because we want to use our own group. # Don't use rules from nixpkgs because we want to use our own group.
services.udev.packages = lib.singleton (pkgs.writeTextFile { services.udev.packages = lib.singleton (pkgs.writeTextFile {
name = "trezord-udev-rules"; name = "trezord-udev-rules";

View File

@ -24,6 +24,7 @@ in {
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.nix-bitcoin.lightning-charge ];
systemd.services.lightning-charge = { systemd.services.lightning-charge = {
description = "Run lightning-charge"; description = "Run lightning-charge";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];

View File

@ -195,7 +195,11 @@ in {
}; };
config = mkIf cfg.enable { 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 = { systemd.services.liquidd = {
description = "Elements daemon providing access to the Liquid sidechain"; description = "Elements daemon providing access to the Liquid sidechain";
requires = [ "bitcoind.service" ]; requires = [ "bitcoind.service" ];

View File

@ -77,7 +77,7 @@ in {
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ cfg.package ]; environment.systemPackages = [ cfg.package (hiPrio cfg.cli) ];
systemd.services.lnd = { systemd.services.lnd = {
description = "Run LND"; description = "Run LND";
path = [ pkgs.nix-bitcoin.bitcoind ]; path = [ pkgs.nix-bitcoin.bitcoind ];

View File

@ -52,6 +52,7 @@ in {
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.nix-bitcoin.nanopos ];
systemd.services.nanopos = { systemd.services.nanopos = {
description = "Run nanopos"; description = "Run nanopos";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
@ -60,7 +61,6 @@ in {
serviceConfig = { serviceConfig = {
EnvironmentFile = "${config.nix-bitcoin.secretsDir}/nanopos-env"; EnvironmentFile = "${config.nix-bitcoin.secretsDir}/nanopos-env";
ExecStart = "${pkgs.nix-bitcoin.nanopos}/bin/nanopos -y ${cfg.itemsFile} -p ${toString cfg.port} --show-bolt11"; ExecStart = "${pkgs.nix-bitcoin.nanopos}/bin/nanopos -y ${cfg.itemsFile} -p ${toString cfg.port} --show-bolt11";
User = "nanopos"; User = "nanopos";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "10s"; RestartSec = "10s";

View File

@ -1,183 +1,9 @@
{ config, lib, pkgs, ... }: # This file exists only for backwards compatibility
with lib; { lib, ... }:
{
let imports = [
cfg = config.services.nix-bitcoin; ./presets/secure-node.nix
operatorCopySSH = pkgs.writeText "operator-copy-ssh.sh" '' (lib.mkRemovedOptionModule [ "services" "nix-bitcoin" "enable" ] "Please directly import ./presets/secure-node.nix")
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 ];
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 {
nix-bitcoin.secretsDir = mkDefault "/secrets";
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;
# Tor SSH service
services.tor.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.tor.hiddenServices.bitcoind = {
map = [{
port = config.services.bitcoind.port;
}];
version = 3;
};
# 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.tor.hiddenServices.clightning = {
map = [{
port = 9735; toPort = 9735;
}];
version = 3;
};
# lnd
services.lnd.enforceTor = true;
# Create user operator which can use bitcoin-cli and lightning-cli
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 [ ]);
};
# Give operator access to onion hostnames
services.onion-chef.enable = true;
services.onion-chef.access.operator = [ "bitcoind" "clightning" "nginx" "liquidd" "spark-wallet" "electrs" "sshd" ];
# 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 ''
operator ALL=(clightning) NOPASSWD: ALL
'') +
(optionalString config.services.lnd.enable ''
operator ALL=(lnd) NOPASSWD: ALL
'');
# Give root ssh access to the operator account
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";
};
};
services.nix-bitcoin-webindex.enforceTor = true;
services.liquidd.rpcuser = "liquidrpc";
services.liquidd.prune = 1000;
services.liquidd.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;
services.tor.hiddenServices.liquidd = {
map = [{
port = config.services.liquidd.port; toPort = config.services.liquidd.port;
}];
version = 3;
};
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.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
[
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
];
};
} }

View File

@ -0,0 +1,154 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services;
mkHiddenService = map: {
map = [ map ];
version = 3;
};
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;
description = "Port on which to listen for tor client connections.";
};
};
config = {
# For backwards compatibility only
nix-bitcoin.secretsDir = mkDefault "/secrets";
networking.firewall.enable = true;
# Tor
services.tor = {
enable = true;
client.enable = true;
# LND uses ControlPort to create onion services
controlPort = mkIf cfg.lnd.enable 9051;
hiddenServices.sshd = mkHiddenService { port = 22; };
};
# bitcoind
services.bitcoind = {
enable = true;
listen = true;
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";
zmqpubrawtx = "tcp://127.0.0.1:28333";
assumevalid = "00000000000000000000e5abc3a74fe27dc0ead9c70ea1deb456f11c15fd7bc6";
addnodes = [ "ecoc5q34tmbq54wl.onion" ];
discover = false;
addresstype = "bech32";
prune = 0;
dbCache = 1000;
};
services.tor.hiddenServices.bitcoind = mkHiddenService { port = cfg.bitcoind.port; };
# clightning
services.clightning = {
bitcoin-rpcuser = cfg.bitcoind.rpcuser;
proxy = cfg.tor.client.socksListenAddress;
enforceTor = true;
always-use-proxy = true;
bind-addr = "127.0.0.1:${toString cfg.clightning.onionport}";
};
services.tor.hiddenServices.clightning = mkHiddenService { port = cfg.clightning.onionport; };
# lnd
services.lnd.enforceTor = true;
# liquidd
services.liquidd = {
rpcuser = "liquidrpc";
prune = 1000;
extraConfig = ''
mainchainrpcuser=${cfg.bitcoind.rpcuser}
mainchainrpcport=8332
'';
validatepegin = true;
listen = true;
proxy = cfg.tor.client.socksListenAddress;
enforceTor = true;
port = 7042;
};
services.tor.hiddenServices.liquidd = mkHiddenService { port = cfg.liquidd.port; };
# electrs
services.electrs = {
port = 50001;
enforceTor = true;
TLSProxy.enable = true;
TLSProxy.port = 50003;
};
services.tor.hiddenServices.electrs = mkHiddenService {
port = cfg.electrs.onionport;
toPort = cfg.electrs.TLSProxy.port;
};
services.spark-wallet.onion-service = true;
services.nix-bitcoin-webindex.enforceTor = true;
environment.systemPackages = with pkgs; [
tor
jq
qrencode
nix-bitcoin.nodeinfo
];
# Create user 'operator' which can access the node's services
users.users.operator = {
isNormalUser = true;
extraGroups = [
"systemd-journal"
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 ]);
openssh.authorizedKeys.keys = config.users.users.root.openssh.authorizedKeys.keys;
};
# Give operator access to onion hostnames
services.onion-chef.enable = true;
services.onion-chef.access.operator = [ "bitcoind" "clightning" "nginx" "liquidd" "spark-wallet" "electrs" "sshd" ];
# Unfortunately c-lightning doesn't allow setting the permissions of the rpc socket
# https://github.com/ElementsProject/lightning/issues/1366
security.sudo.configFile =
(optionalString cfg.clightning.enable ''
operator ALL=(clightning) NOPASSWD: ALL
'') +
(optionalString cfg.lnd.enable ''
operator ALL=(lnd) 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) {
postStart = ''
cp "${config.users.users.root.home}/.vbox-nixops-client-key" "${config.users.users.operator.home}"
'';
};
};
}

View File

@ -47,6 +47,7 @@ in {
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.nix-bitcoin.spark-wallet ];
services.tor.enable = cfg.onion-service; services.tor.enable = cfg.onion-service;
# requires client functionality for Bitcoin rate lookup # requires client functionality for Bitcoin rate lookup
services.tor.client.enable = true; services.tor.client.enable = true;

View File

@ -10,13 +10,12 @@ import ./make-test.nix rec {
machine = { pkgs, lib, ... }: with lib; { machine = { pkgs, lib, ... }: with lib; {
imports = [ imports = [
../modules/nix-bitcoin.nix ../modules/presets/secure-node.nix
../modules/secrets/generate-secrets.nix ../modules/secrets/generate-secrets.nix
# using the hardened profile increases total test duration by ~50%, so disable it for now # using the hardened profile increases total test duration by ~50%, so disable it for now
# hardened # hardened
]; ];
services.nix-bitcoin.enable = true;
services.bitcoind.extraConfig = mkForce "connect=0"; services.bitcoind.extraConfig = mkForce "connect=0";
services.clightning.enable = true; services.clightning.enable = true;