lightningnetwork / lnd

Lightning Network Daemon ⚡️
MIT License
7.67k stars 2.07k forks source link

Feature request: Add programmatic way of unlocking wallet #1611

Closed slush0 closed 6 years ago

slush0 commented 6 years ago

Background

Currently there's no easy way of unlocking wallet in automatic manner, making it hard to automate services for managing lnd. Although I understand passing passphrase over command line is not safe, reading passphrase over stdin or launching external command for fetching passphrase would make it possible.

Expected behaviour

Starting lnd and unlocking wallet with passphrase from stdin:

cat passphrase.txt | lnd --stdin-passphrase

or

lnd --unlock-command unlock.sh

Actual behaviour

There's no way to "un-encrypt" existing wallet (or at least I didn't find a way), only create new one with --noencryptwallet, so it is not possible to automate lnd with systemd.

Currently I use this workaround (may be useful for other people), but it is ugly hack, because lnd need to be spawn as separate process before, making systemd scripts non-trivial.

# cat lnd-start.sh
#!/bin/bash
/usr/local/bin/lnd-unlockwallet.sh &
/home/bitcoin/go/bin/lnd
# cat lnd-unlockwallet.sh
#!/usr/bin/expect
sleep 3
spawn /home/bitcoin/go/bin/lncli "unlock"
expect {
    "Input wallet password:" {
        send -- "password\n"
    }
}
expect eof
exit
Roasbeef commented 6 years ago

Currently there's no easy way of unlocking wallet in automatic manner, making it hard to automate services for managing lnd.

There's an gRPC method: https://api.lightning.community/#unlockwallet Also available over REST: https://api.lightning.community/rest/index.html#v1-unlockwallet

There's no way to "un-encrypt" existing wallet (or at least I didn't find a way), only create new one with --noencryptwallet, so it is not possible to automate lnd with systemd.

Yeah there's no way to "unencrypt" as it defers to on-disk encryption. The --noencryptwallet option actually just uses a hard coded key for the encryption, and atm also doesn't give you a mnemonic seed or anything like that.

slush0 commented 6 years ago

Thank you for pointing me to REST API, it may be more reliable than expect workaround I'm using now. It is still workaround though, as it need invoking another script/process to start lnd, although it could be done easily and in clean way by adding new parameter.

mariodian commented 6 years ago

@slush0 did you manage to figure it out? I'm struggling to run lncli remotely while automatically providing the password.

echo -n "password" | lncli --rpcserver ip.of.the.server:10009 --tlscertpath /path/lnd.cert --macaroonpath /path/admin.macaroon unlock

outputs Input wallet password: [lncli] inappropriate ioctl for device while:

echo -e "password" | lncli --rpcserver ip.of.the.server:10009 --tlscertpath /path/lnd.cert --macaroonpath /path/admin.macaroon unlock --stdin-passphrase

outputs [lncli] flag provided but not defined: -stdin-passphrase

halseth commented 6 years ago

I think we could add a parameter to lncli unlock to allow this, but should note that it is unsafe. Something like lncli unlock --unsafe --password=pw123 or cat password.txt | lncli unlock --unsafe --stdin

mariodian commented 6 years ago

It's not any less safe than leaving the wallet unlocked on a server running 24/7 though.

ZapUser77 commented 6 years ago

Well... leaving a password around in plaintext is more unsafe. (Even if marginally) Someone with physical access (but shouldn't have the password), but is heavily monitored on site, could then take the password off-site to steal all funds. And more so, if the password is stored in plaintext in a machine that isn't running the LND instance. [I've seen network admins hand out "Auto-join-to-domain" disks with Enterprise Admin UN/PW in clear text for global military domains. So.. just food for thought.]

mariodian commented 6 years ago

I think it's easier to get access to a home server that is constantly online than to a laptop that runs a few hours a day here and there.

Anyway, it seems like it's not an easy task to automate things with LND.

juscamarena commented 6 years ago

I run lnd with supervisor and have my own unlock script using the grpc method roasbeef posted, works great. Automatic restarts when there's a crash especially if I'm away for a few days gives me peace of mind.

Roasbeef commented 6 years ago

It's not any less safe than leaving the wallet unlocked on a server running 24/7 though.

It'll show up in the command history. It's also pretty easy to automate as is.

Roasbeef commented 6 years ago

I actually think this can be closed now since the RPC already exists (both REST and gRPC), if discussion kicks up again, I'll re-open.

mariodian commented 6 years ago

@juscamarena could you please share the script? Thanks!

plwalters commented 6 years ago

Just to beat a dead horse there could be a secret.yml or something file in the .lnd directory that LND could use when loading to accomplish everything mentioned above without storing the password in cmd history. Alternatively LND could look in the env vars for the secret and if one is not found prompt for password when unlock is called.

This would be automation of servers much easier, the grpc and rest methods don't feel like a great solution for me either. Being able to issue a single unlock command with no prompts will be even more important when working with container orchestration tools.

</$0.02>
wroscoe commented 3 years ago

There is now a password file option in lnd.conf. https://github.com/lightningnetwork/lnd/blame/756a0ab39240dcfd15dea325c5921ef84e7109d9/sample-lnd.conf#L266