From d13fb1660861840eb76325167122b9ca464c2055 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Thu, 6 May 2021 12:19:12 +0200 Subject: [PATCH] docs: add wallet management doc, fix markup in INSTALL doc To give users an idea how the new auto-unlock flag can be used in a more safe way than just writing the password to a file, we add a new wallet management document and describe the unlock feature in detail. --- docs/INSTALL.md | 61 +++++++++------- docs/wallet.md | 191 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 226 insertions(+), 26 deletions(-) create mode 100644 docs/wallet.md diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 6c721ef7..ecff6b04 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -226,16 +226,16 @@ On FreeBSD, use gmake instead of make. Alternatively, if one doesn't wish to use `make`, then the `go` commands can be used directly: ```shell -cd $GOPATH/src/github.com/lightningnetwork/lnd -git pull -GO111MODULE=on go install -v ./... +⛰ cd $GOPATH/src/github.com/lightningnetwork/lnd +⛰ git pull +⛰ GO111MODULE=on go install -v ./... ``` **Tests** To check that `lnd` was installed properly run the following command: -``` -make check +```shell +⛰ make check ``` This command requires `bitcoind` (almost any version should do) to be available @@ -259,7 +259,7 @@ wallet, and the age of the earliest channels (which were created around March The set of arguments for each of the backend modes is as follows: ## btcd Options -``` +```text btcd: --btcd.dir= The base directory that contains the node's data, logs, configuration file, etc. (default: /Users/roasbeef/Library/Application Support/Btcd) --btcd.rpchost= The daemon's rpc listening address. If a port is omitted, then the default port for the selected chain parameters will be used. (default: localhost) @@ -270,7 +270,7 @@ btcd: ``` ## Neutrino Options -``` +```text neutrino: -a, --neutrino.addpeer= Add a peer to connect with at startup --neutrino.connect= Connect only to the specified peers at startup @@ -282,7 +282,7 @@ neutrino: ``` ## Bitcoind Options -``` +```text bitcoind: --bitcoind.dir= The base directory that contains the node's data, logs, configuration file, etc. (default: /Users/roasbeef/Library/Application Support/Bitcoin) --bitcoind.rpchost= The daemon's rpc listening address. If a port is omitted, then the default port for the selected chain parameters will be used. (default: localhost) @@ -302,8 +302,8 @@ On FreeBSD, use gmake instead of make. To install btcd, run the following commands: Install **btcd**: -``` -make btcd +```shell +⛰ make btcd ``` Alternatively, you can install [`btcd` directly from its @@ -313,8 +313,8 @@ repo](https://github.com/btcsuite/btcd). Running the following command will create `rpc.cert` and default `btcd.conf`. -``` -btcd --testnet --rpcuser=REPLACEME --rpcpass=REPLACEME +```shell +⛰ btcd --testnet --rpcuser=REPLACEME --rpcpass=REPLACEME ``` If you want to use `lnd` on testnet, `btcd` needs to first fully sync the testnet blockchain. Depending on your hardware, this may take up to a few @@ -326,8 +326,8 @@ directly, rather than scanning blocks or BIP 158 filters for relevant items. While `btcd` is syncing you can check on its progress using btcd's `getinfo` RPC command: -``` -btcctl --testnet --rpcuser=REPLACEME --rpcpass=REPLACEME getinfo +```shell +⛰ btcctl --testnet --rpcuser=REPLACEME --rpcpass=REPLACEME getinfo { "version": 120000, "protocolversion": 70002, @@ -346,8 +346,8 @@ Additionally, you can monitor btcd's logs to track its syncing progress in real time. You can test your `btcd` node's connectivity using the `getpeerinfo` command: -``` -btcctl --testnet --rpcuser=REPLACEME --rpcpass=REPLACEME getpeerinfo | more +```shell +⛰ btcctl --testnet --rpcuser=REPLACEME --rpcpass=REPLACEME getpeerinfo | more ``` ### Running lnd using the btcd backend @@ -356,8 +356,9 @@ If you are on testnet, run this command after `btcd` has finished syncing. Otherwise, replace `--bitcoin.testnet` with `--bitcoin.simnet`. If you are installing `lnd` in preparation for the [tutorial](https://dev.lightning.community/tutorial), you may skip this step. -``` -lnd --bitcoin.active --bitcoin.testnet --debuglevel=debug --btcd.rpcuser=kek --btcd.rpcpass=kek --externalip=X.X.X.X +```shell +⛰ lnd --bitcoin.active --bitcoin.testnet --debuglevel=debug \ + --btcd.rpcuser=kek --btcd.rpcpass=kek --externalip=X.X.X.X ``` ## Using Neutrino @@ -371,8 +372,9 @@ mode. A public instance of such a node can be found at To run lnd in neutrino mode, run `lnd` with the following arguments, (swapping in `--bitcoin.simnet` if needed), and also your own `btcd` node if available: -``` -lnd --bitcoin.active --bitcoin.testnet --debuglevel=debug --bitcoin.node=neutrino --neutrino.connect=faucet.lightning.community +```shell +⛰ lnd --bitcoin.active --bitcoin.testnet --debuglevel=debug \ + --bitcoin.node=neutrino --neutrino.connect=faucet.lightning.community ``` @@ -407,7 +409,7 @@ the following: the testnet chain (alternatively, use `--bitcoind.regtest` instead). Here's a sample `bitcoin.conf` for use with lnd: -``` +```text testnet=1 server=1 daemon=1 @@ -421,8 +423,13 @@ updated with the latest blocks on testnet, run the command below to launch `lnd.conf` to save these options, more info on that is described further below): -``` -lnd --bitcoin.active --bitcoin.testnet --debuglevel=debug --bitcoin.node=bitcoind --bitcoind.rpcuser=REPLACEME --bitcoind.rpcpass=REPLACEME --bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332 --bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333 --externalip=X.X.X.X +```shell +⛰ lnd --bitcoin.active --bitcoin.testnet --debuglevel=debug \ + --bitcoin.node=bitcoind --bitcoind.rpcuser=REPLACEME \ + --bitcoind.rpcpass=REPLACEME \ + --bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332 \ + --bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333 \ + --externalip=X.X.X.X ``` *NOTE:* @@ -457,8 +464,8 @@ lnd --bitcoin.active --bitcoin.testnet --debuglevel=debug --bitcoin.node=bitcoin # Creating a wallet If `lnd` is being run for the first time, create a new wallet with: -``` -lncli create +```shell +⛰ lncli create ``` This will prompt for a wallet password, and optionally a cipher seed passphrase. @@ -467,6 +474,8 @@ passphrase. recover the wallet in case of data loss. The user should write this down and keep in a safe place. +More [information about managing wallets can be found in the wallet management +document](wallet.md). # Macaroons @@ -528,7 +537,7 @@ at the command line, you can create an `lnd.conf`. `~/.lnd/lnd.conf` Here's a sample `lnd.conf` for `btcd` to get you started: -``` +```text [Application Options] debuglevel=trace maxpendingchannels=10 diff --git a/docs/wallet.md b/docs/wallet.md new file mode 100644 index 00000000..5d8d57dd --- /dev/null +++ b/docs/wallet.md @@ -0,0 +1,191 @@ +# Wallet management + +The wallet in the context of `lnd` is a database file (located in the data +directory, for example `~/.lnd/data/chain/bitcoin/mainnet/wallet.db` on Linux) +that contains all addresses and private keys for the on-chain **and** off-chain +(LN) funds. + +The wallet is independent of the chain backend that is used (`bitcoind`, `btcd` +or `neutrino`) and must therefore be created as the first step after starting +up a fresh `lnd` node. + +To protect the sensitive content of the wallet, the database is encrypted with +a password chosen by the user when creating the wallet (simply called "wallet +password"). `lnd` will not store that password anywhere by itself (as that would +defeat the purpose of the password) so every time `lnd` is restarted, its wallet +needs to be unlocked with that password. This can either be done [manually +through the command line](#unlocking-a-wallet) or (starting with `lnd` version +`v0.13.0-beta`) [automatically from a file](#auto-unlocking-a-wallet). + +## Creating a wallet + +If `lnd` is being run for the first time, create a new wallet with: +```shell +⛰ lncli create +``` +This will prompt for a wallet password, and optionally a cipher seed +passphrase. + +`lnd` will then print a 24 word cipher seed mnemonic, which can be used to +recover the wallet in case of data loss. The user should write this down and +keep in a safe place. + +In case a node needs to be recovered from an existing seed, this can also be +done through the `create` command. Please refer to the +[recovery guide](recovery.md) for more information about recovering a node. + +## Unlocking a wallet + +Every time `lnd` starts up fresh (e.g. after a system restart or a version +upgrade) the user-chosen wallet password needs to be entered to unlock (decrypt) +the wallet database. + +This will be indicated in `lnd`'s log with a message like this: + +```text +2021-05-06 11:36:11.445 [INF] LTND: Waiting for wallet encryption password. Use `lncli create` to create a wallet, `lncli unlock` to unlock an existing wallet, or `lncli changepassword` to change the password of an existing wallet and unlock it. +``` + +Unlocking the password manually is as simple as running the command +```shell +⛰ lncli unlock +``` +and then typing the wallet password. + +## Auto-unlocking a wallet + +In some situations (for example automated, cluster based setups) it can be +impractical to manually unlock the wallet every time `lnd` is restarted. + +In `lnd` version `v0.13.0-beta` and later there is a configuration option to +tell the wallet to auto-unlock itself by reading the password from a file. This +can only be activated _after_ the wallet was created manually. + +### Very basic example (not very secure) + +This example only tries to give a basic, minimal example on how to use the +auto-unlock feature. Storing a password in a file on the same disk as the wallet +database is not in itself more secure than leaving the database unencrypted in +the first place. This example might be useful in a containerized environment +though where the secrets are mounted to a file anyway. + +- Start `lnd` without the flag: + ```shell + ⛰ lnd --bitcoin.active --bitcoin.xxxx ..... + ``` +- Create the wallet and write down the seed in a safe place: + ```shell + ⛰ lncli create + ``` +- Stop `lnd` again: + ```shell + ⛰ lncli stop + ``` +- Write the password to a file: + ```shell + ⛰ echo 'my-$up3r-Secret-Passw0rd' > /some/safe/location/password.txt + ``` +- Make sure the password file can only be read by our user: + ```shell + ⛰ chmod 0400 /some/safe/location/password.txt + ``` +- Start `lnd` with the auto-unlock flag: + ```shell + ⛰ lnd --bitcoin.active --bitcoin.xxxx ..... \ + --wallet-unlock-password-file=/some/safe/location/password.txt + ``` + +As with every command line flag, the `wallet-unlock-password-file` option can +also be added to `lnd`'s configuration file, for example: + +```text +[Application Options] +debuglevel=debug +wallet-unlock-password-file=/some/safe/location/password.txt + +[Bitcoin] +bitcoin.active=1 +... +``` + +### More secure example with password manager and using a named pipe + +This example is a bit more involved and requires the use of a password manager +of some sort. It will also only work on Unix like file systems that support +named pipes. + +We will use the password manager [`pass`](https://www.passwordstore.org/) as an +example here but it should work similarly with other password managers. + +- Start `lnd` without the flag: + ```shell + ⛰ lnd --bitcoin.active --bitcoin.xxxx ..... + ``` +- Create the wallet and write down the seed in a safe place: + ```shell + ⛰ lncli create + ``` +- Stop `lnd` again: + ```shell + ⛰ lncli stop + ``` +- Store the password in `pass`: + ```shell + ⛰ pass insert lnd/my-wallet-password + ``` +- Create a startup script for starting `lnd`, for example `run-lnd.sh`: + ```shell + #!/bin/bash + + # Create a named pipe. As the name suggests, this is a FIFO (first in first + # out) pipe. Everything sent in can be read out again without the content + # actually being written to a disk. + mkfifo /tmp/wallet-password-pipe + + # Read the password from the manager and attempt to write it to the pipe. Any + # write to a pipe will only be accepted once there is a process that reads + # from the pipe at the same time. That's why we need to run this process in + # the background (the ampersand & at the end) because it would block our + # script from continuing otherwise. + pass lnd/my-wallet-password > /tmp/wallet-password-pipe & + + # Now we can start lnd. + lnd --bitcoin.active --bitcoin.xxxx ..... \ + --wallet-unlock-password-file=/tmp/wallet-password-pipe + ``` +- Run the startup script instead of running `lnd` directly. + ```shell + ⛰ ./run-lnd.sh + ``` + +## Changing the password + +Changing the wallet password is possible but only while the wallet is locked. +So after restarting `lnd`, instead of using the `unlock` command, the +`changepassword` command can be used: + +```shell +⛰ lncli changepassword +``` + +This will ask for the old/existing password and a new one. If successful, the +database is re-encrypted with the new password and then the wallet is also +unlocked in the process. + +## DO NOT USE --noseedbackup on mainnet + +There is a way to get rid of the need to unlock the wallet password: The +`--noseedbackup` flag. + +Using that flag with **real funds (mainnet) is extremely risky for two reasons**: +1. On first startup a wallet is created automatically. The seed phrase (the 24 + words needed to restore a wallet) is never shown to the user. Therefore if + the worst thing happens and the hard disk crashes or the wallet file is + deleted by accident, **THERE IS NO WAY OF GETTING THE FUNDS BACK**. +2. In addition to the seed not being known to the user, the wallet database is + also not protected. A well-known default password is chosen for the + encryption. Any user (or malware) with access to the wallet database can + steal the funds if they copy the file. + +The `--noseedbackup` flag should only ever be used in a test setup, for example +on Bitcoin testnet, regtest or simnet.