# How CFnew Automatically Fetches ECH Configuration

> Learn how CFnew fetches ECH configuration automatically by querying DoH resolvers. It decodes Base64 responses and injects binary data into headers and proxy URLs for seamless integration.

- Repository: [byJoey/cfnew](https://github.com/byJoey/cfnew)
- Tags: how-to-guide
- Published: 2026-05-23

---

**CFnew dynamically retrieves Encrypted Client Hello (ECH) configuration by querying DNS-over-HTTPS (DoH) resolvers during each subscription refresh, automatically decoding Base64 responses and injecting the binary configuration into HTTP headers and proxy URLs.**

The `byJoey/cfnew` project implements a fully automated ECH pipeline that eliminates manual certificate configuration. When users enable ECH support in the interface, the system transparently handles DNS resolution, binary decoding, and parameter injection without requiring additional intervention. Understanding how CFnew automatically fetches ECH configuration reveals a resilient architecture built on redundant DoH queries and real-time integration into generated proxy links.

## Enabling ECH in the CFnew Interface

### The Global Enable Flag

The ECH workflow begins in the user interface defined in `明文源吗`. When a user toggles the **Enable ECH** option, the application sets a global boolean flag:

```javascript
// Lines 568-585 in 明文源吗
enableECH = echControl === 'yes' || enableECH === true;

```

This `enableECH` variable acts as the gatekeeper for all subsequent ECH operations. The state persists across sessions and automatically triggers the fetching routine during the next subscription refresh cycle.

### Custom Domain Configuration

Users can override the default ECH endpoint (`cloudflare-ech.com`) through the custom domain input field. The application retrieves this preference using `getConfigValue` and validates the input before storing it in the `customECHDomain` variable:

```javascript
// Lines 571-579 in 明文源吗
const customECHDomainValue = getConfigValue('customECHDomain', '');
if (customECHDomainValue && customECHDomainValue.trim()) {
  customECHDomain = customECHDomainValue.trim();
}

```

If no custom domain is provided, the system defaults to `cloudflare-ech.com` for all ECH queries.

## Automated ECH Retrieval via DoH

### The fetchECHConfig Function

When a subscription refresh occurs, the application checks the `enableECH` flag and invokes `fetchECHConfig(domain)` with the resolved domain name (lines 2440-2442 in `明文源吗`). This asynchronous function manages the entire retrieval process:

```javascript
// Triggered during subscription refresh
if (enableECH) {
  const echDomain = customECHDomain || 'cloudflare-ech.com';
  await fetchECHConfig(echDomain);
}

```

The function encapsulates the DNS query logic, response decoding, and error handling required to obtain the raw ECH binary configuration.

### Dual Resolver Fallback Strategy

According to the source code in `明文源吗` (lines 2450-2581), `fetchECHConfig` implements a resilient two-tier resolver strategy:

1. **Google DoH** – Queries Google's `https://dns.google/resolve` endpoint for the HTTPS resource record of the target domain.
2. **Cloudflare DoH** – Automatically falls back to Cloudflare's `https://cloudflare-dns.com/dns-query` if the Google request fails or returns invalid data.

Each DNS request includes the `application/dns-json` accept header. The system extracts the ECH configuration from the answer section, supporting both direct binary responses and Base64-encoded payloads. Successful resolution populates the `echConfig` variable with the raw binary data and logs the source (Google-DNS, Cloudflare-DNS, or base64-decoded) to `debugSteps`.

### Debug Logging and Error Handling

If both DoH providers fail to return valid ECH data, the function updates `echDebugInfo` with detailed error messages while allowing the subscription refresh to continue without ECH protection. This ensures that network connectivity issues with public DNS resolvers do not break the core proxy functionality.

## Integrating ECH into Proxy Outputs

### Response Header Injection

After successfully obtaining `echConfig`, the application injects diagnostic headers into the HTTP response. As implemented in `明文源吗` (lines 2769-2773), the system adds:

- `X-ECH-Status: ENABLED`
- `X-ECH-Config-Length` (containing the byte length of the retrieved configuration)

These headers allow downstream Cloudflare Workers (configured via [`wrangler.toml`](https://github.com/byJoey/cfnew/blob/main/wrangler.toml)) to verify that ECH support is active and that the configuration payload matches expected sizes.

### URL Parameter Construction

During final link generation (lines 7888-7914 in `明文源吗`), the system conditionally appends the ECH domain to the proxy URL only when `enableECH` is true:

```javascript
let link = `${proto}://${user}@${safeIP}:${port}?encryption=none&security=tls&sni=${workerDomain}&fp=${enableECH ? 'chrome' : 'randomized'}&type=ws&host=${workerDomain}&path=${wsPath}`;

if (enableECH) {
  const echDomain = customECHDomain || 'cloudflare-ech.com';
  link += `&ech=${echDomain}`;
}

```

The `ech` parameter signals the underlying Cloudflare Worker to negotiate ECH using the previously fetched configuration. The fingerprint (`fp`) also switches from `randomized` to `chrome` when ECH is enabled, ensuring compatibility with the encrypted handshake requirements.

## Summary

- CFnew uses a global `enableECH` flag triggered by UI interaction to activate the ECH pipeline.
- The `fetchECHConfig` function in `明文源吗` retrieves fresh ECH configuration from Google DoH, falling back to Cloudflare DoH if necessary.
- Raw ECH binary data is extracted from DNS responses, supporting both direct and Base64-encoded formats.
- Diagnostic headers (`X-ECH-Status` and `X-ECH-Config-Length`) are injected into responses for downstream verification.
- Generated proxy links automatically append the `ech` parameter when ECH is enabled, using either custom user domains or the default `cloudflare-ech.com`.

## Frequently Asked Questions

### What happens if both Google and Cloudflare DoH resolvers fail?

The `fetchECHConfig` function records the failure in `echDebugInfo` and updates the internal error logs, but the subscription refresh continues normally. In this scenario, the generated proxy links will not include the `ech` parameter, effectively disabling ECH for that session without interrupting connectivity.

### Can I use a custom ECH domain instead of cloudflare-ech.com?

Yes. The application reads the `customECHDomain` configuration value via `getConfigValue('customECHDomain', '')`. If you provide a valid domain in the UI, CFnew queries that domain's HTTPS resource records instead of the default `cloudflare-ech.com` endpoint.

### How is the ECH configuration encoded in the final proxy link?

The configuration itself is not transmitted in the URL. Instead, the link includes only the `ech` parameter containing the domain name (e.g., `&ech=cloudflare-ech.com`). The actual ECH binary (`echConfig`) is handled separately through headers and processed by the Cloudflare Worker backend configured in [`wrangler.toml`](https://github.com/byJoey/cfnew/blob/main/wrangler.toml).

### Does enabling ECH affect the TLS fingerprint in generated links?

Yes. When `enableECH` is true, the code sets the fingerprint parameter (`fp`) to `chrome` instead of `randomized`. This ensures compatibility with the Encrypted Client Hello handshake requirements, as shown in the link generation logic at lines 7888-7914 of `明文源吗`.