clightning: integrate with tor

This commit is contained in:
Colin 2024-01-03 18:29:16 +00:00
parent 22f5853741
commit 43498c62f9
4 changed files with 80 additions and 3 deletions

View File

@ -30,6 +30,13 @@
# see docs at top of file for how to generate this
passwordHMAC = "30002c05d82daa210550e17a182db3f3$6071444151281e1aa8a2729f75e3e2d224e9d7cac3974810dab60e7c28ffaae4";
};
extraConfig = ''
# don't load the wallet, and disable wallet RPC calls
disablewallet=1
# TODO: configure tor integration
# proxy=127.0.0.1:9050
# externalip=$(cat /var/lib/tor/onion/bitcoind/hostname)
'';
};
sane.users.colin.fs.".bitcoin/bitcoin.conf" = sane-lib.fs.wantedSymlinkTo config.sops.secrets."bitcoin.conf".path;

View File

@ -1,9 +1,16 @@
# clightning is an implementation of Bitcoin's Lightning Network.
# as such, this assumes that `services.bitcoin` is enabled.
# docs:
# - tor clightning config: <https://docs.corelightning.org/docs/tor>
#
# management/setup/use:
# - guide: <https://github.com/ElementsProject/lightning>
# - `sudo -u clightning -g clightning lightning-cli help`
#
# first, acquire peers:
# - `lightning-cli listpeers`
#
# sanity:
# - `lightning-cli listfunds`
#
# to receive a payment (do as `clightning` user):
@ -23,13 +30,34 @@
"befcb82d9821049164db5217beb85439$2c31ac7db3124612e43893ae13b9527dbe464ab2d992e814602e7cb07dc28985";
sane.services.clightning.enable = true;
sane.services.clightning.proxy = "127.0.0.1:9050"; # proxy outgoing traffic through tor
# sane.services.clightning.publicAddress = "statictor:127.0.0.1:9051";
sane.services.clightning.getPublicAddressCmd = "cat /var/lib/tor/onion/clightning/hostname";
services.tor.relay.onionServices.clightning = {
version = 3;
map = [{
# by default tor will route public tor port P to 127.0.0.1:P.
# so if this port is the same as clightning would natively use, then no further config is needed here.
# see: <https://2019.www.torproject.org/docs/tor-manual.html.en#HiddenServicePort>
port = 9735;
# target.port; target.addr; #< set if tor port != clightning port
}];
# allow "tor" group (i.e. clightning) to read /var/lib/tor/onion/clightning/hostname
settings.HiddenServiceDirGroupReadable = true;
};
# must be in "tor" group to read /var/lib/tor/onion/*/hostname
users.users.clightning.extraGroups = [ "tor" ];
systemd.services.clightning.after = [ "tor.service" ];
sane.services.clightning.extraConfigFiles = [ config.sops.secrets."lightning-config".path ];
sops.secrets."lightning-config" = {
mode = "0600";
owner = "clightning";
group = "clightning";
};
sane.services.clightning.proxy = "127.0.0.1:9050"; # tor
sane.programs.clightning.enableFor.user.colin = true; # put `lightning-cli` onto PATH
}

View File

@ -1,8 +1,22 @@
{ ... }:
# tor settings: <https://2019.www.torproject.org/docs/tor-manual.html.en>
{ lib, ... }:
{
# tor hidden service hostnames aren't deterministic, so persist.
# might be able to get away with just persisting /var/lib/tor/onion, not sure.
sane.persist.sys.byStore.plaintext = [
{ user = "tor"; group = "tor"; mode = "0710"; path = "/var/lib/tor"; }
];
# tor: `tor.enable` doesn't start a relay, exit node, proxy, etc. it's minimal.
# tor.client.enable configures a torsocks proxy, accessible *only* to localhost.
# at 127.0.0.1:9050
services.tor.enable = true;
services.tor.client.enable = true;
# in order for services to read /var/lib/tor/onion/*/hostname, they must be able to traverse /var/lib/tor,
# and /var/lib/tor must have g+x.
# DataDirectoryGroupReadable causes tor to use g+rx, technically more than we need, but all the files are 600 so it's fine.
services.tor.settings.DataDirectoryGroupReadable = true;
# StateDirectoryMode defaults to 0700, and thereby prevents the onion hostnames from being group readable
systemd.services.tor.serviceConfig.StateDirectoryMode = lib.mkForce "0710";
}

View File

@ -18,6 +18,7 @@ let
network=bitcoin
bitcoin-datadir=${bitcoind.dataDir}
${lib.optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"}
${lib.optionalString (cfg.publicAddress != null) "addr=${cfg.publicAddress}"}
always-use-proxy=${lib.boolToString cfg.always-use-proxy}
bind-addr=${cfg.address}:${toString cfg.port}
bitcoin-rpcconnect=127.0.0.1
@ -68,6 +69,28 @@ in
default = "127.0.0.1";
description = mdDoc "Address to listen for peer connections.";
};
publicAddress = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
address to publish to peers.
leaving this empty will prevent incoming connections and channels, but it should still be possible to create outgoing channels.
formats:
- statictor:<ip>:<port>
creates a tor hidden service based on this node's pubkey, which remains constant across reboots.
'';
example = "statictor:127.0.0.1:9051";
};
getPublicAddressCmd = mkOption {
type = types.nullOr types.str;
default = null;
description = mdDoc ''
Bash expression which outputs the public service address to announce to peers.
this is an alternative to the `publicAddress` option, for if the address is not known statically (e.g. tor).
'';
};
port = mkOption {
type = types.port;
default = 9735;
@ -140,7 +163,12 @@ in
rm -f ${cfg.networkDir}/lightning-rpc
umask u=rw,g=r,o=
cat ${configFile} ${lib.concatStringsSep " " cfg.extraConfigFiles} > ${cfg.dataDir}/config
{
cat ${configFile} ${lib.concatStringsSep " " cfg.extraConfigFiles}
${lib.optionalString (cfg.getPublicAddressCmd != null) ''
echo "announce-addr=$(${cfg.getPublicAddressCmd}):${builtins.toString cfg.port}"
''}
} > ${cfg.dataDir}/config
'';
# Wait until the rpc socket appears
postStart = ''