mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 15:44:21 +01:00
doc: Add a readme to the cln-grpc proxy
These are some common questions that come up from time to time, so let's make sure we address them.
This commit is contained in:
144
plugins/grpc-plugin/README.md
Normal file
144
plugins/grpc-plugin/README.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# GRPC plugin for Core Lightning
|
||||
|
||||
This plugin exposes the JSON-RPC interface through grpc over the
|
||||
network. It listens on a configurable port, authenticates clients
|
||||
using mTLS certificates, and will forward any request to the JSON-RPC
|
||||
interface, performing translations from protobuf to JSON and back.
|
||||
|
||||
|
||||
## Getting started
|
||||
|
||||
The plugin only runs when `lightningd` is configured with the option
|
||||
`--grpc-port`. Upon starting the plugin generates a number of files,
|
||||
if they don't already exist:
|
||||
|
||||
- `ca.pem` and `ca-key.pem`: These are the certificate and private
|
||||
key for your own certificate authority. The plugin will only accept
|
||||
incoming connections using certificates that are signed by theis
|
||||
CA.
|
||||
- `server.pem` and `server-key.pem`: this is the identity
|
||||
(certificate and private key) used by the plugin to authenticate
|
||||
itself. It is signed by the CA, and the client will verify its
|
||||
identity.
|
||||
- `client.pem` and `client-key.pem`: this is an example identity that
|
||||
can be used by a client to connect to the plugin, and issue
|
||||
requests. It is also signed by the CA.
|
||||
|
||||
These files are generated with sane defaults, however you can generate
|
||||
custom certificates should you require some changes (see below for
|
||||
details).
|
||||
|
||||
## Connecting
|
||||
|
||||
The client needs a valid mTLS identity in order to connect to the
|
||||
plugin, so copy over the `ca.pem`, `client.pem` and `client-key.pem`
|
||||
files from the node. The RPC interface is described in the [protobuf
|
||||
file][proto], and we'll first need to generate language specific
|
||||
bindings.
|
||||
|
||||
In this example we walk through the steps for python, however they are
|
||||
mostly the same for other languages.
|
||||
|
||||
We start by downloading the dependencies and `protoc` compiler:
|
||||
|
||||
```bash
|
||||
pip install grpcio-tools
|
||||
```
|
||||
|
||||
Next we generate the bindings in the current directory:
|
||||
|
||||
```bash
|
||||
python -m grpc_tools.protoc \
|
||||
-I path/to/cln-grpc/proto \
|
||||
path/to/cln-grpc/proto/node.proto \
|
||||
--python_out=. \
|
||||
--grpc_python_out=. \
|
||||
--experimental_allow_proto3_optional
|
||||
```
|
||||
|
||||
This will generate two files in the current directory:
|
||||
|
||||
- `node_pb2.py`: the description of the protobuf messages we'll be
|
||||
exchanging with the server.
|
||||
- `node_pb2_grpc.py`: the service and method stubs representing the
|
||||
server-side methods as local objects and associated methods.
|
||||
|
||||
And finally we can use the generated stubs and mTLS identity to
|
||||
connect to the node:
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
from node_pb2_grpc import NodeStub
|
||||
import node_pb2
|
||||
|
||||
p = Path(".")
|
||||
cert_path = p / "client.pem"
|
||||
key_path = p / "client-key.pem"
|
||||
ca_cert_path = p / "ca.pem"
|
||||
|
||||
creds = grpc.ssl_channel_credentials(
|
||||
root_certificates=ca_cert_path.open('rb').read(),
|
||||
private_key=key_path.open('rb').read(),
|
||||
certificate_chain=cert_path.open('rb').read()
|
||||
)
|
||||
|
||||
channel = grpc.secure_channel(
|
||||
f"localhost:{grpc_port}",
|
||||
creds,
|
||||
options=(('grpc.ssl_target_name_override', 'cln'),)
|
||||
)
|
||||
stub = NodeStub(channel)
|
||||
|
||||
print(stub.Getinfo(node_pb2.GetinfoRequest()))
|
||||
```
|
||||
|
||||
In this example we first local the client identity, as well as the CA
|
||||
certificate so we can verify the server's identity against it. We then
|
||||
create a `creds` instance using those details. Next we open a secure
|
||||
channel, i.e., a channel over TLS with verification of identities.
|
||||
|
||||
Notice that we override the expected SSL name with `cln`. This is
|
||||
required because the plugin does not know the domain under which it
|
||||
will be reachable, and will therefore use `cln` as a standin. See
|
||||
custom certificate generation for how this could be changed.
|
||||
|
||||
We then use the channel to instantiate the `NodeStub` representing the
|
||||
service and its methods, so we can finally call the `Getinfo` method
|
||||
with default arguments.
|
||||
|
||||
## Generating custom certificates
|
||||
|
||||
The automatically generated mTLS certificate will not know about
|
||||
potential domains that it'll be served under, and will chose a number
|
||||
of other parameters by default. If you'd like to generate a server
|
||||
certificate with a custom domain you can use the following:
|
||||
|
||||
|
||||
```bash
|
||||
openssl genrsa -out server-key.pem 2048
|
||||
```
|
||||
|
||||
This generates the private key. Next we create a Certificate Signature Request (CSR) that we can then process using our CA identity:
|
||||
|
||||
```bash
|
||||
openssl req -key server-key.pem -new -out server.csr
|
||||
```
|
||||
|
||||
You will be asked a number of questions, the most important of which
|
||||
is the _Common Name_, which you should set to the domain name you'll
|
||||
be serving the interface under. Next we can generate the actual
|
||||
certificate by processing the request with the CA identity:
|
||||
|
||||
```bash
|
||||
openssl x509 -req -CA ca.pem -CAkey ca-key.pem \
|
||||
-in server.csr \
|
||||
-out server.pem \
|
||||
-days 365 -CAcreateserial
|
||||
```
|
||||
|
||||
This will finally create the `server.pem` file, signed by the CA,
|
||||
allowing you to access the node through its real domain name. You can
|
||||
now move `server.pem` and `server-key.pem` into the lightning
|
||||
directory, and they should be picked up during the start.
|
||||
|
||||
[proto]: https://github.com/ElementsProject/lightning/blob/master/cln-grpc/proto/node.proto
|
||||
Reference in New Issue
Block a user