clightning: integrate with tor
This commit is contained in:
@@ -30,6 +30,13 @@
|
|||||||
# see docs at top of file for how to generate this
|
# see docs at top of file for how to generate this
|
||||||
passwordHMAC = "30002c05d82daa210550e17a182db3f3$6071444151281e1aa8a2729f75e3e2d224e9d7cac3974810dab60e7c28ffaae4";
|
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;
|
sane.users.colin.fs.".bitcoin/bitcoin.conf" = sane-lib.fs.wantedSymlinkTo config.sops.secrets."bitcoin.conf".path;
|
||||||
|
@@ -1,9 +1,16 @@
|
|||||||
# clightning is an implementation of Bitcoin's Lightning Network.
|
# clightning is an implementation of Bitcoin's Lightning Network.
|
||||||
# as such, this assumes that `services.bitcoin` is enabled.
|
# as such, this assumes that `services.bitcoin` is enabled.
|
||||||
|
# docs:
|
||||||
|
# - tor clightning config: <https://docs.corelightning.org/docs/tor>
|
||||||
#
|
#
|
||||||
# management/setup/use:
|
# management/setup/use:
|
||||||
# - guide: <https://github.com/ElementsProject/lightning>
|
# - guide: <https://github.com/ElementsProject/lightning>
|
||||||
# - `sudo -u clightning -g clightning lightning-cli help`
|
# - `sudo -u clightning -g clightning lightning-cli help`
|
||||||
|
#
|
||||||
|
# first, acquire peers:
|
||||||
|
# - `lightning-cli listpeers`
|
||||||
|
#
|
||||||
|
# sanity:
|
||||||
# - `lightning-cli listfunds`
|
# - `lightning-cli listfunds`
|
||||||
#
|
#
|
||||||
# to receive a payment (do as `clightning` user):
|
# to receive a payment (do as `clightning` user):
|
||||||
@@ -23,13 +30,34 @@
|
|||||||
"befcb82d9821049164db5217beb85439$2c31ac7db3124612e43893ae13b9527dbe464ab2d992e814602e7cb07dc28985";
|
"befcb82d9821049164db5217beb85439$2c31ac7db3124612e43893ae13b9527dbe464ab2d992e814602e7cb07dc28985";
|
||||||
|
|
||||||
sane.services.clightning.enable = true;
|
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 ];
|
sane.services.clightning.extraConfigFiles = [ config.sops.secrets."lightning-config".path ];
|
||||||
sops.secrets."lightning-config" = {
|
sops.secrets."lightning-config" = {
|
||||||
mode = "0600";
|
mode = "0600";
|
||||||
owner = "clightning";
|
owner = "clightning";
|
||||||
group = "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
|
sane.programs.clightning.enableFor.user.colin = true; # put `lightning-cli` onto PATH
|
||||||
}
|
}
|
||||||
|
@@ -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: `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.
|
# tor.client.enable configures a torsocks proxy, accessible *only* to localhost.
|
||||||
# at 127.0.0.1:9050
|
# at 127.0.0.1:9050
|
||||||
services.tor.enable = true;
|
services.tor.enable = true;
|
||||||
services.tor.client.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";
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,7 @@ let
|
|||||||
network=bitcoin
|
network=bitcoin
|
||||||
bitcoin-datadir=${bitcoind.dataDir}
|
bitcoin-datadir=${bitcoind.dataDir}
|
||||||
${lib.optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"}
|
${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}
|
always-use-proxy=${lib.boolToString cfg.always-use-proxy}
|
||||||
bind-addr=${cfg.address}:${toString cfg.port}
|
bind-addr=${cfg.address}:${toString cfg.port}
|
||||||
bitcoin-rpcconnect=127.0.0.1
|
bitcoin-rpcconnect=127.0.0.1
|
||||||
@@ -68,6 +69,28 @@ in
|
|||||||
default = "127.0.0.1";
|
default = "127.0.0.1";
|
||||||
description = mdDoc "Address to listen for peer connections.";
|
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 {
|
port = mkOption {
|
||||||
type = types.port;
|
type = types.port;
|
||||||
default = 9735;
|
default = 9735;
|
||||||
@@ -140,7 +163,12 @@ in
|
|||||||
rm -f ${cfg.networkDir}/lightning-rpc
|
rm -f ${cfg.networkDir}/lightning-rpc
|
||||||
|
|
||||||
umask u=rw,g=r,o=
|
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
|
# Wait until the rpc socket appears
|
||||||
postStart = ''
|
postStart = ''
|
||||||
|
Reference in New Issue
Block a user