Skip to content

Commit ab40982

Browse files
Merge pull request lightninglabs#237 from lightninglabs/docs-lnd
Update lnd documentation
2 parents cc7c956 + 74b1673 commit ab40982

File tree

2 files changed

+310
-1
lines changed

2 files changed

+310
-1
lines changed

docs/lnd/release-notes/release-notes-0.14.0.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,13 @@ documentation](../psbt.md#use-the-batchopenchannel-rpc-for-safe-batch-channel-fu
185185
take longer to start a `lnd` node when running in `simnet` or `regtest`,
186186
something developers need to watch out from this release.
187187

188+
### Remote signing
189+
190+
It is now possible to delegate any operation that needs access to private keys
191+
to a [remote signer that serves signing requests over
192+
RPC](https://github.com/lightningnetwork/lnd/pull/5689). More information can be
193+
found [in the new remote signing document](../remote-signing.md).
194+
188195
## Security
189196

190197
* The release signature verification script [was overhauled to fix some possible
@@ -205,7 +212,23 @@ If you use a strange system or changed group membership of the group running LND
205212
you may want to check your system to see if it introduces additional risk for
206213
you.
207214

208-
## Safety
215+
## Custom peer messages
216+
217+
Lightning nodes have a connection to each of their peers for exchanging
218+
messages. In regular operation, these messages coordinate processes such as
219+
channel opening and payment forwarding.
220+
221+
The lightning spec however also defines a custom range (>= 32768) for
222+
experimental and application-specific peer messages.
223+
224+
With this release, [custom peer message
225+
exchange](https://github.com/lightningnetwork/lnd/pull/5346) is added to open up
226+
a range of new possibilities. Custom peer messages allow the lightning protocol
227+
with its transport mechanisms (including tor) and public key authentication to
228+
be leveraged for application-level communication. Note that peers exchange these
229+
messages directly. There is no routing/path finding involved.
230+
231+
# Safety
209232

210233
* Locally force closed channels are now [kept in the channel.backup file until
211234
their time lock has fully matured](https://github.com/lightningnetwork/lnd/pull/5528).
@@ -254,6 +277,8 @@ you.
254277
Applications that use the iOS build will have to be updated to include
255278
an `xcframework` instead of a `framework`.
256279

280+
* [Upgrade the sub packages to 1.16](https://github.com/lightningnetwork/lnd/pull/5813)
281+
257282
## Documentation
258283

259284
* [Outdated warning about unsupported pruning was replaced with clarification that LND **does**
@@ -378,6 +403,8 @@ you.
378403
was refactored as a preparation for supporting remote
379404
signing](https://github.com/lightningnetwork/lnd/pull/5708).
380405

406+
* [Include htlc amount in bandwidth hints](https://github.com/lightningnetwork/lnd/pull/5512).
407+
381408
## Database
382409

383410
* [Ensure single writer for legacy
@@ -504,6 +531,7 @@ change](https://github.com/lightningnetwork/lnd/pull/5613).
504531
* Hampus Sjöberg
505532
* Harsha Goli
506533
* Jesse de Wit
534+
* Joost Jager
507535
* Martin Habovstiak
508536
* Naveen Srinivasan
509537
* Oliver Gugger

docs/lnd/remote-signing.md

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
# Remote signing
2+
3+
Remote signing refers to an operating mode of `lnd` in which the wallet is
4+
segregated into two parts, each running within its own instance of `lnd`. One
5+
instance is running in watch-only mode which means it only has **public**
6+
keys in its wallet. The second instance (in this document referred to as
7+
"signer" or "remote signer" instance) has the same keys in its wallet, including
8+
the **private** keys.
9+
10+
The advantage of such a setup is that the `lnd` instance containing the private
11+
keys (the "signer") can be completely offline except for a single inbound gRPC
12+
connection and the outbound connection to `bitcoind` (or `btcd` or `neutrino`).
13+
The signer instance can run on a different machine with more tightly locked down
14+
network security, optimally only allowing the single gRPC connection from the
15+
outside.
16+
17+
An example setup could look like:
18+
19+
```text
20+
xxxxxxxxx
21+
xxxxxxxxx xxxx
22+
xxx xx
23+
x LN p2p network xx
24+
x x
25+
xxx xx
26+
xxxxx xxxxxxxx
27+
xxx
28+
^ +----------------------------------+
29+
| p2p traffic | firewalled/offline network zone |
30+
| | |
31+
v | |
32+
+----------------+ gRPC | +----------------+ |
33+
| watch-only lnd +--------------+-->| full seed lnd | |
34+
+-------+--------+ | +------+---------+ |
35+
| | | |
36+
+-------v--------+ | +------v---------+ |
37+
| bitcoind/btcd | | | bitcoind/btcd | |
38+
+----------------+ | +----------------+ |
39+
| |
40+
+----------------------------------+
41+
```
42+
43+
NOTE: Offline in this context means that `lnd` itself does not need to be
44+
reachable from the internet and itself doesn't connect out. If the `bitcoind`
45+
or other chain backend is indeed running within this same firewall/offline zone
46+
then that component will need at least _outbound_ internet access. But it is
47+
also possible to use a chain backend that is running outside this zone.
48+
49+
## Restrictions / limitations
50+
51+
The current implementation of the remote signing mode comes with a few
52+
restrictions and limitations:
53+
54+
- Both `lnd` instances need a connection to a chain backend:
55+
- The type of chain backend (`bitcoind`, `btcd` or `neutrino`) **must**
56+
match.
57+
- Both instances can point to the same chain backend node, though limits
58+
apply with the number of `lnd` instances that can use the same `bitcoind`
59+
node over ZMQ.
60+
See ["running multiple lnd nodes" in the safety guide](safety.md#running-multiple-lnd-nodes)
61+
.
62+
- Using a pruned chain backend is not recommended as that increases the
63+
chance of the two wallets falling out of sync with each other.
64+
- The wallet of the "signer" instance **must not be used** for anything.
65+
Especially generating new addresses manually on the "signer" will lead to the
66+
two wallets falling out of sync!
67+
68+
## Example setup
69+
70+
In this example we are going to set up two nodes, the "signer" that has the full
71+
seed and private keys and the "watch-only" node that only has public keys.
72+
73+
### The "signer" node
74+
75+
The node "signer" is the hardened node that contains the private key material
76+
and is not connected to the internet or LN P2P network at all. Ideally only a
77+
single RPC based connection (that can be firewalled off specifically) can be
78+
opened to this node from the host on which the node "watch-only" is running.
79+
80+
Recommended entries in `lnd.conf`:
81+
82+
```text
83+
# No special configuration required other than basic "hardening" parameters to
84+
# make sure no connections to the internet are opened.
85+
86+
[Application Options]
87+
# Don't listen on the p2p port.
88+
nolisten=true
89+
90+
# Don't reach out to the bootstrap nodes, we don't need a synced graph.
91+
nobootstrap=true
92+
93+
# Just an example, this is the port that needs to be opened in the firewall and
94+
# reachable from the node "watch-only".
95+
rpclisten=10019
96+
```
97+
98+
After successfully starting up "signer", the following command can be run to
99+
export the `xpub`s of the wallet:
100+
101+
```shell
102+
signer> ⛰ lncli wallet accounts list > accounts-signer.json
103+
```
104+
105+
That `accounts-signer.json` file has to be copied to the machine on which
106+
"watch-only" will be running. It contains the extended public keys for all of
107+
`lnd`'s accounts.
108+
109+
A custom macaroon can be baked for the watch-only node so it only gets the
110+
minimum required permissions on the signer instance:
111+
112+
```shell
113+
signer> ⛰ lncli bakemacaroon --save_to signer.custom.macaroon \
114+
message:write signer:generate address:read onchain:write
115+
```
116+
117+
Copy this file (`signer.custom.macaroon`) along with the `tls.cert` of the
118+
signer node to the machine where the watch-only node will be running.
119+
120+
### The "watch-only" node
121+
122+
The node "watch-only" is the public, internet facing node that does not contain
123+
any private keys in its wallet but delegates all signing operations to the node
124+
"signer" over a single RPC connection.
125+
126+
Required entries in `lnd.conf`:
127+
128+
```text
129+
[remotesigner]
130+
remotesigner.enable=true
131+
remotesigner.rpchost=zane.example.internal:10019
132+
remotesigner.tlscertpath=/home/watch-only/example/signer.tls.cert
133+
remotesigner.macaroonpath=/home/watch-only/example/signer.custom.macaroon
134+
```
135+
136+
After starting "watch-only", the wallet can be created in watch-only mode by
137+
running:
138+
139+
```shell
140+
watch-only> ⛰ lncli createwatchonly accounts-signer.json
141+
142+
Input wallet password:
143+
Confirm password:
144+
145+
Input an optional wallet birthday unix timestamp of first block to start scanning from (default 0):
146+
147+
148+
Input an optional address look-ahead used to scan for used keys (default 2500):
149+
```
150+
151+
Alternatively a script can be used for initializing the watch-only wallet
152+
through the RPC interface as is described in the next section.
153+
154+
## Example initialization script
155+
156+
This section shows an example script that initializes the watch-only wallet of
157+
the public node using NodeJS.
158+
159+
To use this example, first initialize the "signer" wallet with the root key
160+
`tprv8ZgxMBicQKsPe6jS4vDm2n7s42Q6MpvghUQqMmSKG7bTZvGKtjrcU3PGzMNG37yzxywrcdvgkwrr8eYXJmbwdvUNVT4Ucv7ris4jvA7BUmg`
161+
using the command line. This can be done by using the new `x` option during the
162+
interactive `lncli create` command:
163+
164+
```bash
165+
signer> ⛰ lncli create
166+
Input wallet password:
167+
Confirm password:
168+
169+
Do you have an existing cipher seed mnemonic or extended master root key you want to use?
170+
Enter 'y' to use an existing cipher seed mnemonic, 'x' to use an extended master root key
171+
or 'n' to create a new seed (Enter y/x/n):
172+
```
173+
174+
Then run this script against the "watch-only" node (after editing the
175+
constants):
176+
177+
```javascript
178+
179+
// EDIT ME:
180+
const WATCH_ONLY_LND_DIR = '/home/watch-only/.lnd';
181+
const WATCH_ONLY_RPC_HOSTPORT = 'localhost:10018';
182+
const WATCH_ONLY_WALLET_PASSWORD = 'testnet3';
183+
const LND_SOURCE_DIR = '.';
184+
185+
const fs = require('fs');
186+
const grpc = require('@grpc/grpc-js');
187+
const protoLoader = require('@grpc/proto-loader');
188+
const loaderOptions = {
189+
keepCase: true,
190+
longs: String,
191+
enums: String,
192+
defaults: true,
193+
oneofs: true
194+
};
195+
const packageDefinition = protoLoader.loadSync([
196+
LND_SOURCE_DIR + '/lnrpc/walletunlocker.proto',
197+
], loaderOptions);
198+
199+
process.env.GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA'
200+
201+
// build ssl credentials using the cert the same as before
202+
let lndCert = fs.readFileSync(WATCH_ONLY_LND_DIR + '/tls.cert');
203+
let sslCreds = grpc.credentials.createSsl(lndCert);
204+
205+
let lnrpcDescriptor = grpc.loadPackageDefinition(packageDefinition);
206+
let lnrpc = lnrpcDescriptor.lnrpc;
207+
var client = new lnrpc.WalletUnlocker(WATCH_ONLY_RPC_HOSTPORT, sslCreds);
208+
209+
client.initWallet({
210+
wallet_password: Buffer.from(WATCH_ONLY_WALLET_PASSWORD, 'utf-8'),
211+
recovery_window: 2500,
212+
watch_only: {
213+
accounts: [{
214+
purpose: 49,
215+
coin_type: 0,
216+
account: 0,
217+
xpub: 'tpubDDXEYWvGCTytEF6hBog9p4qr2QBUvJhh4P2wM4qHHv9N489khkQoGkBXDVoquuiyBf8SKBwrYseYdtq9j2v2nttPpE8qbuW3sE2MCkFPhTq',
218+
}, {
219+
purpose: 84,
220+
coin_type: 0,
221+
account: 0,
222+
xpub: 'tpubDDWAWrSLRSFrG1KdqXMQQyTKYGSKLKaY7gxpvK7RdV3e3DkhvuW2GgsFvsPN4RGmuoYtUgZ1LHZE8oftz7T4mzc1BxGt5rt8zJcVQiKTPPV',
223+
}, {
224+
purpose: 1017,
225+
coin_type: 1,
226+
account: 0,
227+
xpub: 'tpubDDXFHr67Ro2tHKVWG2gNjjijKUH1Lyv5NKFYdJnuaLGVNBVwyV5AbykhR43iy8wYozEMbw2QfmAqZhb8gnuL5mm9sZh8YsR6FjGAbew1xoT',
228+
}, {
229+
purpose: 1017,
230+
coin_type: 1,
231+
account: 1,
232+
xpub: 'tpubDDXFHr67Ro2tKkccDqNfDqZpd5wCs2n6XRV2Uh185DzCTbkDaEd9v7P837zZTYBNVfaRriuxgGVgxbGjDui4CKxyzBzwz4aAZxjn2PhNcQy',
233+
}, {
234+
purpose: 1017,
235+
coin_type: 1,
236+
account: 2,
237+
xpub: 'tpubDDXFHr67Ro2tNH4KH41i4oTsWfRjFigoH1Ee7urvHow51opH9xJ7mu1qSPMPVtkVqQZ5tE4NTuFJPrbDqno7TQietyUDmPTwyVviJbGCwXk',
238+
}, {
239+
purpose: 1017,
240+
coin_type: 1,
241+
account: 3,
242+
xpub: 'tpubDDXFHr67Ro2tQj5Zvav2ALhkU6dRQAhEtNPnYJVBC8hs2U1A9ecqxRY3XTiJKBDD7e8tudhmTRs8aGWJAiAXJN5kXy3Hi6cmiwGWjXK5Cv5',
243+
}, {
244+
purpose: 1017,
245+
coin_type: 1,
246+
account: 4,
247+
xpub: 'tpubDDXFHr67Ro2tSSR2LLBJtotxx2U45cuESLWKA72YT9td3SzVKHAptzDEx5chsUNZ4WRMY5h6HJxRSebjRatxQKX1uUsux1LvKS1wsfNJ2PH',
248+
}, {
249+
purpose: 1017,
250+
coin_type: 1,
251+
account: 5,
252+
xpub: 'tpubDDXFHr67Ro2tTwzfWvNoMoPpZbxdMEfe1WhbXJxvXikGixPa4ggSRZeGx6T5yxVHTVT3rjVh35Veqsowj7emX8SZfXKDKDKcLduXCeWPUU3',
253+
}, {
254+
purpose: 1017,
255+
coin_type: 1,
256+
account: 6,
257+
xpub: 'tpubDDXFHr67Ro2tYEDS2EByRedfsUoEwBtrzVbS1qdPrX6sAkUYGLrZWvMmQv8KZDZ4zd9r8WzM9bJ2nGp7XuNVC4w2EBtWg7i76gbrmuEWjQh',
258+
}, {
259+
purpose: 1017,
260+
coin_type: 1,
261+
account: 7,
262+
xpub: 'tpubDDXFHr67Ro2tYpwnFJEQaM8eAPM2UV5uY6gFgXeSzS5aC5T9TfzXuawYKBbQMZJn8qHXLafY4tAutoda1aKP5h6Nbgy3swPbnhWbFjS5wnX',
263+
}, {
264+
purpose: 1017,
265+
coin_type: 1,
266+
account: 8,
267+
xpub: 'tpubDDXFHr67Ro2tddKpAjUegXqt7EGxRXnHkeLbUkfuFMGbLJYgRpG4ew5pMmGg2nmcGmHFQ29w3juNhd8N5ZZ8HwJdymC4f5ukQLJ4yg9rEr3',
268+
}, {
269+
purpose: 1017,
270+
coin_type: 1,
271+
account: 9,
272+
xpub: 'tpubDDXFHr67Ro2tgE89V8ZdgMytC2Jq1iT9ttGhdzR1X7haQJNBmXt8kau6taC6DGASYzbrjmo9z9w6JQFcaLNqbhS2h2PVSzKf79j265Zi8hF',
273+
}]
274+
}
275+
}, (err, res) => {
276+
if (err != null) {
277+
console.log(err);
278+
}
279+
console.log(res);
280+
});
281+
```

0 commit comments

Comments
 (0)