nix-bitcoin/modules/clightning.nix

153 lines
5.0 KiB
Nix
Raw Normal View History

2018-11-22 18:49:53 +00:00
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.clightning;
nbLib = config.nix-bitcoin.lib;
nbPkgs = config.nix-bitcoin.pkgs;
2020-10-16 15:43:01 +00:00
network = config.services.bitcoind.makeNetworkName "bitcoin" "regtest";
2018-11-22 18:49:53 +00:00
configFile = pkgs.writeText "config" ''
2020-10-16 15:43:01 +00:00
network=${network}
bitcoin-datadir=${config.services.bitcoind.dataDir}
${optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"}
always-use-proxy=${boolToString cfg.always-use-proxy}
bind-addr=${cfg.address}:${toString cfg.port}
bitcoin-rpcconnect=${config.services.bitcoind.rpc.address}
bitcoin-rpcport=${toString config.services.bitcoind.rpc.port}
bitcoin-rpcuser=${config.services.bitcoind.rpc.users.public.name}
rpc-file-mode=0660
2020-09-28 11:09:07 +00:00
${cfg.extraConfig}
2018-11-22 18:49:53 +00:00
'';
in {
options.services.clightning = {
2021-02-01 21:53:15 +00:00
enable = mkEnableOption "clightning";
address = mkOption {
type = types.str;
default = "127.0.0.1";
description = "IP address or UNIX domain socket to listen for peer connections.";
};
port = mkOption {
type = types.port;
default = 9735;
description = "Port to listen for peer connections.";
2018-11-22 18:49:53 +00:00
};
proxy = mkOption {
type = types.nullOr types.str;
default = if cfg.enforceTor then config.services.tor.client.socksListenAddress 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;
description = ''
Always use the proxy, even to connect to normal IP addresses.
You can still connect to Unix domain sockets manually.
This also disables all DNS lookups, to avoid leaking address information.
'';
};
2018-11-28 23:54:19 +00:00
dataDir = mkOption {
type = types.path;
default = "/var/lib/clightning";
description = "The data directory for clightning.";
2018-11-28 23:54:19 +00:00
};
2020-10-16 15:43:04 +00:00
networkDir = mkOption {
readOnly = true;
default = "${cfg.dataDir}/${network}";
description = "The network data directory.";
};
2020-09-28 11:09:07 +00:00
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Extra lines appended to the configuration file.";
2020-09-28 11:09:07 +00:00
};
2020-05-19 16:09:22 +00:00
user = mkOption {
type = types.str;
default = "clightning";
description = "The user as which to run clightning.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run clightning.";
};
cli = mkOption {
readOnly = true;
2021-02-01 21:53:10 +00:00
default = pkgs.writeScriptBin "lightning-cli" ''
${nbPkgs.clightning}/bin/lightning-cli --lightning-dir='${cfg.dataDir}' "$@"
'';
description = "Binary to connect with the clightning instance.";
};
getPublicAddressCmd = mkOption {
type = types.str;
default = "";
description = ''
Bash expression which outputs the public service address to announce to peers.
If left empty, no address is announced.
'';
};
inherit (nbLib) enforceTor;
2018-11-22 18:49:53 +00:00
};
config = mkIf cfg.enable {
services.bitcoind = {
enable = true;
# Increase rpc thread count due to reports that lightning implementations fail
# under high bitcoind rpc load
rpc.threads = 16;
};
2020-10-18 12:49:20 +00:00
environment.systemPackages = [ nbPkgs.clightning (hiPrio cfg.cli) ];
2018-11-28 23:54:19 +00:00
systemd.tmpfiles.rules = [
2020-05-19 16:09:22 +00:00
"d '${cfg.dataDir}' 0770 ${cfg.user} ${cfg.group} - -"
];
2019-01-02 15:17:57 +00:00
systemd.services.clightning = {
path = [ nbPkgs.bitcoind ];
2019-01-02 15:17:57 +00:00
wantedBy = [ "multi-user.target" ];
requires = [ "bitcoind.service" ];
after = [ "bitcoind.service" ];
2019-01-02 15:17:57 +00:00
preStart = ''
2020-05-19 16:09:22 +00:00
chown -R '${cfg.user}:${cfg.group}' '${cfg.dataDir}'
2019-01-02 15:17:57 +00:00
# The RPC socket has to be removed otherwise we might have stale sockets
2020-10-16 15:43:04 +00:00
rm -f ${cfg.networkDir}/lightning-rpc
install -m 640 ${configFile} '${cfg.dataDir}/config'
{
echo "bitcoin-rpcpassword=$(cat ${config.nix-bitcoin.secretsDir}/bitcoin-rpcpassword-public)"
${optionalString (cfg.getPublicAddressCmd != "") ''
echo "announce-addr=$(${cfg.getPublicAddressCmd})"
''}
} >> '${cfg.dataDir}/config'
'';
serviceConfig = nbLib.defaultHardening // {
ExecStart = "${nbPkgs.clightning}/bin/lightningd --lightning-dir=${cfg.dataDir}";
User = cfg.user;
2019-01-02 15:17:57 +00:00
Restart = "on-failure";
RestartSec = "10s";
ReadWritePaths = cfg.dataDir;
} // (if cfg.enforceTor
then nbLib.allowTor
else nbLib.allowAnyIP
);
# Wait until the rpc socket appears
postStart = ''
2020-10-16 15:43:04 +00:00
while [[ ! -e ${cfg.networkDir}/lightning-rpc ]]; do
sleep 0.1
done
# Needed to enable lightning-cli for users with group 'clightning'
2020-10-16 15:43:04 +00:00
chmod g+x ${cfg.networkDir}
'';
2018-11-22 18:49:53 +00:00
};
users.users.${cfg.user} = {
group = cfg.group;
extraGroups = [ "bitcoinrpc-public" ];
};
users.groups.${cfg.group} = {};
nix-bitcoin.operator.groups = [ cfg.group ];
2019-01-02 15:17:57 +00:00
};
2018-11-22 18:49:53 +00:00
}