# Let's talk about certs! (`wss://` & `grpc`) ## Intended functionality ```mermaid sequenceDiagram participant UserClient participant Greenlight participant UserNode autonumber alt Node registration UserNode ->> Greenlight: Establish reverse tunnel Greenlight ->> Greenlight: Register UserNode as backend end alt Client connects to Node UserClient ->>+ Greenlight: TLS clientHello + SNI Greenlight ->> Greenlight: Extract SNI header & look up node tunnel Greenlight ->>- UserNode: Establish connection loop Communicate UserClient ->> UserNode: Query UserNode ->> UserClient: Response end end ``` ### Requirements - `UserNode` must not be able to impersonate other nodes, i.e., certificate has to be valid only for the subdomain including its `node_id` - The ZeroSSL API access must not be done from the `UserNode`, and `Greenlight` must verify the constraints - The reverse proxy must not be able to see the encrypted content of a connection, but may see traffic metadata (best we can do?). This can be done with SNI. - The domain should be constant and include the `node_id`. We will use `[node_id].gl.blockstream.com` as a placeholder for the actual domain, but the `[node_id]` will be part of the generated domain. - Subdomain names are restricted to 64 bytes in length. The raw `node_id` is 66 bytes when hex encoded, but only 64 bytes when `bech32` encoded (with `ln` HRP), and 44 bytes when `base64` encoded. - Can use either `http-01` or `dns-01` ACME challenge-response scheme to verify ownership of the domain - `http-01` might require an extra round between `Greenlight` and `UserNode` to communicate the `challenge` to the node - `dns-01` can be done purely on the `Greenlight` side, but may be slower and requires an API for the DNS configuration ## Generating a node certificate ```mermaid sequenceDiagram participant ZeroSSL participant Greenlight participant UserNode autonumber UserNode ->> UserNode: Generate Keypair & CSR UserNode ->> Greenlight: RenewCert Greenlight ->> Greenlight: Verify CSR Greenlight ->> ZeroSSL: Sign CSR ZeroSSL -> UserNode: Verify (Challenge-Response) ZeroSSL ->> Greenlight: Deliver Cert Greenlight ->> UserNode: Deliver Cert ``` ## Optional / Considerations - The simple subdomain schema allows for only one service to be exposed. We could allow further subdomains to split out services by name. E.g., `wss.[node_id].gl.blockstream.com` and `grpc.[node_id].gl.blockstream.com` - There can be as many of these reverse tunnels as desired, we will operate one, so apps can always talk to their associated node. - A similar construction could be used to shield the P2P port of a node and give it a constant name. However the `noise_xk` construction explicitly prevents us from identifying the intended destination from the handshake, so we'd have to differentiate them by port instead.