2021-01-14 04:24:17 -08:00
|
|
|
# This module creates onion-services for NixOS services.
|
|
|
|
# An onion service can be enabled for every service that defines
|
|
|
|
# options 'address', 'port' and optionally 'getPublicAddressCmd'.
|
|
|
|
#
|
|
|
|
# See it in use at ./presets/enable-tor.nix
|
|
|
|
|
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
let
|
|
|
|
options.nix-bitcoin.onionServices = mkOption {
|
|
|
|
default = {};
|
|
|
|
type = with types; attrsOf (submodule (
|
|
|
|
{ config, ... }: {
|
|
|
|
options = {
|
|
|
|
enable = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = config.public;
|
|
|
|
description = ''
|
|
|
|
Create an onion service for the given service.
|
2021-10-15 06:56:13 -07:00
|
|
|
The service must define options 'address' and 'onionPort' (or `port`).
|
2021-01-14 04:24:17 -08:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
public = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
Make the onion address accessible to the service.
|
|
|
|
If enabled, the onion service is automatically enabled.
|
|
|
|
Only available for services that define option `getPublicAddressCmd`.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
externalPort = mkOption {
|
|
|
|
type = types.nullOr types.port;
|
|
|
|
default = null;
|
|
|
|
description = "Override the external port of the onion service.";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
));
|
|
|
|
};
|
|
|
|
|
2021-09-13 04:40:47 -07:00
|
|
|
cfg = config.nix-bitcoin.onionServices;
|
|
|
|
nbLib = config.nix-bitcoin.lib;
|
|
|
|
|
2021-10-05 06:07:56 -07:00
|
|
|
onionServices = builtins.attrNames cfg;
|
2021-09-13 04:40:47 -07:00
|
|
|
|
|
|
|
activeServices = builtins.filter (service:
|
|
|
|
config.services.${service}.enable && cfg.${service}.enable
|
2021-10-05 06:07:56 -07:00
|
|
|
) onionServices;
|
2021-09-13 04:40:47 -07:00
|
|
|
|
|
|
|
publicServices = builtins.filter (service: cfg.${service}.public) activeServices;
|
|
|
|
in {
|
|
|
|
inherit options;
|
|
|
|
|
2021-01-14 04:24:17 -08:00
|
|
|
config = mkMerge [
|
2021-10-05 06:07:56 -07:00
|
|
|
(mkIf (activeServices != []) {
|
2021-01-14 04:24:17 -08:00
|
|
|
# Define hidden services
|
|
|
|
services.tor = {
|
|
|
|
enable = true;
|
2021-08-04 15:49:00 -07:00
|
|
|
relay.onionServices = genAttrs activeServices (name:
|
2021-01-14 04:24:17 -08:00
|
|
|
let
|
|
|
|
service = config.services.${name};
|
|
|
|
inherit (cfg.${name}) externalPort;
|
2021-08-04 15:49:00 -07:00
|
|
|
in nbLib.mkOnionService {
|
2021-02-03 13:44:42 -08:00
|
|
|
port = if externalPort != null then externalPort else service.port;
|
2021-10-15 06:56:13 -07:00
|
|
|
target.port = service.onionPort or service.port;
|
2021-10-01 02:51:57 -07:00
|
|
|
target.addr = nbLib.address service.address;
|
2021-01-14 04:24:17 -08:00
|
|
|
}
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2021-01-30 01:47:05 -08:00
|
|
|
nix-bitcoin.onionAddresses = {
|
|
|
|
# Enable public services to access their own onion addresses
|
|
|
|
services = publicServices;
|
|
|
|
|
2021-01-14 04:24:17 -08:00
|
|
|
# Allow the operator user to access onion addresses for all active services
|
2021-01-30 01:47:05 -08:00
|
|
|
access.${config.nix-bitcoin.operator.name} = mkIf config.nix-bitcoin.operator.enable activeServices;
|
2021-01-14 04:24:17 -08:00
|
|
|
};
|
|
|
|
systemd.services = let
|
|
|
|
onionAddresses = [ "onion-addresses.service" ];
|
|
|
|
in genAttrs publicServices (service: {
|
|
|
|
requires = onionAddresses;
|
|
|
|
after = onionAddresses;
|
|
|
|
});
|
|
|
|
})
|
|
|
|
|
|
|
|
# Set getPublicAddressCmd for public services
|
|
|
|
{
|
|
|
|
services = let
|
|
|
|
# publicServices' doesn't depend on config.services.*.enable,
|
|
|
|
# so we can use it to define config.services without causing infinite recursion
|
|
|
|
publicServices' = builtins.filter (service:
|
|
|
|
let srv = cfg.${service};
|
|
|
|
in srv.public && srv.enable
|
2021-10-05 06:07:56 -07:00
|
|
|
) onionServices;
|
2021-01-14 04:24:17 -08:00
|
|
|
in genAttrs publicServices' (service: {
|
2021-02-16 08:53:35 -08:00
|
|
|
getPublicAddressCmd = "cat ${config.nix-bitcoin.onionAddresses.dataDir}/services/${service}";
|
2021-01-14 04:24:17 -08:00
|
|
|
});
|
|
|
|
}
|
2021-01-14 04:24:18 -08:00
|
|
|
|
|
|
|
# Set sensible defaults for some services
|
|
|
|
{
|
|
|
|
nix-bitcoin.onionServices = {
|
2021-01-14 04:24:19 -08:00
|
|
|
spark-wallet = {
|
|
|
|
externalPort = 80;
|
|
|
|
# Enable 'public' by default, but don't auto-enable the onion service.
|
|
|
|
# When the onion service is enabled, 'public' lets spark-wallet generate
|
|
|
|
# a QR code for accessing the web interface.
|
|
|
|
public = true;
|
|
|
|
# Low priority so we can override this with mkDefault in ./presets/enable-tor.nix
|
|
|
|
enable = mkOverride 1400 false;
|
|
|
|
};
|
2021-01-14 04:24:18 -08:00
|
|
|
btcpayserver = {
|
|
|
|
externalPort = 80;
|
|
|
|
};
|
2021-01-17 04:24:57 -08:00
|
|
|
joinmarket-ob-watcher = {
|
|
|
|
externalPort = 80;
|
|
|
|
};
|
2021-01-14 04:24:18 -08:00
|
|
|
};
|
2021-10-15 06:56:13 -07:00
|
|
|
|
|
|
|
# When the bitcoind onion service is enabled, add an onion-tagged socket
|
|
|
|
# to distinguish local connections from Tor connections
|
|
|
|
services.bitcoind.onionPort = mkIf (cfg.bitcoind.enable or false) 8334;
|
2021-01-14 04:24:18 -08:00
|
|
|
}
|
2021-01-14 04:24:17 -08:00
|
|
|
];
|
|
|
|
}
|