lndconnect: add clnrest
This commit is contained in:
parent
87b929bc99
commit
daa3bfbae3
9 changed files with 171 additions and 29 deletions
|
|
@ -66,6 +66,16 @@ with lib;
|
|||
onion = true;
|
||||
};
|
||||
};
|
||||
services.clightning = {
|
||||
enable = true;
|
||||
plugins.clnrest = {
|
||||
enable = true;
|
||||
lnconnect = {
|
||||
enable = true;
|
||||
onion = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
services.clightning-rest = {
|
||||
enable = true;
|
||||
lndconnect = {
|
||||
|
|
|
|||
|
|
@ -7,13 +7,15 @@ run-tests.sh -s wireguard-lndconnect-online container
|
|||
# 2. Test connecting via Tor
|
||||
# Print QR codes for lnd, clightning-rest connections via Tor
|
||||
c lndconnect
|
||||
c lnconnect-clnrest
|
||||
c lndconnect-clightning
|
||||
# Add these to Zeus >= 0.7.1.
|
||||
# Add these to Zeus >= 0.9.0.
|
||||
# To explicitly check if the connection is successful, press the node logo in the top
|
||||
# left corner, and then "Node Info".
|
||||
|
||||
# Debug
|
||||
c lndconnect --url
|
||||
c lnconnect-clnrest --url
|
||||
c lndconnect-clightning --url
|
||||
|
||||
# 3. Test connecting via WireGuard
|
||||
|
|
@ -33,13 +35,15 @@ c nix-bitcoin-wg-connect --text
|
|||
|
||||
# Print QR codes for lnd, clightning-rest connections via WireGuard
|
||||
c lndconnect-wg
|
||||
c lnconnect-clnrest-wg
|
||||
c lndconnect-clightning-wg
|
||||
# Add these to Zeus >= 0.7.1.
|
||||
# To explicitly check if the connection is successful, press the node logo in the top
|
||||
# Add these to Zeus >= 0.9.0.
|
||||
# To explicitly check if the connection is successful, press the menu button in the top
|
||||
# left corner, and then "Node Info".
|
||||
|
||||
# Debug
|
||||
c lndconnect-wg --url
|
||||
c lnconnect-clnrest-wg --url
|
||||
c lndconnect-clightning-wg --url
|
||||
|
||||
# 3.3.remove external firewall port forward, remove local port forward:
|
||||
|
|
@ -55,6 +59,8 @@ c nodeinfo
|
|||
|
||||
c lndconnect --url
|
||||
c lndconnect-wg --url
|
||||
c lndconnect-clnrest --url
|
||||
c lndconnect-clnrest-wg --url
|
||||
c lndconnect-clightning --url
|
||||
c lndconnect-clightning-wg --url
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ The default password location is `$secretsDir/rtl-password`.
|
|||
See: [Secrets dir](./configuration.md#secrets-dir)
|
||||
|
||||
# Use Zeus (mobile lightning wallet) via Tor
|
||||
1. Install [Zeus](https://zeusln.app) (version ≥ 0.7.1)
|
||||
1. Install [Zeus](https://zeusln.app) (version ≥ 0.9.0)
|
||||
|
||||
2. Edit your `configuration.nix`
|
||||
|
||||
|
|
@ -161,9 +161,9 @@ See: [Secrets dir](./configuration.md#secrets-dir)
|
|||
|
||||
Add the following config:
|
||||
```nix
|
||||
services.clightning-rest = {
|
||||
services.clightning.plugins.clnrest = {
|
||||
enable = true;
|
||||
lndconnect = {
|
||||
lnconnect = {
|
||||
enable = true;
|
||||
onion = true;
|
||||
};
|
||||
|
|
@ -182,7 +182,7 @@ See: [Secrets dir](./configuration.md#secrets-dir)
|
|||
|
||||
##### For clightning
|
||||
```
|
||||
lndconnect-clightning
|
||||
lnconnect-clnrest
|
||||
```
|
||||
|
||||
5. Configure Zeus
|
||||
|
|
@ -212,7 +212,7 @@ There are two ways to establish a secure, direct connection:
|
|||
- Connecting via WireGuard. This approach is simpler and more versatile, and is
|
||||
described in this guide.
|
||||
|
||||
1. Install [Zeus](https://zeusln.app) (version ≥ 0.7.1) and
|
||||
1. Install [Zeus](https://zeusln.app) (version ≥ 0.9.0) and
|
||||
[WireGuard](https://www.wireguard.com/install/) on your mobile device.
|
||||
|
||||
2. Add the following to your `configuration.nix`:
|
||||
|
|
@ -229,9 +229,11 @@ There are two ways to establish a secure, direct connection:
|
|||
services.lnd.lndconnect.enable = true;
|
||||
|
||||
# For clightning
|
||||
services.clightning-rest = {
|
||||
enable = true;
|
||||
lndconnect.enable = true;
|
||||
services.clightning = {
|
||||
plugins.clnrest = {
|
||||
enable = true;
|
||||
lnconnect.enable = true;
|
||||
};
|
||||
};
|
||||
```
|
||||
3. Deploy your configuration.
|
||||
|
|
@ -275,7 +277,7 @@ There are two ways to establish a secure, direct connection:
|
|||
|
||||
##### For clightning
|
||||
```
|
||||
lndconnect-clightning-wg
|
||||
lnconnect-clnrest-wg
|
||||
```
|
||||
|
||||
Configure Zeus:
|
||||
|
|
|
|||
|
|
@ -56,15 +56,15 @@
|
|||
#
|
||||
# == REST server
|
||||
# Set this to create a clightning REST onion service.
|
||||
# This also adds binary `lndconnect-clightning` to the system environment.
|
||||
# This also adds binary `lnconnect-clnrest` to the system environment.
|
||||
# This binary creates QR codes or URLs for connecting applications to clightning
|
||||
# via the REST onion service.
|
||||
# You can also connect via WireGuard instead of Tor.
|
||||
# See ../docs/services.md for details.
|
||||
#
|
||||
# services.clightning-rest = {
|
||||
# services.clightning.plugins.clnrest = {
|
||||
# enable = true;
|
||||
# lndconnect = {
|
||||
# lnconnect = {
|
||||
# enable = true;
|
||||
# onion = true;
|
||||
# };
|
||||
|
|
|
|||
|
|
@ -32,6 +32,34 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
services.clightning.plugins.clnrest.lnconnect = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Add a `lnconnect-clnrest` binary to the system environment which prints
|
||||
connection info for clightning clients.
|
||||
See: https://github.com/LN-Zap/lndconnect
|
||||
|
||||
Usage:
|
||||
```bash
|
||||
# Print QR code
|
||||
lnconnect-clnrest
|
||||
|
||||
# Print URL
|
||||
lnconnect-clnrest --url
|
||||
```
|
||||
'';
|
||||
};
|
||||
onion = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Create an onion service for the clnrest server,
|
||||
which is used by lnconnect.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
services.clightning-rest.lndconnect = {
|
||||
enable = mkOption {
|
||||
|
|
@ -77,14 +105,18 @@ let
|
|||
|
||||
inherit (config.services)
|
||||
lnd
|
||||
clightning
|
||||
clightning-rest;
|
||||
|
||||
inherit (clightning.plugins) clnrest;
|
||||
|
||||
mkLndconnect = {
|
||||
name,
|
||||
shebang ? "#!${pkgs.stdenv.shell} -e",
|
||||
isClightning ? false,
|
||||
isClnrest ? false,
|
||||
port,
|
||||
macaroonPath,
|
||||
authSecretPath,
|
||||
enableOnion,
|
||||
onionService ? null,
|
||||
certPath ? null
|
||||
|
|
@ -99,7 +131,7 @@ let
|
|||
${optionalString enableOnion "--host=$(cat ${config.nix-bitcoin.onionAddresses.dataDir}/${onionService})"} \
|
||||
--port=${toString port} \
|
||||
${if enableOnion || certPath == null then "--nocert" else "--tlscertpath='${certPath}'"} \
|
||||
--adminmacaroonpath='${macaroonPath}' \
|
||||
--adminmacaroonpath='${authSecretPath}' \
|
||||
--configfile=/dev/null "$@"
|
||||
)
|
||||
|
||||
|
|
@ -109,7 +141,7 @@ let
|
|||
# Because `macaroon` is always the last URL fragment, the
|
||||
# sed replacement below works correctly.
|
||||
''
|
||||
macaroonHex=$(${getExe pkgs.xxd} -p -u -c 99999 '${macaroonPath}')
|
||||
macaroonHex=$(${getExe pkgs.xxd} -p -u -c 99999 '${authSecretPath}')
|
||||
url=$(
|
||||
echo "$url" | ${getExe pkgs.gnused} "
|
||||
s|^lndconnect|c-lightning-rest|
|
||||
|
|
@ -119,6 +151,18 @@ let
|
|||
''
|
||||
}
|
||||
|
||||
${optionalString isClnrest
|
||||
# Change URL procotcol to clnrest
|
||||
''
|
||||
url=$(
|
||||
echo "$url" | ${getExe pkgs.gnused} "
|
||||
s|^lndconnect|clnrest|
|
||||
s|macaroon=.*|rune=$(cat '${authSecretPath}')|
|
||||
";
|
||||
)
|
||||
''
|
||||
}
|
||||
|
||||
# If --url is in args
|
||||
if [[ " $* " =~ " --url " ]]; then
|
||||
echo "$url"
|
||||
|
|
@ -146,7 +190,7 @@ in {
|
|||
onionService = "${lnd.user}/lnd-rest";
|
||||
port = lnd.restPort;
|
||||
certPath = lnd.certPath;
|
||||
macaroonPath = "${lnd.networkDir}/admin.macaroon";
|
||||
authSecretPath = "${lnd.networkDir}/admin.macaroon";
|
||||
}
|
||||
)];
|
||||
|
||||
|
|
@ -169,6 +213,39 @@ in {
|
|||
})
|
||||
]))
|
||||
|
||||
(mkIf (clnrest.enable && clnrest.lnconnect.enable)
|
||||
(mkMerge [
|
||||
{
|
||||
environment.systemPackages = [(
|
||||
mkLndconnect {
|
||||
name = "lnconnect-clnrest";
|
||||
isClnrest = true;
|
||||
enableOnion = clnrest.lnconnect.onion;
|
||||
onionService = "${operatorName}/clnrest";
|
||||
port = clnrest.port;
|
||||
certPath = "${clightning.networkDir}/client.pem";
|
||||
authSecretPath = "${clightning.networkDir}/admin-rune";
|
||||
}
|
||||
)];
|
||||
|
||||
services.clightning.plugins.clnrest.address = mkIf (!clnrest.lnconnect.onion) "0.0.0.0";
|
||||
}
|
||||
|
||||
(mkIf clnrest.lnconnect.onion {
|
||||
services.tor = {
|
||||
enable = true;
|
||||
relay.onionServices.clnrest = nbLib.mkOnionService {
|
||||
target.addr = nbLib.address clnrest.address;
|
||||
target.port = clnrest.port;
|
||||
port = clnrest.port;
|
||||
};
|
||||
};
|
||||
# This also allows nodeinfo to show the clnrest onion address
|
||||
nix-bitcoin.onionAddresses.access.${operatorName} = [ "clnrest" ];
|
||||
})
|
||||
])
|
||||
)
|
||||
|
||||
(mkIf (clightning-rest.enable && clightning-rest.lndconnect.enable)
|
||||
(mkMerge [
|
||||
{
|
||||
|
|
@ -180,7 +257,7 @@ in {
|
|||
onionService = "${operatorName}/clightning-rest";
|
||||
port = clightning-rest.port;
|
||||
certPath = "${clightning-rest.dataDir}/certs/certificate.pem";
|
||||
macaroonPath = "${clightning-rest.dataDir}/certs/access.macaroon";
|
||||
authSecretPath = "${clightning-rest.dataDir}/certs/access.macaroon";
|
||||
}
|
||||
)];
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
# Create a WireGuard server with a single peer.
|
||||
# Private/public keys are created via the secrets system.
|
||||
# Add helper binaries `nix-bitcoin-wg-connect` and optionally `lndconnect-wg`, `lndconnect-clightning-wg`.
|
||||
# Add helper binaries `nix-bitcoin-wg-connect` and optionally `lndconnect-wg`,
|
||||
# `lnconnect-clnrest-wg`, `lndconnect-clightning-wg`.
|
||||
|
||||
# See ../../docs/services.md ("Use Zeus (mobile lightning wallet) via WireGuard")
|
||||
# for usage instructions.
|
||||
|
|
@ -33,9 +34,12 @@ let
|
|||
inherit (config.networking.wireguard.interfaces) wg-nb;
|
||||
inherit (config.services)
|
||||
lnd
|
||||
clightning
|
||||
clightning-rest;
|
||||
inherit (clightning.plugins) clnrest;
|
||||
|
||||
lndconnect = lnd.enable && lnd.lndconnect.enable;
|
||||
lnconnect-clnrest = clnrest.enable && clnrest.lnconnect.enable;
|
||||
lndconnect-clightning = clightning-rest.enable && clightning-rest.lndconnect.enable;
|
||||
|
||||
serverAddress = "${wgSubnet}.1";
|
||||
|
|
@ -150,6 +154,10 @@ in {
|
|||
(pkgs.writers.writeBashBin "lndconnect-wg" ''
|
||||
exec lndconnect --host "${serverAddress}" --nocert "$@"
|
||||
'')
|
||||
) ++ (optional lnconnect-clnrest
|
||||
(pkgs.writers.writeBashBin "lnconnect-clnrest-wg" ''
|
||||
exec lnconnect-clnrest --host "${serverAddress}" --nocert "$@"
|
||||
'')
|
||||
) ++ (optional lndconnect-clightning
|
||||
(pkgs.writers.writeBashBin "lndconnect-clightning-wg" ''
|
||||
exec lndconnect-clightning --host "${serverAddress}" --nocert "$@"
|
||||
|
|
@ -165,6 +173,9 @@ in {
|
|||
optionalString lndconnect ''
|
||||
iptables -w -A nixos-fw -p tcp -s ${wgSubnet}.0/24 --dport ${toString lnd.restPort} -j nixos-fw-accept
|
||||
''
|
||||
+ optionalString lnconnect-clnrest ''
|
||||
iptables -w -A nixos-fw -p tcp -s ${wgSubnet}.0/24 --dport ${toString clnrest.port} -j nixos-fw-accept
|
||||
''
|
||||
+ optionalString lndconnect-clightning ''
|
||||
iptables -w -A nixos-fw -p tcp -s ${wgSubnet}.0/24 --dport ${toString clightning-rest.port} -j nixos-fw-accept
|
||||
''
|
||||
|
|
@ -187,6 +198,11 @@ in {
|
|||
restAddress = "0.0.0.0";
|
||||
tor.enforce = false;
|
||||
};
|
||||
|
||||
services.clightning.plugins.clnrest.address = mkIf lnconnect-clnrest "0.0.0.0";
|
||||
# clnrest runs inside `clightning.service`
|
||||
services.clightning.tor.enforce = mkIf lnconnect-clnrest false;
|
||||
|
||||
services.clightning-rest = mkIf lndconnect-clightning {
|
||||
# clightning-rest always listens on "0.0.0.0"
|
||||
tor.enforce = false;
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ let
|
|||
nix-bitcoin.onionServices.lnd.public = true;
|
||||
|
||||
tests.lndconnect-onion-lnd = with cfg.lnd.lndconnect; enable && onion;
|
||||
tests.lnconnect-onion-clnrest = with cfg.clightning.plugins.clnrest.lnconnect; enable && onion;
|
||||
tests.lndconnect-onion-clightning = with cfg.clightning-rest.lndconnect; enable && onion;
|
||||
|
||||
tests.lightning-loop = cfg.lightning-loop.enable;
|
||||
|
|
@ -195,6 +196,10 @@ let
|
|||
encrypt = true;
|
||||
local.directory = "/var/backup/clightning";
|
||||
};
|
||||
services.clightning.plugins.clnrest = {
|
||||
enable = true;
|
||||
lnconnect = { enable = true; onion = true; };
|
||||
};
|
||||
test.features.clightningPlugins = true;
|
||||
services.rtl.enable = true;
|
||||
services.clightning-rest.enable = true;
|
||||
|
|
|
|||
|
|
@ -179,6 +179,11 @@ def _():
|
|||
assert_running("lnd")
|
||||
assert_matches("runuser -u operator -- lndconnect --url", ".onion")
|
||||
|
||||
@test("lnconnect-onion-clnrest")
|
||||
def _():
|
||||
assert_running("clightning")
|
||||
assert_matches("runuser -u operator -- lnconnect-clnrest --url", ".onion")
|
||||
|
||||
@test("lndconnect-onion-clightning")
|
||||
def _():
|
||||
assert_running("clightning-rest")
|
||||
|
|
|
|||
|
|
@ -18,6 +18,14 @@ makeTestVM {
|
|||
nix-bitcoin.generateSecrets = true;
|
||||
nix-bitcoin.operator.enable = true;
|
||||
|
||||
services.clightning = {
|
||||
enable = true;
|
||||
plugins.clnrest = {
|
||||
enable = true;
|
||||
lnconnect.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
services.clightning-rest = {
|
||||
enable = true;
|
||||
lndconnect.enable = true;
|
||||
|
|
@ -51,16 +59,19 @@ makeTestVM {
|
|||
|
||||
def parse_lndconnect_url(url):
|
||||
u = Url.urlparse(url)
|
||||
data = {'host': u.hostname, 'port': u.port}
|
||||
queries = Url.parse_qs(u.query)
|
||||
macaroon = queries['macaroon'][0]
|
||||
is_clightning = url.startswith("c-lightning-rest")
|
||||
if url.startswith("clnrest"):
|
||||
data['rune'] = queries['rune'][0]
|
||||
else:
|
||||
macaroon = queries['macaroon'][0]
|
||||
if url.startswith("c-lightning-rest"):
|
||||
data['macaroon_hex'] = macaroon
|
||||
else:
|
||||
# lnd
|
||||
data['macaroon_hex'] = base64.urlsafe_b64decode(macaroon + '===').hex().upper()
|
||||
|
||||
return SimpleNamespace(
|
||||
host = u.hostname,
|
||||
port = u.port,
|
||||
macaroon_hex =
|
||||
macaroon if is_clightning else base64.urlsafe_b64decode(macaroon + '===').hex().upper()
|
||||
)
|
||||
return SimpleNamespace(**data)
|
||||
|
||||
client.start()
|
||||
server.connect()
|
||||
|
|
@ -92,6 +103,16 @@ makeTestVM {
|
|||
f"-X GET https://{api.host}:{api.port}/v1/getinfo"
|
||||
)
|
||||
|
||||
with subtest("lnconnect-clnrest-wg"):
|
||||
server.wait_for_unit("clightning.service")
|
||||
lndconnect_url = server.succeed("runuser -u operator -- lnconnect-clnrest-wg --url")
|
||||
api = parse_lndconnect_url(lndconnect_url)
|
||||
# Make clnrest API call
|
||||
client.succeed(
|
||||
f"curl -fsS --max-time 3 --insecure --header 'rune: {api.rune}' "
|
||||
f"-X POST https://{api.host}:{api.port}/v1/getinfo"
|
||||
)
|
||||
|
||||
with subtest("lndconnect-clightning-wg"):
|
||||
server.wait_for_unit("clightning-rest.service")
|
||||
lndconnect_url = server.succeed("runuser -u operator -- lndconnect-clightning-wg --url")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue