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