Skip to content

Add "stateless remote mode" #160

Closed
@guggero

Description

@guggero

Goal

It should be possible to run LiT in a way that it requires no sensitive information to be available to it on disk and also does not store sensitive information to disk itself.
To enter that "stateless remote mode", I'd like to start LiT with just one flag: --lnd-mode=stateless-remote

This would just start the UI and then wait for user interaction there. In this mode, the UI would not ask for a password first but for a lndconnect format connection string. The connection string contains all information that is needed to connect to the remote lnd mode (IP address, TLS cert if necessary and macaroon). Once the string is provided, the LiT binary connects to the given lnd node and starts the integrated daemons (Loop, Pool, Faraday).

Challenges

  1. Loop, Pool, Faraday (="the daemons") still require each subserver macaroon to be available as a file to connect to lnd. This was fixed in lnd 0.11.1: allow custom macaroon to be used instead of requiring all subserver macaroons lndclient#19 but that fix hasn't been pulled into the daemons yet. We can even expand on that and make it possible to pass in a macaroon directly as a hex string instead of needing to pass a file name.
    • Needs a small change to lndclient that then needs to be pulled into Pool, Loop, Faraday and LiT.
  2. The daemons don't have a stateless init mode yet, meaning they'll leave their own RPC macaroons laying around on the disk (unencrypted).
    • When running in stateless-remote mode, the daemons wouldn't use their own macaroons (wouldn't even create a macaroon DB) but instead use the remote lnd node to validate their macaroons.
    • Because the macaroons for the daemons will contain permissions and/or RPC URIs that lnd doesn't know, this requires a new RPC in lnd that allows us to validate a macaroon without checking the permissions part of it.
    • When baking a macaroon, a new flag would be necessary to instruct lnd to not complain about permission pairs or URIs it doesn't know itself.
    • Users of the stateless remote mode would need to bake a "super admin macaroon" that gives access to lnd and all daemons. Basically containing all permissions that exist of all the 4 daemons.
  3. The daemons don't have an unlock mechanism yet, meaning their macaroon DB is unencrypted (or to be precise: the encryption uses a default password).
    • Would also be solved by turning off macaroons for the daemons in the stateless remote mode.
  4. LiT gives the user access to all RPCs with just a password. That Basic Auth mechanism is turned into a macaroon internally. But it means the LiT backend needs access to all daemon macaroons (and lnd's) internally.
    • The UI password would be replaced completely with the connection string. That could be stored in the browser's session storage by the UI scripts. The macaroon part could even be encrypted, causing the UI to ask for a password before using it. That way the encrypted string could also be stored in the longer term storage of the browser, effectively requiring the user to "log in" again after the browser is closed.

Steps to completion

  • (1) Add new CustomMacaroonHex to lndclient's LndServicesConfig.
  • (2) Update Loop, Pool, Faraday and LiT to use lndclient version containing the above change.
  • (3) Add PR to lnd that adds a new RPC call to check external macaroon permissions, for example CheckMacaroonPermission. The same PR should also add a new flag to the BakeMacaroon RPC that allows specifying permission pairs or URIs that lnd doesn't know. The flag could be called --allow_external_permissions.
  • (4) Add the new stateless-remote mode to the LiT binary and its internal gRPC/REST proxy component. In this mode it wouldn't look for a password in the Authorization header field but expect an lndconnect string there. If such a request comes in and the daemons weren't started yet, it would do so first before forwarding the request.
  • (5) Update the LiT UI code to detect the stateless-remote mode and act accordingly.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions