China is now blocking all encrypted HTTPS traffic that uses TLS 1.3 and ESNI

I have just read this article about china blocking traffics that’s set up with new technologies like TLS 1.3 and ESNI (Encrypted Server Name Indication).

I’m not sure if my caddy would still work with this setup (in China) out of the box. Would you mind sharing your thoughts about this here?

Caddy supports TLS 1.2 and 1.3, you can reduce your TLS support to 1.2 only if that would help.

I assume there is a way to only do so for IP from China (Geolocation, although would not affect any user in China using VPN services, they may not be affected by that block in the first place though). If not, you may need two instances of Caddy if you want to allow TLS 1.3 for everyone else.

I don’t think you’d need 2 Caddy instances, especially if they’re running on the same machine.

I don’t know if you can configure Caddy to only serve TLS 1.2 to an IP range and additionally permit TLS 1.3 for any other IP. If Caddy cannot do that, then two instances would make sense as a workaround? (One would allow the non-China IP range in, while the other would only respond to that China IP range)

The article mentions it’s only when ESNI is also used with TLS 1.3, I assume the client negotiates TLS 1.3 with the server before making a request with that, which might only happen if the server reports ESNI support? (appeared to be an extension for TLS 1.3) If so then Caddy just needs to be able to toggle ESNI off instead and can still use TLS 1.3 with China. Although you’d perhaps still have the same issue of wanting to allow that for users outside of China.

Not currently, but it’s designed for it!

What you’re looking for is a TLS connection policy “matcher” module: https://caddyserver.com/docs/json/apps/http/servers/#tls_connection_policies/match

These allow you to customize what kind of TLS configuration Caddy uses based on whatever matches the client’s TLS ClientHello. Part of that is the client’s (remote’s) IP address. We already have one such matcher for HTTP requests: https://caddyserver.com/docs/modules/http.matchers.remote_ip

So, adding a remote IP module for TLS connections is easy breezy – we can copy or borrow the logic from the existing HTTP request matcher module. Then voila, you can serve one TLS ServerHello to some clients based on their IP address, and another ServerHello to all others.

However, this almost certainly won’t be exposed in the Caddyfile (anytime soon).

1 Like

That’s awesome!

That’s less awesome (but understandable) :stuck_out_tongue:

It could just be my misunderstanding though. I’ve only ever seen the JSON config as something that’s modified via a REST interface, if you can similarly modify a JSON file and provide that just like the Caddyfile, that’s all good too. I realize it’s not difficult to use the API for JSON, I’ve got Insomnia setup with snippets for easily doing so, but I do find Caddyfile nice and quick for learning/experimenting.


Does Caddy export OpenAPI v3 or similar for making adoption with tools like Insomnia even easier? Currently I have to look up the docs and create/type out what I want to try. I remember it not always being entirely clear and having to guess a few attempts until I got the outcome I was expecting.

If OpenAPI v3 is supported, you could also get nice doc generation with ReDoc, see an example here.

Yep that’s how it works. The default is JSON. Caddy checks if the filename starts with “Caddyfile” and uses the Caddyfile adapter if so (or you can specify the adapter to use).

JSON is the low-level, underlying config language of Caddy, the Caddyfile is a user-friendly higher level language. The Caddyfile brings a bit of magic to make things simpler, but you lose out on flexibility to a certain extent.

No but there is a plugin that generates a JSON schema from the loaded modules:

Feel free to work on setting up OpenAPI support if you find it valuable.

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.