bitcoind, liquidd: add whitelisted socket

This allows whitelisting local services without implicitly
whitelisting all inbound onion connections, which would happen when
setting bitcoind/liquidd option `whitelist=localhost`.

Used by electrs and nbxplorer, which requires the unsafe `mempool`
permission.
This commit is contained in:
Erik Arvstedt 2021-10-29 17:56:57 +02:00
parent 8c3a88b2e8
commit 1da23cd933
No known key found for this signature in database
GPG Key ID: 33312B944DD97846
4 changed files with 54 additions and 27 deletions

View File

@ -25,6 +25,27 @@ let
If set, inbound connections to this port are tagged as onion peers. If set, inbound connections to this port are tagged as onion peers.
''; '';
}; };
listen = mkOption {
type = types.bool;
default = false;
description = ''
Listen for peer connections at `address:port`
and `address:onionPort` (if `onionPort` is set).
'';
};
listenWhitelisted = mkOption {
type = types.bool;
default = false;
description = ''
Listen for peer connections at `address:whitelistedPort`.
Peers connected through this socket are automatically whitelisted.
'';
};
whitelistedPort = mkOption {
type = types.port;
default = 8335;
description = "See `listenWhitelisted`.";
};
getPublicAddressCmd = mkOption { getPublicAddressCmd = mkOption {
type = types.str; type = types.str;
default = ""; default = "";
@ -147,11 +168,6 @@ let
With `only-outgoing`, incoming i2p connections are disabled. With `only-outgoing`, incoming i2p connections are disabled.
''; '';
}; };
listen = mkOption {
type = types.bool;
default = false;
description = "Accept incoming connections.";
};
dataDirReadableByGroup = mkOption { dataDirReadableByGroup = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
@ -273,15 +289,17 @@ let
${optionalString (cfg.assumevalid != null) "assumevalid=${cfg.assumevalid}"} ${optionalString (cfg.assumevalid != null) "assumevalid=${cfg.assumevalid}"}
# Connection options # Connection options
listen=${if (cfg.listen || cfg.listenWhitelisted) then "1" else "0"}
${optionalString cfg.listen ${optionalString cfg.listen
"bind=${cfg.address}:${toString cfg.port}"} "bind=${cfg.address}:${toString cfg.port}"}
${optionalString (cfg.listen && cfg.onionPort != null) ${optionalString (cfg.listen && cfg.onionPort != null)
"bind=${cfg.address}:${toString cfg.onionPort}=onion"} "bind=${cfg.address}:${toString cfg.onionPort}=onion"}
${optionalString cfg.listenWhitelisted
"whitebind=${cfg.address}:${toString cfg.whitelistedPort}"}
${optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"} ${optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"}
${optionalString (cfg.i2p != false) "i2psam=${nbLib.addressWithPort i2pSAM.address i2pSAM.port}"} ${optionalString (cfg.i2p != false) "i2psam=${nbLib.addressWithPort i2pSAM.address i2pSAM.port}"}
${optionalString (cfg.i2p == "only-outgoing") "i2pacceptincoming=0"} ${optionalString (cfg.i2p == "only-outgoing") "i2pacceptincoming=0"}
listen=${if cfg.listen then "1" else "0"}
${optionalString (cfg.discover != null) "discover=${if cfg.discover then "1" else "0"}"} ${optionalString (cfg.discover != null) "discover=${if cfg.discover then "1" else "0"}"}
${lib.concatMapStrings (node: "addnode=${node}\n") cfg.addnodes} ${lib.concatMapStrings (node: "addnode=${node}\n") cfg.addnodes}

View File

@ -116,18 +116,13 @@ in {
"getpeerinfo" "getpeerinfo"
]; ];
}; };
# Enable p2p connections listenWhitelisted = true;
listen = true;
extraConfig = ''
whitelist=download@${nbLib.address cfg.nbxplorer.address}
'';
}; };
services.clightning.enable = mkIf (cfg.btcpayserver.lightningBackend == "clightning") true; services.clightning.enable = mkIf (cfg.btcpayserver.lightningBackend == "clightning") true;
services.lnd.enable = mkIf (cfg.btcpayserver.lightningBackend == "lnd") true; services.lnd.enable = mkIf (cfg.btcpayserver.lightningBackend == "lnd") true;
services.liquidd = mkIf cfg.btcpayserver.lbtc { services.liquidd = mkIf cfg.btcpayserver.lbtc {
enable = true; enable = true;
# Enable p2p connections listenWhitelisted = true;
listen = true;
}; };
services.lnd.macaroons.btcpayserver = mkIf (cfg.btcpayserver.lightningBackend == "lnd") { services.lnd.macaroons.btcpayserver = mkIf (cfg.btcpayserver.lightningBackend == "lnd") {
@ -154,14 +149,14 @@ in {
network=${bitcoind.network} network=${bitcoind.network}
btcrpcuser=${cfg.bitcoind.rpc.users.btcpayserver.name} btcrpcuser=${cfg.bitcoind.rpc.users.btcpayserver.name}
btcrpcurl=http://${nbLib.addressWithPort bitcoind.rpc.address cfg.bitcoind.rpc.port} btcrpcurl=http://${nbLib.addressWithPort bitcoind.rpc.address cfg.bitcoind.rpc.port}
btcnodeendpoint=${nbLib.addressWithPort bitcoind.address bitcoind.port} btcnodeendpoint=${nbLib.addressWithPort bitcoind.address bitcoind.whitelistedPort}
bind=${cfg.nbxplorer.address} bind=${cfg.nbxplorer.address}
port=${toString cfg.nbxplorer.port} port=${toString cfg.nbxplorer.port}
${optionalString cfg.btcpayserver.lbtc '' ${optionalString cfg.btcpayserver.lbtc ''
chains=btc,lbtc chains=btc,lbtc
lbtcrpcuser=${liquidd.rpcuser} lbtcrpcuser=${liquidd.rpcuser}
lbtcrpcurl=http://${nbLib.addressWithPort liquidd.rpc.address liquidd.rpc.port} lbtcrpcurl=http://${nbLib.addressWithPort liquidd.rpc.address liquidd.rpc.port}
lbtcnodeendpoint=${nbLib.addressWithPort liquidd.address liquidd.port} lbtcnodeendpoint=${nbLib.addressWithPort liquidd.address bitcoind.whitelistedPort}
''} ''}
''; '';
in { in {

View File

@ -58,9 +58,7 @@ in {
services.bitcoind = { services.bitcoind = {
enable = true; enable = true;
# Enable p2p connections listenWhitelisted = true;
listen = true;
extraConfig = "whitelist=download@${nbLib.address cfg.address}";
}; };
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
@ -88,7 +86,7 @@ in {
--electrum-rpc-addr=${cfg.address}:${toString cfg.port} \ --electrum-rpc-addr=${cfg.address}:${toString cfg.port} \
--monitoring-addr=${cfg.address}:${toString cfg.monitoringPort} \ --monitoring-addr=${cfg.address}:${toString cfg.monitoringPort} \
--daemon-rpc-addr=${nbLib.addressWithPort bitcoind.rpc.address bitcoind.rpc.port} \ --daemon-rpc-addr=${nbLib.addressWithPort bitcoind.rpc.address bitcoind.rpc.port} \
--daemon-p2p-addr=${nbLib.addressWithPort bitcoind.address bitcoind.port} \ --daemon-p2p-addr=${nbLib.addressWithPort bitcoind.address bitcoind.whitelistedPort} \
${cfg.extraArgs} ${cfg.extraArgs}
''; '';
User = cfg.user; User = cfg.user;

View File

@ -25,6 +25,27 @@ let
If set, inbound connections to this port are tagged as onion peers. If set, inbound connections to this port are tagged as onion peers.
''; '';
}; };
listen = mkOption {
type = types.bool;
default = false;
description = ''
Listen for peer connections at `address:port`
and `address:onionPort` (if `onionPort` is set).
'';
};
listenWhitelisted = mkOption {
type = types.bool;
default = false;
description = ''
Listen for peer connections at `address:whitelistedPort`.
Peers connected through this socket are automatically whitelisted.
'';
};
whitelistedPort = mkOption {
type = types.port;
default = 7044;
description = "See `listenWhitelisted`.";
};
extraConfig = mkOption { extraConfig = mkOption {
type = types.lines; type = types.lines;
default = ""; default = "";
@ -80,13 +101,6 @@ let
default = if cfg.enforceTor then config.nix-bitcoin.torClientAddressWithPort else null; default = if cfg.enforceTor then config.nix-bitcoin.torClientAddressWithPort else null;
description = "Connect through SOCKS5 proxy"; description = "Connect through SOCKS5 proxy";
}; };
listen = mkOption {
type = types.bool;
default = false;
description = ''
If enabled, the liquid service will listen.
'';
};
dbCache = mkOption { dbCache = mkOption {
type = types.nullOr (types.ints.between 4 16384); type = types.nullOr (types.ints.between 4 16384);
default = null; default = null;
@ -163,12 +177,14 @@ let
${optionalString (cfg.validatepegin != null) "validatepegin=${if cfg.validatepegin then "1" else "0"}"} ${optionalString (cfg.validatepegin != null) "validatepegin=${if cfg.validatepegin then "1" else "0"}"}
# Connection options # Connection options
listen=${if (cfg.listen || cfg.listenWhitelisted) then "1" else "0"}
${optionalString cfg.listen ${optionalString cfg.listen
"bind=${cfg.address}:${toString cfg.port}"} "bind=${cfg.address}:${toString cfg.port}"}
${optionalString (cfg.listen && cfg.onionPort != null) ${optionalString (cfg.listen && cfg.onionPort != null)
"bind=${cfg.address}:${toString cfg.onionPort}=onion"} "bind=${cfg.address}:${toString cfg.onionPort}=onion"}
${optionalString cfg.listenWhitelisted
"whitebind=${cfg.address}:${toString cfg.whitelistedPort}"}
${optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"} ${optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"}
listen=${if cfg.listen then "1" else "0"}
# RPC server options # RPC server options
rpcport=${toString cfg.rpc.port} rpcport=${toString cfg.rpc.port}