Skip to content

Creating a ECH client connection #138

@mbinns

Description

@mbinns

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=<value> 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?

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions