mit-dci / lit

Lightning Network node software
MIT License
551 stars 119 forks source link

Remote control #312

Closed gertjaap closed 6 years ago

gertjaap commented 6 years ago

Implementation for #235

Varunram commented 6 years ago

needs rebase

gertjaap commented 6 years ago

Okay, so this pull requests allows RPC-via-LNDC.

Local control (i.e. lit-af on host)

lit-af connects to localhost over LNDC and uses a key derived from privkey.hex. Since this key is also available to lit, it can determine the public key and autorize commands from that key by default.

When lit receives an RPC call over LNDC, it will check if the node is authorized using the pubkey of the peer or the pubkey included in the message (the one in the message has preference). If unauthorized, lit will reject the call.

If authorized, it will execute the RPC request using reflection (similar to how jsonrpc does this internally), and send back the result wrapped in a response message to the peer that sent the request.

Remote control

When privkey.hex is not present, lit-af will use a newly generated / password protected key stored in the homefolder, similar to privkey.hex (just named lit-af-key.hex). This key is used as node ID in the LNDC communication.

There is an extra parameter to lit-af (addr) that specifies the ln address of the host we're going to control. So starting lit-af for a remote host would look something like this:

lit-af -node 1.2.3.4 -p 2448 -addr ln1hzcjphula5cxh5hpj3zqancy0jv7t2zvyz0wnt

When sending commands using lit-af in this fashion, it will identify with the node ID, and therefore it's important to authorize this on the lit node (otherwise everything will return Unauthorized).

From the lit-af remote instance, you can issue the rcreq command. This will execute the LitRPC.RequestRemoteControlAuthorization RPC call, which is not protected by authorization. The RPC call will mark the key that sent the command as one that is requesting access.

Using lit-af on the host (which is authorized by default) you can then use ls rcauth to view pending requests and use rcauth {key} true to authorize or rcauth {key} false to decline.

Once authorized, the remote lit-af can do the same things the local lit-af can, and is controlling the node over LNDC.

I also created a websocket RPC proxy - which behaves the same as the original websocket RPC, just tunnels the commands over LNDC. When you run this proxy from the lit host, it will use the same key as lit-af, which means it will be authorized by default. When using it from a remote host (or from a mobile phone), you need to provide it with a key to use.

This way, we can still support clients that use websocket RPC, just they can run anywhere - not just with lit on localhost.

delbonis commented 6 years ago

There is an extra parameter to lit-af (addr) that specifies the ln address of the host we're going to control. So starting lit-af for a remote host would look something like this: lit-af -node 1.2.3.4 -p 2448 -addr ln1hzcjphula5cxh5hpj3zqancy0jv7t2zvyz0wnt

Could we just use the same address format that's passed to con?

gertjaap commented 6 years ago

@delbonis Yeah that would be pretty easy. If we ensure it also supports the other scenarios that's probably more user-friendly. So:

I'll look into that.

gertjaap commented 6 years ago

retest this please

gertjaap commented 6 years ago

You can now use lit-af for both local (just give it no parameters) and remote in a uniform way.

So for local, you just do lit-af If you're running on another port, you can do lit-af -con <port> If you want to connect to a remote client, you do lit-af -con <ln1adr> If you know the hostname/port as well (and you don't want to or can't use the tracker) you do lit-af -con <ln1adr>@<host>:<port>

I also re-added the "traditional" RPC under a flag (unauthrpc) that you can switch on, and is off by default.

To me, this seems ready to merge. Feel free to chime in if you disagree.