2019-03-29 07:46:13 -07:00
|
|
|
# The onion chef module allows unprivileged users to read onion hostnames.
|
|
|
|
# By default the onion hostnames in /var/lib/tor/onion are only readable by the
|
|
|
|
# tor user. The onion chef copies the onion hostnames into into
|
|
|
|
# /var/lib/onion-chef and sets permissions according to the access option.
|
|
|
|
|
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
cfg = config.services.onion-chef;
|
2019-11-27 05:04:23 -08:00
|
|
|
inherit (config) nix-bitcoin-services;
|
2019-03-29 07:46:13 -07:00
|
|
|
dataDir = "/var/lib/onion-chef/";
|
|
|
|
onion-chef-script = pkgs.writeScript "onion-chef.sh" ''
|
|
|
|
# wait until tor is up
|
|
|
|
until ls -l /var/lib/tor/state; do sleep 1; done
|
|
|
|
|
|
|
|
cd ${dataDir}
|
|
|
|
|
|
|
|
# Create directory for every user and set permissions
|
|
|
|
${ builtins.foldl'
|
|
|
|
(x: user: x +
|
|
|
|
''
|
|
|
|
mkdir -p -m 0700 ${user}
|
|
|
|
chown ${user} ${user}
|
|
|
|
# Copy onion hostnames into the user's directory
|
|
|
|
${ builtins.foldl'
|
|
|
|
(x: onion: x +
|
|
|
|
''
|
|
|
|
ONION_FILE=/var/lib/tor/onion/${onion}/hostname
|
|
|
|
if [ -e "$ONION_FILE" ]; then
|
|
|
|
cp $ONION_FILE ${user}/${onion}
|
|
|
|
chown ${user} ${user}/${onion}
|
|
|
|
fi
|
|
|
|
'')
|
|
|
|
""
|
|
|
|
(builtins.getAttr user cfg.access)
|
|
|
|
}
|
|
|
|
'')
|
|
|
|
""
|
|
|
|
(builtins.attrNames cfg.access)
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
in {
|
|
|
|
options.services.onion-chef = {
|
|
|
|
enable = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
If enabled, the onion-chef service will be installed.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
access = mkOption {
|
|
|
|
type = types.attrs;
|
|
|
|
default = {};
|
|
|
|
description = ''
|
|
|
|
This option controls who is allowed to access onion hostnames. For
|
|
|
|
example the following allows the user operator to access the bitcoind
|
|
|
|
and clightning onion.
|
|
|
|
{
|
|
|
|
"operator" = [ "bitcoind" "clightning" ];
|
|
|
|
};
|
|
|
|
The onion hostnames can then be read from
|
|
|
|
/var/lib/onion-chef/<user>.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = mkIf cfg.enable {
|
2020-05-06 03:43:57 -07:00
|
|
|
systemd.tmpfiles.rules = [
|
|
|
|
"d '${dataDir}' 0755 root root - -"
|
|
|
|
];
|
|
|
|
|
2019-03-29 07:46:13 -07:00
|
|
|
systemd.services.onion-chef = {
|
|
|
|
description = "Run onion-chef";
|
2019-11-27 05:04:37 -08:00
|
|
|
wantedBy = [ "tor.service" ];
|
|
|
|
bindsTo = [ "tor.service" ];
|
2019-03-29 07:46:13 -07:00
|
|
|
after = [ "tor.service" ];
|
2020-05-05 06:18:41 -07:00
|
|
|
serviceConfig = nix-bitcoin-services.defaultHardening // {
|
2019-03-29 07:46:13 -07:00
|
|
|
ExecStart = "${pkgs.bash}/bin/bash ${onion-chef-script}";
|
|
|
|
Type = "oneshot";
|
2019-11-27 05:04:37 -08:00
|
|
|
RemainAfterExit = true;
|
2020-05-05 06:25:00 -07:00
|
|
|
PrivateNetwork = "true"; # This service needs no network access
|
2020-05-06 01:28:00 -07:00
|
|
|
PrivateUsers = "false";
|
2020-05-05 08:15:16 -07:00
|
|
|
ReadWritePaths = "${dataDir}";
|
2020-05-05 06:27:07 -07:00
|
|
|
CapabilityBoundingSet = "CAP_CHOWN CAP_FSETID CAP_SETFCAP CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER CAP_IPC_OWNER";
|
2020-05-05 06:18:41 -07:00
|
|
|
};
|
2019-03-29 07:46:13 -07:00
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|