cloudflare / cloudflare/go

Creating a ECH client connection

Open
#138 6 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
370
Forks
62
PR merge metrics
No merged PRs in 30d

Description

I am trying to create an ECH connection as a client and I was hoping to use this fork in a proof of concept example.

Looking through the source it looks like if I specify `ECHEnabled: true` in my TLS config without specifying an `ECHConfig` it will fail over to GREASE.
I am missing on what value/how to create my own ECHConfig struct to pass that in so that I can get a legitimate ECH connection

Performing a `dig -t TYPE65 crypto.cloudflare.com` request provides me the following and I am assuming `ech=` is the config I need?
```
crypto.cloudflare.com. 198 IN HTTPS 1 . alpn="http/1.1,h2" ipv4hint=162.159.137.85,162.159.138.85 ech=AEb+DQBClAAgACCA88XUXJSY8yxlp6HWzE6uW3fyWQRcLW1e8o48eVAIfQAEAAEAAQATY2xvdWRmbGFyZS1lc25pLmNvbQAA ipv6hint=2606:4700:7::a29f:8955,2606:4700:7::a29f:8a55
```

I see you guys have an `ECHConfig` struct in `tls/ech_config.go` and clearly the tls config options take an array for that is there a marshaling function that I should be using with the raw value that comes back from the DNS lookup?

Also how then would I go about modifying the ClientHelloInner to point to the remote resource I am trying to access.

Sorry for the potentially naive questions, I've been reading over the source and trying to piece things together but I figured I might have better luck asking.

As an example of what I have so far in a toy example. I am fairly certain this is a successful GREASE request?
```go
func main() {
req, _ := http.NewRequest("GET", "https://crypto.cloudflare.com/cdn-cgi/trace", nil)

req.Host = "crypto.cloudflare.com"
req.Header.Set("User-Agent", "Mozilla/5.0")

client := http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
ServerName: "crypto.cloudflare.com",
ECHEnabled: true,
},
},
}

o, err:= client.Do(req)

/* Print response */
if nil != err {
log.Fatalf("Dump: %v", err)
}
bodyBytes, _ := io.ReadAll(o.Body)
fmt.Printf("%s\n", string(bodyBytes))
}
```
Thanks again for your time and work on this!

Contributor guide

Open the contributing guide

Research direction

Start with tls/ech_config.go and the TLS config options referenced in the issue, then compare them with the DNS TYPE65 record and the provided http.Client example. The issue would be complete when the supported client-side ECH flow, ECHConfig input, and ClientHelloInner usage are explained with a working example.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
networking, security
Issue type
Documentation
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.