Merge fort-nix/nix-bitcoin#425: Misc. improvements

def64a73b8 treewide: use TODO-EXTERNAL (Erik Arvstedt)
6f37bef2a3 netns-isolation: simplify firewall setup (Erik Arvstedt)
f52059ce3c docs: add doc 'Configuration and maintenance' (Erik Arvstedt)
94aee8174d usage.md: add section `Managing services` (Erik Arvstedt)
8cc7b83da1 usage.md: convert to '#' heading syntax (Erik Arvstedt)
91fbcfcc77 faq.md: reformat (Erik Arvstedt)
9e4f4d6b0f bitcoind: add option `txindex` (Erik Arvstedt)
10a744a598 rtl: add option `extraCurrency` (Erik Arvstedt)
62a2602e78 electrs: use dataDir for storing extra config (Erik Arvstedt)
9bda7305fd services: add `tor.*` options (Erik Arvstedt)
ff24e73ad7 onion-addresses: fix files not being copied (Erik Arvstedt)
c6fe017aeb netns-isolation: avoid creating service files for disabled services (Erik Arvstedt)
017e08ca10 btcpayserver: move nbxplorer options to bottom (Erik Arvstedt)
e1d869d76c modules.nix: move rtl to fix topological sorting (Erik Arvstedt)
e44cd7ecdc rtl: improve descriptions (Erik Arvstedt)
bd275d3a9a minor improvements (Erik Arvstedt)
8aa28da110 remove `recurring-donations` module (Erik Arvstedt)

Pull request description:

ACKs for top commit:
  nixbitcoin:
    ACK def64a73b8
  jonasnick:
    ACK def64a73b8

Tree-SHA512: 13acd2a3dd73c07f9c31874c8e961f12f39accb48847cbad08479b9a8154b79a6f186819272072dfb5c4768264b81f6e058e9afa57a729db2096784e48352dfd
This commit is contained in:
Jonas Nick 2021-11-29 18:05:08 +00:00
commit 747019a9e9
No known key found for this signature in database
GPG Key ID: 4861DBF262123605
31 changed files with 553 additions and 322 deletions

View File

