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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions