---
# System prepended metadata

title: 'Let''s talk about certs! (`wss://` & `grpc`)'

---

# 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.