bitcoind: add rpc user option 'passwordHMACFromFile'

This allows adding additional rpc users without the need for
user-specific code in preStart.
This commit is contained in:
Erik Arvstedt 2020-08-26 21:15:33 +02:00
parent 59434e79f0
commit 876cfadf1a
No known key found for this signature in database
GPG Key ID: 33312B944DD97846
2 changed files with 25 additions and 16 deletions

View File

@ -30,12 +30,11 @@ let
${optionalString (cfg.rpcthreads != null) "rpcthreads=${toString cfg.rpcthreads}"} ${optionalString (cfg.rpcthreads != null) "rpcthreads=${toString cfg.rpcthreads}"}
rpcport=${toString cfg.rpc.port} rpcport=${toString cfg.rpc.port}
rpcwhitelistdefault=0 rpcwhitelistdefault=0
${concatMapStringsSep "\n" ${concatMapStrings (user: ''
(rpcUser: '' ${optionalString (!user.passwordHMACFromFile) "rpcauth=${user.name}:${passwordHMAC}"}
rpcauth=${rpcUser.name}:${rpcUser.passwordHMAC} ${optionalString (user.rpcwhitelist != [])
${optionalString (rpcUser.rpcwhitelist != []) "rpcwhitelist=${rpcUser.name}:${lib.strings.concatStringsSep "," rpcUser.rpcwhitelist}"} "rpcwhitelist=${user.name}:${lib.strings.concatStringsSep "," user.rpcwhitelist}"}
'') '') (builtins.attrValues cfg.rpc.users)
(attrValues cfg.rpc.users)
} }
${lib.concatMapStrings (rpcbind: "rpcbind=${rpcbind}\n") cfg.rpcbind} ${lib.concatMapStrings (rpcbind: "rpcbind=${rpcbind}\n") cfg.rpcbind}
${lib.concatMapStrings (rpcallowip: "rpcallowip=${rpcallowip}\n") cfg.rpcallowip} ${lib.concatMapStrings (rpcallowip: "rpcallowip=${rpcallowip}\n") cfg.rpcallowip}
@ -123,6 +122,11 @@ in {
format <SALT-HEX>$<HMAC-HEX>. format <SALT-HEX>$<HMAC-HEX>.
''; '';
}; };
passwordHMACFromFile = mkOption {
type = lib.types.bool;
internal = true;
default = false;
};
rpcwhitelist = mkOption { rpcwhitelist = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [];
@ -296,13 +300,20 @@ in {
requires = [ "nix-bitcoin-secrets.target" ]; requires = [ "nix-bitcoin-secrets.target" ];
after = [ "network.target" "nix-bitcoin-secrets.target" ]; after = [ "network.target" "nix-bitcoin-secrets.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
preStart = '' preStart = let
extraRpcauth = concatMapStrings (name: let
user = cfg.rpc.users.${name};
in optionalString user.passwordHMACFromFile ''
echo "rpcauth=${user.name}:$(cat ${secretsDir}/bitcoin-HMAC-${name})"
''
) (builtins.attrNames cfg.rpc.users);
in ''
${optionalString cfg.dataDirReadableByGroup "chmod -R g+rX '${cfg.dataDir}/blocks'"} ${optionalString cfg.dataDirReadableByGroup "chmod -R g+rX '${cfg.dataDir}/blocks'"}
cfg=$(
cfgpre=$(cat ${configFile}; printf "rpcpassword="; cat "${secretsDir}/bitcoin-rpcpassword-privileged") cat ${configFile};
cfg=$(echo "$cfgpre" | \ ${extraRpcauth}
sed "s/bitcoin-HMAC-privileged/$(cat ${secretsDir}/bitcoin-HMAC-privileged)/g" | \ printf "rpcpassword="; cat "${secretsDir}/bitcoin-rpcpassword-privileged";
sed "s/bitcoin-HMAC-public/$(cat ${secretsDir}/bitcoin-HMAC-public)/g") )
confFile='${cfg.dataDir}/bitcoin.conf' confFile='${cfg.dataDir}/bitcoin.conf'
if [[ ! -e $confFile || $cfg != $(cat $confFile) ]]; then if [[ ! -e $confFile || $cfg != $(cat $confFile) ]]; then
install -o '${cfg.user}' -g '${cfg.group}' -m 640 <(echo "$cfg") $confFile install -o '${cfg.user}' -g '${cfg.group}' -m 640 <(echo "$cfg") $confFile

View File

@ -77,13 +77,11 @@ in {
rpcthreads = 16; rpcthreads = 16;
rpc.users.privileged = { rpc.users.privileged = {
name = "bitcoinrpc"; name = "bitcoinrpc";
# Placeholder to be sed'd out by bitcoind preStart passwordHMACFromFile = true;
passwordHMAC = "bitcoin-HMAC-privileged";
}; };
rpc.users.public = { rpc.users.public = {
name = "publicrpc"; name = "publicrpc";
# Placeholder to be sed'd out by bitcoind preStart passwordHMACFromFile = true;
passwordHMAC = "bitcoin-HMAC-public";
rpcwhitelist = [ rpcwhitelist = [
"echo" "echo"
"getinfo" "getinfo"