onionServices: use actual user name of services

Previously, onionAddresses definitions in onionServices were of the form
onionAddresses.access.<service> = [<service>];

This caused failures for configurations where a service user name was
overridden or for bitcoind whose default user is 'bitcoin' instead of 'bitcoind'.

Now set the equivalent of:
onionAddresses.access.<actualServiceUser> = [<service>];

Implement this via a new option `onionAddresses.services` to make things more
readable and to work around an infinite recursion error in onionServices.
This commit is contained in:
Erik Arvstedt 2021-01-30 10:47:05 +01:00
parent 5c09845e6f
commit 9662c19ab1
No known key found for this signature in database
GPG Key ID: 33312B944DD97846
2 changed files with 24 additions and 7 deletions

View File

@ -27,13 +27,22 @@ in {
/var/lib/onion-addresses/myuser. /var/lib/onion-addresses/myuser.
''; '';
}; };
services = mkOption {
type = with types; listOf str;
default = [];
description = ''
Services that can access their onion address via file
/var/lib/onion-addresses/<service>
The file is readable only by the service user.
'';
};
dataDir = mkOption { dataDir = mkOption {
readOnly = true; readOnly = true;
default = "/var/lib/onion-addresses"; default = "/var/lib/onion-addresses";
}; };
}; };
config = mkIf (cfg.access != {}) { config = mkIf (cfg.access != {} || cfg.services != []) {
systemd.services.onion-addresses = { systemd.services.onion-addresses = {
wantedBy = [ "tor.service" ]; wantedBy = [ "tor.service" ];
bindsTo = [ "tor.service" ]; bindsTo = [ "tor.service" ];
@ -42,6 +51,7 @@ in {
Type = "oneshot"; Type = "oneshot";
RemainAfterExit = true; RemainAfterExit = true;
StateDirectory = "onion-addresses"; StateDirectory = "onion-addresses";
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";
@ -70,6 +80,13 @@ in {
'') '')
(builtins.attrNames cfg.access) (builtins.attrNames cfg.access)
} }
${concatMapStrings (service: ''
onionFile=/var/lib/tor/onion/${service}/hostname
if [[ -e $onionFile ]]; then
install -o ${config.systemd.services.${service}.serviceConfig.User} -m 400 $onionFile ${service}
fi
'') cfg.services}
''; '';
}; };
}; };

View File

@ -71,12 +71,12 @@ in {
); );
}; };
nix-bitcoin.onionAddresses = {
# Enable public services to access their own onion addresses # Enable public services to access their own onion addresses
nix-bitcoin.onionAddresses.access = ( services = publicServices;
genAttrs publicServices singleton
) // {
# Allow the operator user to access onion addresses for all active services # Allow the operator user to access onion addresses for all active services
${config.nix-bitcoin.operator.name} = mkIf config.nix-bitcoin.operator.enable activeServices; access.${config.nix-bitcoin.operator.name} = mkIf config.nix-bitcoin.operator.enable activeServices;
}; };
systemd.services = let systemd.services = let
onionAddresses = [ "onion-addresses.service" ]; onionAddresses = [ "onion-addresses.service" ];
@ -96,7 +96,7 @@ in {
in srv.public && srv.enable in srv.public && srv.enable
) services; ) services;
in genAttrs publicServices' (service: { in genAttrs publicServices' (service: {
getPublicAddressCmd = "cat ${config.nix-bitcoin.onionAddresses.dataDir}/${service}/${service}"; getPublicAddressCmd = "cat ${config.nix-bitcoin.onionAddresses.dataDir}/${service}";
}); });
} }