2021-01-14 12:24:10 +00:00
|
|
|
# This module enables unprivileged users to read onion addresses.
|
|
|
|
# By default, onion addresses in /var/lib/tor/onion are only readable by the
|
|
|
|
# tor user.
|
|
|
|
# The included service copies onion addresses to /var/lib/onion-addresses/<user>/
|
|
|
|
# and sets permissions according to option 'access'.
|
2019-03-29 14:46:13 +00:00
|
|
|
|
2021-01-14 12:24:14 +00:00
|
|
|
{ config, lib, ... }:
|
2019-03-29 14:46:13 +00:00
|
|
|
|
|
|
|
with lib;
|
|
|
|
let
|
2021-01-14 12:24:10 +00:00
|
|
|
options.nix-bitcoin.onionAddresses = {
|
2019-03-29 14:46:13 +00:00
|
|
|
access = mkOption {
|
2021-01-14 12:24:13 +00:00
|
|
|
type = with types; attrsOf (listOf str);
|
2019-03-29 14:46:13 +00:00
|
|
|
default = {};
|
2022-12-18 12:13:47 +00:00
|
|
|
description = mdDoc ''
|
2021-01-14 12:24:13 +00:00
|
|
|
This option controls who is allowed to access onion addresses.
|
|
|
|
For example, the following allows user 'myuser' to access bitcoind
|
|
|
|
and clightning onion addresses:
|
2022-12-18 12:13:47 +00:00
|
|
|
```nix
|
2019-03-29 14:46:13 +00:00
|
|
|
{
|
2021-01-14 12:24:13 +00:00
|
|
|
"myuser" = [ "bitcoind" "clightning" ];
|
2019-03-29 14:46:13 +00:00
|
|
|
};
|
2022-12-18 12:13:47 +00:00
|
|
|
```
|
2019-03-29 14:46:13 +00:00
|
|
|
The onion hostnames can then be read from
|
2022-12-18 12:13:47 +00:00
|
|
|
{file}`/var/lib/onion-addresses/myuser`.
|
2019-03-29 14:46:13 +00:00
|
|
|
'';
|
|
|
|
};
|
2021-01-30 09:47:05 +00:00
|
|
|
services = mkOption {
|
|
|
|
type = with types; listOf str;
|
|
|
|
default = [];
|
2022-12-18 12:13:47 +00:00
|
|
|
description = mdDoc ''
|
2021-01-30 09:47:05 +00:00
|
|
|
Services that can access their onion address via file
|
2022-12-18 12:13:47 +00:00
|
|
|
{file}`/var/lib/onion-addresses/<service>`
|
2021-01-30 09:47:05 +00:00
|
|
|
The file is readable only by the service user.
|
|
|
|
'';
|
|
|
|
};
|
2021-01-14 12:24:16 +00:00
|
|
|
dataDir = mkOption {
|
|
|
|
readOnly = true;
|
|
|
|
default = "/var/lib/onion-addresses";
|
|
|
|
};
|
2019-03-29 14:46:13 +00:00
|
|
|
};
|
|
|
|
|
2021-09-13 11:40:47 +00:00
|
|
|
cfg = config.nix-bitcoin.onionAddresses;
|
|
|
|
nbLib = config.nix-bitcoin.lib;
|
|
|
|
in {
|
|
|
|
inherit options;
|
|
|
|
|
2021-01-30 09:47:05 +00:00
|
|
|
config = mkIf (cfg.access != {} || cfg.services != []) {
|
2021-01-14 12:24:10 +00:00
|
|
|
systemd.services.onion-addresses = {
|
2019-11-27 13:04:37 +00:00
|
|
|
wantedBy = [ "tor.service" ];
|
|
|
|
bindsTo = [ "tor.service" ];
|
2019-03-29 14:46:13 +00:00
|
|
|
after = [ "tor.service" ];
|
2021-02-03 21:44:41 +00:00
|
|
|
serviceConfig = nbLib.defaultHardening // {
|
2019-03-29 14:46:13 +00:00
|
|
|
Type = "oneshot";
|
2019-11-27 13:04:37 +00:00
|
|
|
RemainAfterExit = true;
|
2021-01-14 12:24:11 +00:00
|
|
|
StateDirectory = "onion-addresses";
|
2021-01-30 09:47:05 +00:00
|
|
|
StateDirectoryMode = "771";
|
2020-05-05 13:25:00 +00:00
|
|
|
PrivateNetwork = "true"; # This service needs no network access
|
2020-05-06 08:28:00 +00:00
|
|
|
PrivateUsers = "false";
|
2020-05-05 13:27:07 +00:00
|
|
|
CapabilityBoundingSet = "CAP_CHOWN CAP_FSETID CAP_SETFCAP CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER CAP_IPC_OWNER";
|
2020-05-05 13:18:41 +00:00
|
|
|
};
|
2021-01-14 12:24:14 +00:00
|
|
|
script = ''
|
2021-11-28 20:19:20 +00:00
|
|
|
waitForFile() {
|
|
|
|
file=$1
|
|
|
|
for ((i=0; i<300; i++)); do
|
|
|
|
if [[ -e $file ]]; then
|
|
|
|
return;
|
|
|
|
fi
|
|
|
|
sleep 0.1
|
|
|
|
done
|
|
|
|
echo "Error: File $file did not appear after 30 sec."
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
2021-01-14 12:24:15 +00:00
|
|
|
# Wait until tor is up
|
2021-11-28 20:19:20 +00:00
|
|
|
waitForFile /var/lib/tor/state
|
2021-01-14 12:24:14 +00:00
|
|
|
|
2021-01-14 12:24:16 +00:00
|
|
|
cd ${cfg.dataDir}
|
2022-07-31 21:32:12 +00:00
|
|
|
rm -rf ./*
|
2021-01-14 12:24:14 +00:00
|
|
|
|
2021-01-14 12:24:15 +00:00
|
|
|
${concatMapStrings
|
|
|
|
(user: ''
|
2021-01-14 12:24:14 +00:00
|
|
|
mkdir -p -m 0700 ${user}
|
|
|
|
chown ${user} ${user}
|
2021-01-14 12:24:15 +00:00
|
|
|
${concatMapStrings
|
|
|
|
(service: ''
|
2022-07-31 21:32:12 +00:00
|
|
|
onionFile='/var/lib/tor/onion/${service}/hostname'
|
|
|
|
waitForFile "$onionFile"
|
|
|
|
cp "$onionFile" '${user}/${service}'
|
|
|
|
chown '${user}' '${user}/${service}'
|
2021-01-14 12:24:15 +00:00
|
|
|
'')
|
|
|
|
cfg.access.${user}
|
2021-11-28 20:19:20 +00:00
|
|
|
}
|
2021-01-14 12:24:15 +00:00
|
|
|
'')
|
2021-01-14 12:24:14 +00:00
|
|
|
(builtins.attrNames cfg.access)
|
|
|
|
}
|
2021-01-30 09:47:05 +00:00
|
|
|
|
|
|
|
${concatMapStrings (service: ''
|
|
|
|
onionFile=/var/lib/tor/onion/${service}/hostname
|
2022-07-31 21:32:12 +00:00
|
|
|
waitForFile "$onionFile"
|
|
|
|
install -D -o ${config.systemd.services.${service}.serviceConfig.User} -m 400 "$onionFile" services/${service}
|
2021-01-30 09:47:05 +00:00
|
|
|
'') cfg.services}
|
2021-01-14 12:24:14 +00:00
|
|
|
'';
|
2019-03-29 14:46:13 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|