#grpc #lightning #certificate #mtls #json-rpc #plugin #bitcoin

app cln-grpc-plugin

Core Lightning插件,重新暴露JSON-RPC通过grpc。身份验证通过mTLS进行。

3个版本

0.1.6 2024年6月5日
0.1.5 2024年3月8日
0.1.4 2023年11月22日

#2961 in 神奇豆

每月下载量38

MIT许可证

2.5MB
57K SLoC

C 34K SLoC // 0.1% comments Rust 23K SLoC // 0.0% comments Python 547 SLoC // 0.1% comments

Core Lightning的GRPC插件

此插件通过grpc在网络上暴露JSON-RPC接口。它监听可配置的端口,使用mTLS证书验证客户端,并将任何请求转发到JSON-RPC接口,执行从protobuf到JSON的转换以及反向转换。

入门

只有当lightningd配置了选项--grpc-port时,插件才会运行。启动插件时,如果文件不存在,会生成一些文件:

  • ca.pemca-key.pem:这是您自己的证书授权机构(CA)的证书和私钥。插件只接受由该CA签名的证书的传入连接。
  • server.pemserver-key.pem:这是插件用于验证其身份的标识(证书和私钥)。它由CA签署,客户端将验证其身份。
  • client.pemclient-key.pem:这是一个示例身份,客户端可以使用它连接到插件并发出请求。它也由CA签名。

这些文件使用合理的默认值生成,但是如果您需要一些更改,可以生成自定义证书(详细信息见下文)。

连接

客户端需要有效的mTLS身份才能连接到插件,因此需要从节点复制 ca.pemclient.pemclient-key.pem 文件。RPC接口在 protobuf文件 中描述,我们首先需要生成特定语言的绑定。

在这个例子中,我们将逐步介绍Python的步骤,但对于其他语言也大致相同。

我们首先下载依赖项和 protoc 编译器

pip install grpcio-tools

接下来,我们在当前目录中生成绑定

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

这将在当前目录中生成两个文件

  • node_pb2.py:描述我们将与服务器交换的protobuf消息。
  • node_pb2_grpc.py:代表服务器端方法的服务和方法的存根,作为本地对象及其相关方法。

最后,我们可以使用生成的存根和mTLS身份连接到节点

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()))

在这个例子中,我们首先定位客户端身份以及CA证书,以便我们可以使用它来验证服务器的身份。然后,我们使用这些详细信息创建一个 creds 实例。接下来,我们打开一个安全通道,即具有身份验证的TLS通道。

注意,我们用 cln 覆盖了预期的SSL名称。这是必要的,因为插件不知道它将通过哪个域名访问,因此将使用 cln 作为替代。有关如何更改此内容的说明,请参阅自定义证书生成。

然后,我们使用该通道实例化代表服务和其方法的 NodeStub,因此我们可以最终使用默认参数调用 Getinfo 方法。

生成自定义证书

自动生成的mTLS证书将不知道它将被服务的潜在域名,并且将默认选择一系列其他参数。如果您想生成具有自定义域名的服务器证书,可以使用以下内容

openssl genrsa -out server-key.pem 2048

这生成了私钥。接下来,我们创建一个证书签名请求(CSR),然后我们可以使用我们的CA身份对其进行处理

openssl req -key server-key.pem -new -out server.csr

您将回答许多问题,其中最重要的是 通用名称,您应该将其设置为在下面为接口提供服务的域名。然后,我们可以通过使用CA身份处理请求来生成实际的证书

openssl x509 -req -CA ca.pem -CAkey ca-key.pem \
  -in server.csr \
  -out server.pem \
  -days 365 -CAcreateserial

这将最终创建由CA签名的 server.pem 文件,允许您通过其实际域名访问节点。现在,您可以将 server.pemserver-key.pem 移动到lightning目录中,它们应在启动时被拾取。

依赖项

~27–40MB
~664K SLoC