@ -47,6 +47,14 @@ Get started
- To add nix-bitcoin to an existing NixOS configuration, see [importable-configuration.nix](examples/importable-configuration.nix)
and the [Flake example](examples/flakes/flake.nix).
Docs
---
* [Hardware Requirements](docs/hardware.md)
* [Installation](docs/install.md)
* [Configuration and maintenance](docs/configuration.md)
* [Using services](docs/services.md)
* [FAQ](docs/faq.md)
Features
---
A [configuration preset](modules/presets/secure-node.nix) for setting up a secure node
@ -69,13 +77,13 @@ NixOS modules ([src](modules/modules.nix))
* [Lightning Pool](https://github.com/lightninglabs/pool)
* [charge-lnd](https://github.com/accumulator/charge-lnd): policy-based channel fee manager
* [lndconnect](https://github.com/LN-Zap/lndconnect) via a REST onion service
* [Ride The Lightning](https://github.com/Ride-The-Lightning/RTL): web interface for `lnd` and `clightning`
* [spark-wallet](https://github.com/shesek/spark-wallet)
* [electrs](https://github.com/romanz/electrs)
* [btcpayserver](https://github.com/btcpayserver/btcpayserver)
* [liquid](https://github.com/elementsproject/elements)
* [JoinMarket](https://github.com/joinmarket-org/joinmarket-clientserver)
* [JoinMarket Orderbook Watcher](https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/orderbook.md)
* [recurring-donations](modules/recurring-donations.nix): for periodic lightning payments
* [bitcoin-core-hwi](https://github.com/bitcoin-core/HWI)
* Helper
* [netns-isolation](modules/netns-isolation.nix): isolates applications on the network-level via network namespaces
@ -92,13 +100,6 @@ Security
Note that if the machine you're deploying *from* is insecure, there is nothing nix-bitcoin can do to protect itself.
Docs
---
* [Hardware Requirements](docs/hardware.md)
* [Install instructions](docs/install.md)
* [Usage instructions](docs/usage.md)
* [FAQ](docs/faq.md)
Troubleshooting
---
If you are having problems with nix-bitcoin check the [FAQ](docs/faq.md) or submit an issue.\

240
docs/configuration.md Normal file
View File

@ -0,0 +1,240 @@
# Managing your deployment
This section applies to users of the deployment method described in the [installation guide](./install.md).
## Deployment shell
Run command `nix-shell` in your deployment directory.\
You now have access to deployment commands:
- `deploy`\
Deploy the current configuration to your node.
- `eval-config`\
Locally evaluate the configuration. This is useful to check for configuration errors.
- `h`, `help`\
Show help
## Updating nix-bitcoin
Run `update-nix-bitcoin` from the deployment shell.\
This fetches the latest release, verifies its signatures and updates `nix-bitcoin-release.nix`.
# Customizing your configuration
## Get started with Nix
See [Nix - A One Pager](https://github.com/tazjin/nix-1p) for a short guide
to Nix, the language used in `configuration.nix`.
You can follow along this guide by running command `nix repl` which allows you to interactively
evaluate Nix expressions.
For a general introduction to the Nix and NixOS ecosystem, see [nix.dev](https://nix.dev/).
## Set options
All features and services are configurable through options. You can find a list of
supported options at the top of each nix-bitcoin [module](../modules/modules.nix)
(Examples: [bitcoind.nix](../modules/bitcoind.nix), [btcpayserver.nix](../modules/btcpayserver.nix)).
Example: Set some `bitcoind` options by adding these lines to your `configuration.nix`:
```nix
# Use a custom data dir
services.bitcoind.dataDir = "/my/datadir";
# Enable txindex
services.bitcoind.txindex = true;
```
You can also use regular [NixOS options](https://search.nixos.org/options)
for configuring your system:
```nix
networking.hostName = "myhost";
time.timeZone = "UTC";
```
## Debug your configuration
To print the values of specific options of your config, add the following to your `configuration.nix`:
```nix
system.extraDependencies = let
debugVal = config.networking.firewall.allowedTCPPorts;
# More example options:
# debugVal = config.environment.systemPackages;
# debugVal = config.services.bitcoind.dataDir;
in lib.traceSeqN 3 debugVal [];
```
and run command `eval-config` from the deployment shell.
# Allowing external connections to services
## Allow peer connections to bitcoind
```nix
services.bitcoind = {
# Accept incoming peer connections
listen = true;
# Listen to connections on all interfaces
address = "0.0.0.0";
# Set this to also add IPv6 connectivity.
extraConfig = ''
bind=::
'';
# If you're using the `secure-node.nix` template, set this to allow non-Tor connections
# to bitcoind
tor.enforce = false;
# Also set this if bitcoind should not use Tor for outgoing peer connections
tor.proxy = false;
};
# Open the p2p port in the firewall
networking.firewall.allowedTCPPorts = [ config.services.nix-bitcoin.port ];
```
## Allow bitcoind RPC connections from LAN
```nix
services.bitcoind = {
# Listen to connections on all interfaces
address = "0.0.0.0";
# Allow RPC connections from external addresses
rpc.allowip = [
"10.10.0.0/24" # Allow a subnet
"10.50.0.3" # Allow a specific address
"0.0.0.0" # Allow all addresses
];
# Set this if you're using the `secure-node.nix` template
tor.enforce = false;
};
# Open the RPC port in the firewall
networking.firewall.allowedTCPPorts = [ config.services.nix-bitcoin.rpc.port ];
```
## Allow connections to electrs
```nix
services.electrs = {
# Listen to connections on all interfaces
address = "0.0.0.0";
# Set this if you're using the `secure-node.nix` template
tor.enforce = false;
};
# Open the electrs port in the firewall
networking.firewall.allowedTCPPorts = [ config.services.electrs.port ];
```
You can use the same approach to allow connections to other services.
# Migrate existing services to nix-bitcoin
## Example: bitcoind
```shell
# 1. Stop bitcoind on your nodes
ssh root@nix-bitcoin-node 'systemctl stop bitcoind'
# Also stop bitcoind on the node that you'll be copying data from
# 2. Copy the data to the nix-bitcoin node
# Important: Add a trailing slash to the source path
rsync /path/to/existing/bitcoind-datadir/ root@nix-bitcoin-node:/var/lib/bitcoind
# 3. Fix data dir permissions on the nix-bitcoin node
ssh root@nix-bitcoin-node 'chown -R bitcoin: /var/lib/bitcoind'
# 4. Start bitcoind
ssh root@nix-bitcoin-node 'systemctl start bitcoind'
```
You can use the same workflow for other services.\
The default data dir path is `/var/lib/<service>` for all services.
Some services require extra steps:
- lnd
Copy your wallet password to `$secretsDir/lnd-wallet-password` (See: [Secrets dir](#secrets-dir)).
- btcpayserver
Copy the postgresql database:
```shell
# Export (on the other node)
sudo -u postgres pg_dump YOUR_BTCPAYSERVER_DB > export.sql
# Restore (on the nix-bitcoin node)
sudo -u postgres psql btcpaydb < export.sql
```
- joinmarket
Copy your wallet to `/var/lib/joinmarket/wallets/wallet.jmdat`.\
Write your wallet password, without a trailing newline, to
`$secretsDir/jm-wallet-password` (See: [Secrets dir](#secrets-dir)).
# Use bitcoind from another node
Use a bitcoind instance running on another node within a nix-bitcoin config.
```nix
services.bitcoind = {
# Address of the other node
address = "10.10.0.2";
rpc.users = let
# The fully privileged bitcoind RPC username of the other node
name = "myrpcuser";
in {
privileged.name = name;
public.name = name;
## Set this if you use btcpayserver
# btcpayserver.name = name;
## Set this if you use joinmarket-ob-watcher
# joinmarket-ob-watcher.name = name;
};
};
# Disable the local bitcoind service
systemd.services.bitcoind.wantedBy = mkForce [];
```
Now save the password of the RPC user to the following files on your nix-bitcoin node:
```shell
$secretsDir/bitcoin-rpcpassword-privileged
$secretsDir/bitcoin-rpcpassword-public
## Only needed when set in the above config snippet
# $secretsDir/bitcoin-rpcpassword-btcpayserver
# $secretsDir/bitcoin-rpcpassword-joinmarket-ob-watcher
```
See: [Secrets dir](#secrets-dir)
# Temporarily disable a service
Sometimes you might want to disable a service without removing the service user and
integration with other services, as it would happen when setting
`services.<service>.enable = false`.
Use the following approach:
```
systemd.services.<service>.wantedBy = mkForce [];
```
This way, the systemd service still exists, but is not automatically started.
# Appendix
## Secrets dir
The secrets dir is set by option `nix-bitoin.secretsDir` and has the
following default values:
- If you're using the krops deployment method: `/var/src/secrets`
- Otherwise:
- `/secrets` (if you're using the `secure-node.nix` template)
- `/etc/nix-bitcoin-secrets` (otherwise)
`/secrets` only exists to provide backwards compatibility for users of the
`secure-node.nix` template.

View File

@ -1,6 +1,19 @@
* **Q:** The clightning service is running but when I try to use it (f.e. by running `lightning-cli getinfo` as user operator) all I get is `lightning-cli: Connecting to 'lightning-rpc': Connection refused`.
* **A:** Check your clightning logs with `journalctl -eu clightning`. Do you see something like `bitcoin-cli getblock ... false` failed? Are you using pruned mode? That means that clightning hasn't seen all the blocks it needs to and it can't get that block because your node is pruned. If you're just setting up a new node you can `systemctl stop clightning` and wipe your `/var/lib/clightning` directory. Otherwise you need to reindex the Bitcoin node.
* **Q:** My disk space is getting low due to nix.
* **A:** run `nix-collect-garbage -d`
* **Q:** Where is `sudo`???
* **A:** we replaced sudo with OpenBSD's doas after [CVE-2021-3156](https://www.openwall.com/lists/oss-security/2021/01/26/3). It has greatly reduced complexity, and is therefore less likely to be a source of severe vulnerabilities in the future.
- **Q:** The clightning service is running but when I try to use it (f.e. by running
`lightning-cli getinfo` as user operator) all I get is `lightning-cli: Connecting
to 'lightning-rpc': Connection refused`.\
**A:** Check your clightning logs with `journalctl -eu clightning`. Do you see
something like `bitcoin-cli getblock ... false` failed? Are you using pruned mode?
That means that clightning hasn't seen all the blocks it needs to and it can't get
that block because your node is pruned. \
If you're just setting up a new node you can `systemctl stop clightning` and wipe
your `/var/lib/clightning` directory. Otherwise you need to reindex the Bitcoin
node.
- **Q:** My disk space is getting low due to nix.\
**A:** run `nix-collect-garbage -d`
- **Q:** Where is `sudo`?\
**A:** After [CVE-2021-3156](https://www.openwall.com/lists/oss-security/2021/01/26/3),
we've replaced `sudo` with OpenBSD's `doas` for users of the `secure-node.nix` template.
It has greatly reduced complexity and is therefore less likely to be a source of
severe vulnerabilities in the future.

View File

@ -329,4 +329,7 @@ You can also build Nix from source by following the instructions at https://nixo
For security reasons, all normal system management tasks can and should be performed with the `operator` user. Logging in as `root` should be done as rarely as possible.
See [usage.md](usage.md) for usage instructions, such as how to update.
See also:
- [Migrating existing services to bitcoind](configuration.md#migrate-existing-services-to-nix-bitcoin)
- [Managing your deployment](configuration.md#managing-your-deployment)
- [Using services](services.md)

View File

@ -1,18 +1,32 @@
Updating
---
In your deployment directory, enter the nix shell with `nix-shell` and run the
following to update `nix-bitcoin-release.nix`:
```
update-nix-bitcoin
```
Nodeinfo
---
# Nodeinfo
Run `nodeinfo` to see onion addresses and local addresses for enabled services.
Connect to RTL
---
# Managing services
NixOS uses the [systemd](https://wiki.archlinux.org/title/systemd) service manager.
Usage:
```shell
# Show service status
systemctl status bitcoind
# Show the last 100 log messages
journalctl -u bitcoind -n 100
# Show all log messages since the last system boot
journalctl -b -u bitcoind
# These commands require root permissions
systemctl stop bitcoind
systemctl start bitcoind
systemctl restart bitcoind
# Show the service definition
systemctl cat bitcoind
# Show all service parameters
systemctl show bitcoind
```
# Connect to RTL
Normally you would connect to RTL via SSH tunneling with a command like this
```
@ -29,8 +43,7 @@ Otherwise, you can access it via Tor Browser at `http://<onion-address>`.
You can find the `<onion-address>` with command `nodeinfo`.
The default password location is `/secrets/rtl-password`.
Connect to spark-wallet
---
# Connect to spark-wallet
### Requirements
* Android phone
* [Orbot](https://guardianproject.info/apps/orbot/) installed from [F-Droid](https://guardianproject.info/fdroid) (recommended) or [Google Play](https://play.google.com/store/apps/details?id=org.torproject.android&hl=en)
@ -73,8 +86,7 @@ Connect to spark-wallet
Done
```
Connect to LND with Zeus
---
# Connect to LND with Zeus
### Requirements
* Android phone
* [Orbot](https://guardianproject.info/apps/orbot/) installed from
@ -110,8 +122,7 @@ Connect to LND with Zeus
5. Scan the QR code with your Zeus wallet and start sending Satoshis privately
Connect to electrs
---
# Connect to electrs
### Requirements Android
* Android phone
* [Orbot](https://guardianproject.info/apps/orbot/) installed from [F-Droid](https://guardianproject.info/fdroid) (recommended) or [Google Play](https://play.google.com/store/apps/details?id=org.torproject.android&hl=en)
@ -158,8 +169,7 @@ Connect to electrs
Network > Server: <electrs onion address>:t
```
Connect to nix-bitcoin node through the SSH onion service
---
# Connect to nix-bitcoin node through the SSH onion service
1. Get the SSH onion address (excluding the port suffix)
```
@ -195,8 +205,7 @@ Connect to nix-bitcoin node through the SSH onion service
6. After deploying the new configuration, it will connect through the SSH tunnel you established in step iv. This also allows you to do more complex SSH setups that some deployment tools don't support. An example would be authenticating with [Trezor's SSH agent](https://github.com/romanz/trezor-agent), which provides extra security.
Initialize a Trezor for Bitcoin Core's Hardware Wallet Interface
---
# Initialize a Trezor for Bitcoin Core's Hardware Wallet Interface
1. Enable Trezor in `configuration.nix`
@ -258,8 +267,7 @@ Initialize a Trezor for Bitcoin Core's Hardware Wallet Interface
8. Follow Bitcoin Core's instructions on [Using Bitcoin Core with Hardware Wallets](https://github.com/bitcoin-core/HWI/blob/master/docs/bitcoin-core-usage.md) to use your Trezor with `bitcoin-cli` on your nix-bitcoin node
JoinMarket
---
# JoinMarket
## Diff to regular JoinMarket usage
@ -380,8 +388,7 @@ See [here](https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master
3. Profit
clightning
---
# clightning
## Plugins

View File

@ -16,7 +16,7 @@
# See the comments at the top of `hardened-extended.nix` for further details.
# <nix-bitcoin/modules/presets/hardened-extended.nix>
# FIXME: Uncomment next line to import your hardware configuration. If so,
# FIXME: Uncomment the next line to import your hardware configuration. If so,
# add the hardware configuration file to the same directory as this file.
#./hardware-configuration.nix
];
@ -145,22 +145,6 @@
#
# Liquid can be controlled with command 'elements-cli'.
### RECURRING-DONATIONS
# Set this to enable recurring donations. This is EXPERIMENTAL; it's
# not guaranteed that payments are succeeding or that you will notice payment
# failure.
# services.recurring-donations.enable = true;
# This automatically enables clightning.
#
# Specify the receivers of the donations. By default donations are every
# Monday at a randomized time. Check `journalctl -eu recurring-donations` or
# `lightning-cli listpayments` for successful lightning donations.
# services.recurring-donations.tallycoin = {
# "<receiver name>" = <amount you wish to donate in sat>"
# "<additional receiver name>" = <amount you wish to donate in sat>;
# "djbooth007" = 1000;
# };
### Hardware wallets
# Enable the following to allow using hardware wallets.
# See https://github.com/bitcoin-core/HWI for more information.

View File

@ -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 {
@ -206,6 +206,11 @@ let
Value 0 disables pruning.
'';
};
txindex = mkOption {
type = types.bool;
default = false;
description = "Enable the transaction index.";
};
zmqpubrawblock = mkOption {
type = types.nullOr types.str;
default = null;
@ -262,7 +267,7 @@ let
'';
description = "Binary to connect with the bitcoind instance.";
};
enforceTor = nbLib.enforceTor;
tor = nbLib.tor;
};
};
@ -284,6 +289,7 @@ let
''}
${optionalString (cfg.dbCache != null) "dbcache=${toString cfg.dbCache}"}
prune=${toString cfg.prune}
${optionalString cfg.txindex "txindex=1"}
${optionalString (cfg.sysperms != null) "sysperms=${if cfg.sysperms then "1" else "0"}"}
${optionalString (cfg.disablewallet != null) "disablewallet=${if cfg.disablewallet then "1" else "0"}"}
${optionalString (cfg.assumevalid != null) "assumevalid=${cfg.assumevalid}"}
@ -407,7 +413,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;
};

View File

@ -3,45 +3,6 @@
with lib;
let
options.services = {
nbxplorer = {
package = mkOption {
type = types.package;
default = nbPkgs.nbxplorer;
description = "The package providing nbxplorer binaries.";
};
address = mkOption {
type = types.str;
default = "127.0.0.1";
description = "Address to listen on.";
};
port = mkOption {
type = types.port;
default = 24444;
description = "Port to listen on.";
};
dataDir = mkOption {
type = types.path;
default = "/var/lib/nbxplorer";
description = "The data directory for nbxplorer.";
};
user = mkOption {
type = types.str;
default = "nbxplorer";
description = "The user as which to run nbxplorer.";
};
group = mkOption {
type = types.str;
default = cfg.nbxplorer.user;
description = "The group as which to run nbxplorer.";
};
enable = mkOption {
# This option is only used by netns-isolation
internal = true;
default = cfg.btcpayserver.enable;
};
enforceTor = nbLib.enforceTor;
};
btcpayserver = {
enable = mkEnableOption "btcpayserver";
address = mkOption {
@ -93,7 +54,49 @@ let
default = cfg.btcpayserver.user;
description = "The group as which to run btcpayserver.";
};
enforceTor = nbLib.enforceTor;
tor.enforce = nbLib.tor.enforce;
};
nbxplorer = {
enable = mkOption {
# This option is only used by netns-isolation
internal = true;
default = cfg.btcpayserver.enable;
description = ''
nbxplorer is always enabled when btcpayserver is enabled.
'';
};
package = mkOption {
type = types.package;
default = nbPkgs.nbxplorer;
description = "The package providing nbxplorer binaries.";
};
address = mkOption {
type = types.str;
default = "127.0.0.1";
description = "Address to listen on.";
};
port = mkOption {
type = types.port;
default = 24444;
description = "Port to listen on.";
};
dataDir = mkOption {
type = types.path;
default = "/var/lib/nbxplorer";
description = "The data directory for nbxplorer.";
};
user = mkOption {
type = types.str;
default = "nbxplorer";
description = "The user as which to run nbxplorer.";
};
group = mkOption {
type = types.str;
default = cfg.nbxplorer.user;
description = "The group as which to run nbxplorer.";
};
tor.enforce = nbLib.tor.enforce;
};
};
@ -182,11 +185,11 @@ in {
RestartSec = "10s";
ReadWritePaths = cfg.nbxplorer.dataDir;
MemoryDenyWriteExecute = "false";
} // nbLib.allowedIPAddresses cfg.nbxplorer.enforceTor;
} // nbLib.allowedIPAddresses cfg.nbxplorer.tor.enforce;
};
systemd.services.btcpayserver = let
nbExplorerUrl = "http://${cfg.nbxplorer.address}:${toString cfg.nbxplorer.port}/";
nbExplorerUrl = "http://${nbLib.addressWithPort cfg.nbxplorer.address cfg.nbxplorer.port}/";
nbExplorerCookie = "${cfg.nbxplorer.dataDir}/${bitcoind.makeNetworkName "Main" "RegTest"}/.cookie";
configFile = builtins.toFile "config" (''
network=${bitcoind.network}
@ -196,7 +199,8 @@ in {
btcexplorerurl=${nbExplorerUrl}
btcexplorercookiefile=${nbExplorerCookie}
postgres=User ID=${cfg.btcpayserver.user};Host=/run/postgresql;Database=btcpaydb
${optionalString (cfg.btcpayserver.rootpath != null) "rootpath=${cfg.btcpayserver.rootpath}"}
'' + optionalString (cfg.btcpayserver.rootpath != null) ''
rootpath=${cfg.btcpayserver.rootpath}
'' + optionalString (cfg.btcpayserver.lightningBackend == "clightning") ''
btclightning=type=clightning;server=unix:///${cfg.clightning.dataDir}/bitcoin/lightning-rpc
'' + optionalString cfg.btcpayserver.lbtc ''
@ -234,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} = {

View File

@ -9,7 +9,9 @@ let cfg = config.services.clightning.plugins.clboss; in
type = types.ints.positive;
default = 30000;
description = ''
Specify target amount (in satoshi) that CLBOSS will leave onchain.
Target amount (in satoshi) that CLBOSS will leave on-chain.
clboss will only open new channels if this amount is smaller than
the funds in your clightning wallet.
'';
};
package = mkOption {
@ -26,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);
};
}

View File

@ -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.
@ -43,7 +43,16 @@ let
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Extra lines appended to the configuration file.";
example = ''
alias=mynode
'';
description = ''
Extra lines appended to the configuration file.
See all available options at
https://github.com/ElementsProject/lightning/blob/master/doc/lightningd-config.5.md
or by running `lightningd --help`.
'';
};
user = mkOption {
type = types.str;
@ -70,7 +79,7 @@ let
If left empty, no address is announced.
'';
};
inherit (nbLib) enforceTor;
tor = nbLib.tor;
};
cfg = config.services.clightning;
@ -88,6 +97,7 @@ let
bitcoin-rpcport=${toString config.services.bitcoind.rpc.port}
bitcoin-rpcuser=${config.services.bitcoind.rpc.users.public.name}
rpc-file-mode=0660
log-timestamps=false
${cfg.extraConfig}
'';
@ -123,13 +133,14 @@ in {
preStart = ''
# The RPC socket has to be removed otherwise we might have stale sockets
rm -f ${cfg.networkDir}/lightning-rpc
install -m 640 ${configFile} '${cfg.dataDir}/config'
umask u=rw,g=r,o=
{
cat ${configFile}
echo "bitcoin-rpcpassword=$(cat ${config.nix-bitcoin.secretsDir}/bitcoin-rpcpassword-public)"
${optionalString (cfg.getPublicAddressCmd != "") ''
echo "announce-addr=$(${cfg.getPublicAddressCmd}):${toString publicPort}"
''}
} >> '${cfg.dataDir}/config'
} > '${cfg.dataDir}/config'
'';
serviceConfig = nbLib.defaultHardening // {
ExecStart = "${nbPkgs.clightning}/bin/lightningd --lightning-dir=${cfg.dataDir}";
@ -145,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

View File

@ -8,7 +8,6 @@
presets.secure-node = ./presets/secure-node.nix;
rtl = ./rtl.nix;
spark-wallet = ./spark-wallet.nix;
recurring-donations = ./recurring-donations.nix;
lnd = ./lnd.nix;
charge-lnd = ./charge-lnd.nix;
joinmarket = ./joinmarket.nix;

View File

@ -12,7 +12,7 @@ let
port = mkOption {
type = types.port;
default = 50001;
description = "RPC port.";
description = "Port to listen for RPC connections.";
};
dataDir = mkOption {
type = types.path;
@ -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;
@ -74,10 +74,8 @@ in {
> electrs.toml
'';
serviceConfig = nbLib.defaultHardening // {
RuntimeDirectory = "electrs";
RuntimeDirectoryMode = "700";
# electrs only uses the working directory for reading electrs.toml
WorkingDirectory = "/run/electrs";
WorkingDirectory = cfg.dataDir;
ExecStart = ''
${config.nix-bitcoin.pkgs.electrs}/bin/electrs \
--log-filters=INFO \
@ -95,7 +93,7 @@ in {
Restart = "on-failure";
RestartSec = "10s";
ReadWritePaths = cfg.dataDir;
} // nbLib.allowedIPAddresses cfg.enforceTor;
} // nbLib.allowedIPAddresses cfg.tor.enforce;
};
users.users.${cfg.user} = {

View File

@ -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} = {

View File

@ -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} = {

View File

@ -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 = {

View File

@ -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
};
};

View File

@ -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} = {

View File

@ -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} = {

View File

@ -12,20 +12,19 @@
./bitcoind.nix
./clightning.nix
./clightning-plugins
./rtl.nix
./spark-wallet.nix
./lnd.nix
./lnd-rest-onion-service.nix # Requires onion-addresses.nix
./lightning-loop.nix
./lightning-pool.nix
./charge-lnd.nix
./rtl.nix
./electrs.nix
./liquid.nix
./btcpayserver.nix
./joinmarket.nix
./joinmarket-ob-watcher.nix
./hardware-wallets.nix
./recurring-donations.nix
# Support features
./versioning.nix

View File

@ -70,7 +70,8 @@ let
# and
# availableNetns.clighting = [ "bitcoind" ];
#
# FIXME: Although negligible for our purposes, this calculation's runtime
# TODO-EXTERNAL:
# Although negligible for our purposes, this calculation's runtime
# is in the order of (number of connections * number of services),
# because attrsets and lists are fully copied on each update with '//' or '++'.
# This can only be improved with an update in the nix language.
@ -156,7 +157,9 @@ in {
peer = "nb-veth-br-${toString v.id}";
inherit (v) netnsName;
nsenter = "${pkgs.utillinux}/bin/nsenter";
allowedAddresses = concatMapStringsSep "," (available: netns.${available}.address) v.availableNetns;
allowedNetnsAddresses = map (available: netns.${available}.address) v.availableNetns;
allowedAddresses = concatStringsSep ","
([ "127.0.0.1,${bridgeIp},${v.address}" ] ++ allowedNetnsAddresses);
setup = ''
${ip} netns add ${netnsName}
@ -176,17 +179,13 @@ in {
${ip} route add default via ${bridgeIp}
${iptables} -w -P INPUT DROP
${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) ''
${iptables} -w -P OUTPUT DROP
${iptables} -w -A OUTPUT -d 127.0.0.1,${bridgeIp},${v.address} -j ACCEPT
'' + optionalString (v.availableNetns != []) ''
${iptables} -w -A INPUT -s ${allowedAddresses} -j ACCEPT
'' + optionalString (config.services.${n}.tor.enforce or false) ''
${iptables} -w -P OUTPUT DROP
${iptables} -w -A OUTPUT -d ${allowedAddresses} -j ACCEPT
'';
script = name: src: pkgs.writers.writeDash name ''
set -e
${src}
@ -246,10 +245,6 @@ in {
id = 17;
# communicates with clightning over lightning-rpc socket
};
recurring-donations = {
id = 20;
# communicates with clightning over lightning-rpc socket
};
nginx = {
id = 21;
};
@ -336,14 +331,16 @@ in {
payjoinAddress = netns.joinmarket.address;
cliExec = mkCliExec "joinmarket";
};
systemd.services.joinmarket-yieldgenerator.serviceConfig.NetworkNamespacePath = "/var/run/netns/nb-joinmarket";
systemd.services.joinmarket-yieldgenerator = mkIf config.services.joinmarket.yieldgenerator.enable {
serviceConfig.NetworkNamespacePath = "/var/run/netns/nb-joinmarket";
};
services.joinmarket-ob-watcher.address = netns.joinmarket-ob-watcher.address;
services.lightning-pool.rpcAddress = netns.lightning-pool.address;
services.rtl.address = netns.rtl.address;
systemd.services.cl-rest = {
systemd.services.cl-rest = mkIf config.services.rtl.cl-rest.enable {
serviceConfig.NetworkNamespacePath = "/var/run/netns/nb-rtl";
requires = [ "netns-rtl.service" ] ;
after = [ "netns-rtl.service" ];

View File

@ -35,7 +35,7 @@ with lib;
runAsUserCmd = mkOption {
readOnly = true;
default = if config.security.doas.enable
# TODO: Use absolute path until https://github.com/NixOS/nixpkgs/pull/133622 is available.
# TODO-EXTERNAL: Use absolute path until https://github.com/NixOS/nixpkgs/pull/133622 is available.
then "/run/wrappers/bin/doas -u"
else "sudo -u";
};

View File

@ -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"
]);
}

View File

@ -58,8 +58,20 @@ in {
CapabilityBoundingSet = "CAP_CHOWN CAP_FSETID CAP_SETFCAP CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER CAP_IPC_OWNER";
};
script = ''
waitForFile() {
file=$1
for ((i=0; i<300; i++)); do
if [[ -e $file ]]; then
return;
fi
sleep 0.1
done
echo "Error: File $file did not appear after 30 sec."
exit 1
}
# Wait until tor is up
until [[ -e /var/lib/tor/state ]]; do sleep 0.1; done
waitForFile /var/lib/tor/state
cd ${cfg.dataDir}
rm -rf *
@ -71,22 +83,20 @@ in {
${concatMapStrings
(service: ''
onionFile=/var/lib/tor/onion/${service}/hostname
if [[ -e $onionFile ]]; then
cp $onionFile ${user}/${service}
chown ${user} ${user}/${service}
fi
waitForFile $onionFile
cp $onionFile ${user}/${service}
chown ${user} ${user}/${service}
'')
cfg.access.${user}
}
}
'')
(builtins.attrNames cfg.access)
}
${concatMapStrings (service: ''
onionFile=/var/lib/tor/onion/${service}/hostname
if [[ -e $onionFile ]]; then
install -D -o ${config.systemd.services.${service}.serviceConfig.User} -m 400 $onionFile services/${service}
fi
waitForFile $onionFile
install -D -o ${config.systemd.services.${service}.serviceConfig.User} -m 400 $onionFile services/${service}
'') cfg.services}
'';
};

View File

@ -1,27 +1,43 @@
{ 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;
# TODO-EXTERNAL:
# disable Tor enforcement until btcpayserver can fetch rates over Tor
# btcpayserver.enforceTor = true;
nbxplorer.enforceTor = true;
spark-wallet.enforceTor = true;
recurring-donations.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

View File

@ -1,107 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
options.services.recurring-donations = {
enable = mkEnableOption "recurring-donations";
tallycoin = mkOption {
type = types.attrs;
default = {};
description = ''
This option is used to specify tallycoin donation receivers using an
attribute set. For example the following setting instructs the module
to repeatedly send 1000 satoshis to djbooth007.
{
"djbooth007" = 1000;
}
'';
};
interval = mkOption {
type = types.str;
default = "Mon *-*-* 00:00:00";
description = ''
Schedules the donations. Default is weekly on Mon 00:00:00. See `man
systemd.time` for further options.
'';
};
randomizedDelaySec = mkOption {
type = types.int;
default = 86400;
description = ''
Random delay to add to scheduled time for donation. Default is one day.
'';
};
enforceTor = nbLib.enforceTor;
};
cfg = config.services.recurring-donations;
nbLib = config.nix-bitcoin.lib;
recurring-donations-script = pkgs.writeScript "recurring-donations.sh" ''
LNCLI="${config.nix-bitcoin.pkgs.clightning}/bin/lightning-cli --lightning-dir=${config.services.clightning.dataDir}"
pay_tallycoin() {
NAME=$1
AMOUNT=$2
echo "Attempting to pay $AMOUNT sat to $NAME"
INVOICE=$(curl --socks5-hostname ${config.nix-bitcoin.torClientAddressWithPort} -d "satoshi_amount=$AMOUNT&payment_method=ln&id=$NAME&type=profile" -X POST https://api.tallyco.in/v1/payment/request/ | jq -r '.lightning_pay_request') 2> /dev/null
if [ -z "$INVOICE" ] || [ "$INVOICE" = "null" ]; then
echo "ERROR: did not get invoice from tallycoin"
return
fi
# Decode invoice and compare amount with requested amount
DECODED_AMOUNT=$($LNCLI decodepay "$INVOICE" | jq -r '.amount_msat' | head -c -8)
if [ -z "$DECODED_AMOUNT" ] || [ "$DECODED_AMOUNT" = "null" ]; then
echo "ERROR: did not get response from clightning"
return
fi
if [ $DECODED_AMOUNT -eq $AMOUNT ]; then
echo "Paying with invoice $INVOICE"
$LNCLI pay "$INVOICE"
else
echo "ERROR: requested amount and invoice amount do not match. $AMOUNT vs $DECODED_AMOUNT"
return
fi
}
${ builtins.foldl'
(x: receiver: x +
''
pay_tallycoin ${receiver} ${toString (builtins.getAttr receiver cfg.tallycoin)}
'')
""
(builtins.attrNames cfg.tallycoin)
}
'';
in {
inherit options;
config = mkIf cfg.enable {
services.clightning.enable = true;
systemd.services.recurring-donations = {
requires = [ "clightning.service" ];
after = [ "clightning.service" ];
path = with pkgs; [ nix-bitcoin.clightning curl jq ];
serviceConfig = nbLib.defaultHardening // {
ExecStart = "${pkgs.bash}/bin/bash ${recurring-donations-script}";
User = "recurring-donations";
Type = "oneshot";
} // nbLib.allowedIPAddresses cfg.enforceTor;
};
systemd.timers.recurring-donations = {
requires = [ "clightning.service" ];
after = [ "clightning.service" ];
timerConfig = {
Unit = "recurring-donations.service";
OnCalendar = cfg.interval;
RandomizedDelaySec = toString cfg.randomizedDelaySec;
};
wantedBy = [ "multi-user.target" ];
};
users.users.recurring-donations = {
isSystemUser = true;
group = "recurring-donations";
extraGroups = [ config.services.clightning.group ];
};
users.groups.recurring-donations = {};
};
}

View File

@ -23,12 +23,12 @@ let
clightning = mkOption {
type = types.bool;
default = false;
description = "Add a node interface for clightning.";
description = "Enable the clightning node interface.";
};
lnd = mkOption {
type = types.bool;
default = false;
description = "Add a node interface for lnd.";
description = "Enable the lnd node interface.";
};
reverseOrder = mkOption {
type = types.bool;
@ -49,11 +49,36 @@ let
default = false;
description = "Enable the Night UI Theme.";
};
extraCurrency = mkOption {
type = with types; nullOr str;
default = null;
example = "USD";
description = ''
Currency code (ISO 4217) of the extra currency used for displaying balances.
When set, this option enables online currency rate fetching.
Warning: Rate fetching requires outgoing clearnet connections, so option
`tor.enforce` is automatically disabled.
'';
};
user = mkOption {
type = types.str;
default = "rtl";
description = "The user as which to run RTL.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run RTL.";
};
cl-rest = {
enable = mkOption {
readOnly = true;
type = types.bool;
default = cfg.nodes.clightning;
description = "Enable c-lightning-REST server.";
description = ''
Enable c-lightning-REST server. This service is required for
clightning support and is automatically enabled.
'';
};
address = mkOption {
readOnly = true;
@ -75,17 +100,7 @@ let
description = "Swagger API documentation server port.";
};
};
user = mkOption {
type = types.str;
default = "rtl";
description = "The user as which to run RTL.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run RTL.";
};
inherit (nbLib) enforceTor;
tor.enforce = nbLib.tor.enforce;
};
cfg = config.services.rtl;
@ -114,7 +129,10 @@ let
''"channelBackupPath": "${cfg.dataDir}/backup/lnd",''
}
"logLevel": "INFO",
"fiatConversion": false,
"fiatConversion": ${if cfg.extraCurrency == null then "false" else "true"},
${optionalString (cfg.extraCurrency != null)
''"currencyUnit": "${cfg.extraCurrency}",''
}
${optionalString (isLnd && cfg.loop)
''"swapServerUrl": "https://${nbLib.addressWithPort lightning-loop.restAddress lightning-loop.restPort}",''
}
@ -186,6 +204,8 @@ in {
"d '${cfg.dataDir}' 0770 ${cfg.user} ${cfg.group} - -"
];
services.rtl.tor.enforce = mkIf (cfg.extraCurrency != null) false;
systemd.services.rtl = rec {
wantedBy = [ "multi-user.target" ];
requires = optional cfg.nodes.clightning "cl-rest.service" ++
@ -210,7 +230,7 @@ in {
Restart = "on-failure";
RestartSec = "10s";
ReadWritePaths = cfg.dataDir;
} // nbLib.allowedIPAddresses cfg.enforceTor
} // nbLib.allowedIPAddresses cfg.tor.enforce
// nbLib.nodejs;
};

View File

@ -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;
};

View File

@ -55,13 +55,20 @@ let self = {
then self.allowLocalIPAddresses
else self.allowAllIPAddresses;
enforceTor = 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;
'';
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 enforce Tor on a service by only allowing connections
from and to localhost and link-local addresses.
'';
};
};
script = name: src: pkgs.writers.writeBash name ''

View File

@ -13,7 +13,7 @@ buildPythonPackage rec {
postUnpack = "sourceRoot=$sourceRoot/contrib/pyln-spec/bolt7";
# TODO-EXTERNAL
# TODO-EXTERNAL:
# Remove when this fix is released
# https://github.com/ElementsProject/lightning/pull/4910
postPatch = ''

View File

@ -67,6 +67,7 @@ let
nix-bitcoin.generateSecretsCmds.rtl = mkIf cfg.rtl.enable (mkForce ''
echo a > rtl-password
'');
services.rtl.extraCurrency = mkDefault "CHF";
tests.spark-wallet = cfg.spark-wallet.enable;

View File

@ -375,7 +375,6 @@ def _():
num_blocks = test_data["num_blocks"]
if enabled("electrs"):
machine.wait_for_unit("onion-addresses")
machine.wait_until_succeeds(log_has_string("electrs", "serving Electrum RPC"))
get_block_height_cmd = (
"""echo '{"method": "blockchain.headers.subscribe", "id": 0, "params": []}'"""