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: ACKdef64a73b8
jonasnick: ACKdef64a73b8
Tree-SHA512: 13acd2a3dd73c07f9c31874c8e961f12f39accb48847cbad08479b9a8154b79a6f186819272072dfb5c4768264b81f6e058e9afa57a729db2096784e48352dfd
This commit is contained in:
commit
747019a9e9
17
README.md
17
README.md
@ -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
240
docs/configuration.md
Normal 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.
|
25
docs/faq.md
25
docs/faq.md
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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} = {
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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} = {
|
||||
|
@ -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} = {
|
||||
|
@ -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
|
||||
|
@ -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" ];
|
||||
|
@ -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";
|
||||
};
|
||||
|
@ -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"
|
||||
]);
|
||||
}
|
||||
|
@ -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}
|
||||
'';
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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 = {};
|
||||
};
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
21
pkgs/lib.nix
21
pkgs/lib.nix
@ -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 ''
|
||||
|
@ -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 = ''
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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": []}'"""
|
||||
|
Loading…
Reference in New Issue
Block a user