services: add tor.*
options
Split `enforceTor` into `tor.proxy` and `tor.enforce`. By enabling `tor.proxy` without `tor.enforce`, a service can accept incoming clearnet connections. E.g., this allows setting up a Tor-proxied bitcoind node that accepts RPC connections from LAN.
This commit is contained in:
parent
ff24e73ad7
commit
9bda7305fd
@ -157,7 +157,7 @@ let
|
||||
};
|
||||
proxy = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = if cfg.enforceTor then config.nix-bitcoin.torClientAddressWithPort else null;
|
||||
default = if cfg.tor.proxy then config.nix-bitcoin.torClientAddressWithPort else null;
|
||||
description = "Connect through SOCKS5 proxy";
|
||||
};
|
||||
i2p = mkOption {
|
||||
@ -262,7 +262,7 @@ let
|
||||
'';
|
||||
description = "Binary to connect with the bitcoind instance.";
|
||||
};
|
||||
enforceTor = nbLib.enforceTor;
|
||||
tor = nbLib.tor;
|
||||
};
|
||||
};
|
||||
|
||||
@ -407,7 +407,7 @@ in {
|
||||
Restart = "on-failure";
|
||||
UMask = mkIf cfg.dataDirReadableByGroup "0027";
|
||||
ReadWritePaths = cfg.dataDir;
|
||||
} // nbLib.allowedIPAddresses cfg.enforceTor
|
||||
} // nbLib.allowedIPAddresses cfg.tor.enforce
|
||||
// optionalAttrs zmqServerEnabled nbLib.allowNetlink;
|
||||
};
|
||||
|
||||
|
@ -54,7 +54,7 @@ let
|
||||
default = cfg.btcpayserver.user;
|
||||
description = "The group as which to run btcpayserver.";
|
||||
};
|
||||
enforceTor = nbLib.enforceTor;
|
||||
tor.enforce = nbLib.tor.enforce;
|
||||
};
|
||||
|
||||
nbxplorer = {
|
||||
@ -96,7 +96,7 @@ let
|
||||
default = cfg.nbxplorer.user;
|
||||
description = "The group as which to run nbxplorer.";
|
||||
};
|
||||
enforceTor = nbLib.enforceTor;
|
||||
tor.enforce = nbLib.tor.enforce;
|
||||
};
|
||||
};
|
||||
|
||||
@ -185,7 +185,7 @@ in {
|
||||
RestartSec = "10s";
|
||||
ReadWritePaths = cfg.nbxplorer.dataDir;
|
||||
MemoryDenyWriteExecute = "false";
|
||||
} // nbLib.allowedIPAddresses cfg.nbxplorer.enforceTor;
|
||||
} // nbLib.allowedIPAddresses cfg.nbxplorer.tor.enforce;
|
||||
};
|
||||
|
||||
systemd.services.btcpayserver = let
|
||||
@ -238,7 +238,7 @@ in {
|
||||
RestartSec = "10s";
|
||||
ReadWritePaths = cfg.btcpayserver.dataDir;
|
||||
MemoryDenyWriteExecute = "false";
|
||||
} // nbLib.allowedIPAddresses cfg.btcpayserver.enforceTor;
|
||||
} // nbLib.allowedIPAddresses cfg.btcpayserver.tor.enforce;
|
||||
}; in self;
|
||||
|
||||
users.users.${cfg.nbxplorer.user} = {
|
||||
|
@ -28,6 +28,6 @@ let cfg = config.services.clightning.plugins.clboss; in
|
||||
'';
|
||||
systemd.services.clightning.path = [
|
||||
pkgs.dnsutils
|
||||
] ++ optional config.services.clightning.enforceTor (hiPrio config.nix-bitcoin.torify);
|
||||
] ++ optional config.services.clightning.tor.proxy (hiPrio config.nix-bitcoin.torify);
|
||||
};
|
||||
}
|
||||
|
@ -16,14 +16,14 @@ let
|
||||
};
|
||||
proxy = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = if cfg.enforceTor then config.nix-bitcoin.torClientAddressWithPort else null;
|
||||
default = if cfg.tor.proxy then config.nix-bitcoin.torClientAddressWithPort else null;
|
||||
description = ''
|
||||
Socks proxy for connecting to Tor nodes (or for all connections if option always-use-proxy is set).
|
||||
'';
|
||||
};
|
||||
always-use-proxy = mkOption {
|
||||
type = types.bool;
|
||||
default = cfg.enforceTor;
|
||||
default = cfg.tor.proxy;
|
||||
description = ''
|
||||
Always use the proxy, even to connect to normal IP addresses.
|
||||
You can still connect to Unix domain sockets manually.
|
||||
@ -79,7 +79,7 @@ let
|
||||
If left empty, no address is announced.
|
||||
'';
|
||||
};
|
||||
inherit (nbLib) enforceTor;
|
||||
tor = nbLib.tor;
|
||||
};
|
||||
|
||||
cfg = config.services.clightning;
|
||||
@ -156,7 +156,7 @@ in {
|
||||
#
|
||||
# Disable seccomp filtering because clightning depends on this syscall.
|
||||
SystemCallFilter = [];
|
||||
} // nbLib.allowedIPAddresses cfg.enforceTor;
|
||||
} // nbLib.allowedIPAddresses cfg.tor.enforce;
|
||||
# Wait until the rpc socket appears
|
||||
postStart = ''
|
||||
while [[ ! -e ${cfg.networkDir}/lightning-rpc ]]; do
|
||||
|
@ -39,7 +39,7 @@ let
|
||||
default = cfg.user;
|
||||
description = "The group as which to run electrs.";
|
||||
};
|
||||
enforceTor = nbLib.enforceTor;
|
||||
tor.enforce = nbLib.tor.enforce;
|
||||
};
|
||||
|
||||
cfg = config.services.electrs;
|
||||
@ -94,7 +94,7 @@ in {
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
ReadWritePaths = cfg.dataDir;
|
||||
} // nbLib.allowedIPAddresses cfg.enforceTor;
|
||||
} // nbLib.allowedIPAddresses cfg.tor.enforce;
|
||||
};
|
||||
|
||||
users.users.${cfg.user} = {
|
||||
|
@ -29,11 +29,9 @@ let
|
||||
default = cfg.user;
|
||||
description = "The group as which to run JoinMarket.";
|
||||
};
|
||||
# This option is only used by netns-isolation
|
||||
enforceTor = mkOption {
|
||||
readOnly = true;
|
||||
default = true;
|
||||
};
|
||||
# This option is only used by netns-isolation.
|
||||
# Tor is always enabled.
|
||||
tor.enforce = nbLib.tor.enforce;
|
||||
};
|
||||
|
||||
cfg = config.services.joinmarket-ob-watcher;
|
||||
@ -100,7 +98,7 @@ in {
|
||||
SystemCallFilter = nbLib.defaultHardening.SystemCallFilter ++ [ "mbind" ] ;
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
} // nbLib.allowTor;
|
||||
} // nbLib.allowedIPAddresses cfg.tor.enforce;
|
||||
};
|
||||
|
||||
users.users.${cfg.user} = {
|
||||
|
@ -50,11 +50,9 @@ let
|
||||
readOnly = true;
|
||||
default = ircServers;
|
||||
};
|
||||
# This option is only used by netns-isolation
|
||||
enforceTor = mkOption {
|
||||
readOnly = true;
|
||||
default = true;
|
||||
};
|
||||
# This option is only used by netns-isolation.
|
||||
# Tor is always enabled.
|
||||
tor.enforce = nbLib.tor.enforce;
|
||||
inherit (nbLib) cliExec;
|
||||
|
||||
yieldgenerator = {
|
||||
@ -328,7 +326,7 @@ in {
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
ReadWritePaths = cfg.dataDir;
|
||||
} // nbLib.allowTor;
|
||||
} // nbLib.allowedIPAddresses cfg.tor.enforce;
|
||||
};
|
||||
|
||||
users.users.${cfg.user} = {
|
||||
|
@ -36,7 +36,7 @@ let
|
||||
};
|
||||
proxy = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = if cfg.enforceTor then config.nix-bitcoin.torClientAddressWithPort else null;
|
||||
default = if cfg.tor.proxy then config.nix-bitcoin.torClientAddressWithPort else null;
|
||||
description = "host:port of SOCKS5 proxy for connnecting to the loop server.";
|
||||
};
|
||||
extraConfig = mkOption {
|
||||
@ -56,7 +56,7 @@ let
|
||||
'';
|
||||
description = "Binary to connect with the lightning-loop instance.";
|
||||
};
|
||||
enforceTor = nbLib.enforceTor;
|
||||
tor = nbLib.tor;
|
||||
};
|
||||
|
||||
cfg = config.services.lightning-loop;
|
||||
@ -105,7 +105,7 @@ in {
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
ReadWritePaths = cfg.dataDir;
|
||||
} // nbLib.allowedIPAddresses cfg.enforceTor;
|
||||
} // nbLib.allowedIPAddresses cfg.tor.enforce;
|
||||
};
|
||||
|
||||
nix-bitcoin.secrets = {
|
||||
|
@ -36,7 +36,7 @@ let
|
||||
};
|
||||
proxy = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = if cfg.enforceTor then config.nix-bitcoin.torClientAddressWithPort else null;
|
||||
default = if cfg.tor.proxy then config.nix-bitcoin.torClientAddressWithPort else null;
|
||||
description = "host:port of SOCKS5 proxy for connnecting to the pool auction server.";
|
||||
};
|
||||
extraConfig = mkOption {
|
||||
@ -56,7 +56,7 @@ let
|
||||
'';
|
||||
description = "Binary to connect with the lightning-pool instance.";
|
||||
};
|
||||
enforceTor = nbLib.enforceTor;
|
||||
tor = nbLib.tor;
|
||||
};
|
||||
|
||||
cfg = config.services.lightning-pool;
|
||||
@ -102,7 +102,7 @@ in {
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
ReadWritePaths = cfg.dataDir;
|
||||
} // (nbLib.allowedIPAddresses cfg.enforceTor)
|
||||
} // (nbLib.allowedIPAddresses cfg.tor.enforce)
|
||||
// nbLib.allowNetlink; # required by gRPC-Go
|
||||
};
|
||||
};
|
||||
|
@ -98,7 +98,7 @@ let
|
||||
};
|
||||
proxy = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = if cfg.enforceTor then config.nix-bitcoin.torClientAddressWithPort else null;
|
||||
default = if cfg.tor.proxy then config.nix-bitcoin.torClientAddressWithPort else null;
|
||||
description = "Connect through SOCKS5 proxy";
|
||||
};
|
||||
dbCache = mkOption {
|
||||
@ -156,7 +156,7 @@ let
|
||||
'';
|
||||
description = "Binary for managing liquid swaps.";
|
||||
};
|
||||
enforceTor = nbLib.enforceTor;
|
||||
tor = nbLib.tor;
|
||||
};
|
||||
};
|
||||
|
||||
@ -271,7 +271,7 @@ in {
|
||||
ExecStart = "${nbPkgs.elementsd}/bin/elementsd -datadir='${cfg.dataDir}'";
|
||||
Restart = "on-failure";
|
||||
ReadWritePaths = cfg.dataDir;
|
||||
} // nbLib.allowedIPAddresses cfg.enforceTor;
|
||||
} // nbLib.allowedIPAddresses cfg.tor.enforce;
|
||||
};
|
||||
|
||||
users.users.${cfg.user} = {
|
||||
|
@ -46,7 +46,7 @@ let
|
||||
};
|
||||
tor-socks = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = if cfg.enforceTor then config.nix-bitcoin.torClientAddressWithPort else null;
|
||||
default = if cfg.tor.proxy then config.nix-bitcoin.torClientAddressWithPort else null;
|
||||
description = "Socks proxy for connecting to Tor nodes";
|
||||
};
|
||||
macaroons = mkOption {
|
||||
@ -117,7 +117,7 @@ let
|
||||
default = "${secretsDir}/lnd-cert";
|
||||
description = "LND TLS certificate path.";
|
||||
};
|
||||
inherit (nbLib) enforceTor;
|
||||
tor = nbLib.tor;
|
||||
};
|
||||
|
||||
cfg = config.services.lnd;
|
||||
@ -143,7 +143,7 @@ let
|
||||
bitcoin.active=1
|
||||
bitcoin.node=bitcoind
|
||||
|
||||
${optionalString (cfg.enforceTor) "tor.active=true"}
|
||||
${optionalString (cfg.tor.proxy) "tor.active=true"}
|
||||
${optionalString (cfg.tor-socks != null) "tor.socks=${cfg.tor-socks}"}
|
||||
|
||||
bitcoind.rpchost=${bitcoindRpcAddress}:${toString bitcoind.rpc.port}
|
||||
@ -277,7 +277,7 @@ in {
|
||||
'') (attrNames cfg.macaroons)}
|
||||
'')
|
||||
];
|
||||
} // nbLib.allowedIPAddresses cfg.enforceTor;
|
||||
} // nbLib.allowedIPAddresses cfg.tor.enforce;
|
||||
};
|
||||
|
||||
users.users.${cfg.user} = {
|
||||
|
@ -179,7 +179,7 @@ in {
|
||||
${iptables} -w -A INPUT -s 127.0.0.1,${bridgeIp},${v.address} -j ACCEPT
|
||||
# allow return traffic to outgoing connections initiated by the service itself
|
||||
${iptables} -w -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
|
||||
'' + optionalString (config.services.${n}.enforceTor or false) ''
|
||||
'' + optionalString (config.services.${n}.tor.enforce or false) ''
|
||||
${iptables} -w -P OUTPUT DROP
|
||||
${iptables} -w -A OUTPUT -d 127.0.0.1,${bridgeIp},${v.address} -j ACCEPT
|
||||
'' + optionalString (v.availableNetns != []) ''
|
||||
|
@ -7,6 +7,16 @@ let
|
||||
mkRemovedOptionModule [ "services" service "announce-tor" ] ''
|
||||
Use option `nix-bitcoin.onionServices.${service}.public` instead.
|
||||
'';
|
||||
|
||||
mkSplitEnforceTorOption = service:
|
||||
(mkRemovedOptionModule [ "services" service "enforceTor" ] ''
|
||||
The option has been split into options `tor.proxy` and `tor.enforce`.
|
||||
Set `tor.proxy = true` to proxy outgoing connections with Tor.
|
||||
Set `tor.enforce = true` to only allow connections (incoming and outgoing) through Tor.
|
||||
'');
|
||||
mkRenamedEnforceTorOption = service:
|
||||
(mkRenamedOptionModule [ "services" service "enforceTor" ] [ "services" service "tor" "enforce" ]);
|
||||
|
||||
in {
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "services" "bitcoind" "bind" ] [ "services" "bitcoind" "address" ])
|
||||
@ -33,5 +43,20 @@ in {
|
||||
bitcoin peer connections for syncing blocks. This performs well on low and high
|
||||
memory systems.
|
||||
'')
|
||||
];
|
||||
] ++
|
||||
# 0.0.59
|
||||
(map mkSplitEnforceTorOption [
|
||||
"clightning"
|
||||
"lightning-loop"
|
||||
"lightning-pool"
|
||||
"liquid"
|
||||
"lnd"
|
||||
"spark-wallet"
|
||||
"bitcoind"
|
||||
]) ++
|
||||
(map mkRenamedEnforceTorOption [
|
||||
"btcpayserver"
|
||||
"rtl"
|
||||
"electrs"
|
||||
]);
|
||||
}
|
||||
|
@ -1,26 +1,42 @@
|
||||
{ lib, config, ... }:
|
||||
let
|
||||
defaultTrue = lib.mkDefault true;
|
||||
defaultEnableTorProxy = {
|
||||
tor.proxy = defaultTrue;
|
||||
tor.enforce = defaultTrue;
|
||||
};
|
||||
defaultEnforceTor = {
|
||||
tor.enforce = defaultTrue;
|
||||
};
|
||||
in {
|
||||
services.tor = {
|
||||
enable = true;
|
||||
client.enable = true;
|
||||
};
|
||||
|
||||
# Use Tor for all outgoing connections
|
||||
services = {
|
||||
bitcoind.enforceTor = true;
|
||||
clightning.enforceTor = true;
|
||||
lnd.enforceTor = true;
|
||||
lightning-loop.enforceTor = true;
|
||||
liquidd.enforceTor = true;
|
||||
electrs.enforceTor = true;
|
||||
# Use Tor as a proxy for outgoing connections
|
||||
# and restrict all connections to Tor
|
||||
#
|
||||
bitcoind = defaultEnableTorProxy;
|
||||
clightning = defaultEnableTorProxy;
|
||||
lnd = defaultEnableTorProxy;
|
||||
lightning-loop = defaultEnableTorProxy;
|
||||
liquidd = defaultEnableTorProxy;
|
||||
# disable Tor enforcement until btcpayserver can fetch rates over Tor
|
||||
# btcpayserver.enforceTor = true;
|
||||
nbxplorer.enforceTor = true;
|
||||
spark-wallet.enforceTor = true;
|
||||
lightning-pool.enforceTor = true;
|
||||
rtl.enforceTor = true;
|
||||
# btcpayserver = defaultEnableTorProxy;
|
||||
spark-wallet = defaultEnableTorProxy;
|
||||
lightning-pool = defaultEnableTorProxy;
|
||||
|
||||
# These services don't make outgoing connections
|
||||
# (or use Tor by default in case of joinmarket)
|
||||
# but we restrict them to Tor just to be safe.
|
||||
#
|
||||
electrs = defaultEnforceTor;
|
||||
nbxplorer = defaultEnforceTor;
|
||||
rtl = defaultEnforceTor;
|
||||
joinmarket = defaultEnforceTor;
|
||||
joinmarket-ob-watcher = defaultEnforceTor;
|
||||
};
|
||||
|
||||
# Add onion services for incoming connections
|
||||
|
@ -89,7 +89,7 @@ let
|
||||
description = "Swagger API documentation server port.";
|
||||
};
|
||||
};
|
||||
inherit (nbLib) enforceTor;
|
||||
tor.enforce = nbLib.tor.enforce;
|
||||
};
|
||||
|
||||
cfg = config.services.rtl;
|
||||
@ -214,7 +214,7 @@ in {
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
ReadWritePaths = cfg.dataDir;
|
||||
} // nbLib.allowedIPAddresses cfg.enforceTor
|
||||
} // nbLib.allowedIPAddresses cfg.tor.enforce
|
||||
// nbLib.nodejs;
|
||||
};
|
||||
|
||||
|
@ -38,7 +38,7 @@ let
|
||||
default = cfg.user;
|
||||
description = "The group as which to run spark-wallet.";
|
||||
};
|
||||
inherit (nbLib) enforceTor;
|
||||
tor = nbLib.tor;
|
||||
};
|
||||
|
||||
cfg = config.services.spark-wallet;
|
||||
@ -57,7 +57,7 @@ let
|
||||
--ln-path '${clightning.networkDir}' \
|
||||
--host ${cfg.address} --port ${toString cfg.port} \
|
||||
--config '${config.nix-bitcoin.secretsDir}/spark-wallet-login' \
|
||||
${optionalString cfg.enforceTor torRateProvider} \
|
||||
${optionalString cfg.tor.proxy torRateProvider} \
|
||||
$publicURL \
|
||||
--pairing-qr --print-key ${cfg.extraArgs}
|
||||
'';
|
||||
@ -76,7 +76,7 @@ in {
|
||||
User = cfg.user;
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
} // nbLib.allowedIPAddresses cfg.enforceTor
|
||||
} // nbLib.allowedIPAddresses cfg.tor.enforce
|
||||
// nbLib.nodejs;
|
||||
};
|
||||
|
||||
|
13
pkgs/lib.nix
13
pkgs/lib.nix
@ -55,14 +55,21 @@ let self = {
|
||||
then self.allowLocalIPAddresses
|
||||
else self.allowAllIPAddresses;
|
||||
|
||||
enforceTor = mkOption {
|
||||
tor = {
|
||||
proxy = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to proxy outgoing connections with Tor.";
|
||||
};
|
||||
enforce = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to force Tor on a service by only allowing connections from and
|
||||
to 127.0.0.1;
|
||||
Whether to enforce Tor on a service by only allowing connections
|
||||
from and to localhost and link-local addresses.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
script = name: src: pkgs.writers.writeBash name ''
|
||||
set -eo pipefail
|
||||
|
Loading…
Reference in New Issue
Block a user