Ability to pass ServerName indication (SNI) in fetch API

Hello Team,

I am trying to use this option which is already available in nodejs https module here is a SO discussion about this:

So, I guess basically the CF worker fetch init option needs to accept a new key servername for this to work:

response = await fetch(newURL, { method: new_method, 
                                       headers: new_headers, 
                                       servername: host}); 

Currently when I try similar construct, I get this error:

TLS peer’s certificate is not trusted; reason = Hostname mismatch

Background, our use-case: I am trying to set up a reverse-proxy solution for more than 100 servers which will be serving regional traffic for the domain tcl.com. The main issue here is IT operational related: even at the DNS level these regional sites are not under the tcl.com zone! And we can fairly assume, every-single one of them has a different IT team that maintain the infrastructure. However, in the current set up the regional sites accept the https traffic request based on IP (if the correct SNI is passed in the https request).

It sounds like you’re attempting to change the host header of the request? That’s specifically disallowed in workers. However it can potentially be done using page rules (or other methods depending on discussion with your account team) on an Enterprise zone.

https://www.cloudflare.com/plans/enterprise/contact/

1 Like

No, i am trying to pass SNI extension this is a HTTPS extension feature, and is NOT part of HTTP header!
Apparently the Fetch API does not support it.

Also, it would be a very complex solution if we need to maintain all those few hundered sites IP’s both on page rules, and also from within the worker code also they are NOT all on the tcl.com zone!

Changing SNI goes hand in hand with the host header. So @cscharff’s comment is accurate.

NodeJS HTTPS lib already support this, so in my workers can I just use this https lib instead of implementing the CF worker fetch APi to get my response from origins?

The point is that Cloudflare wont let you override the host header (be it on an SSL or HTTP level).

As @cscharff mentioned, an Enterprise plan might give you more freedom here however.

I am already overriding the host header successfully using the comment i found here

And for the most part the solution is working you can see the published result here:

The problem is: in this first case the origin host url that resolves without issue and TLS happens correctly for that host origin URL, for my other origins I don’t even have a good hostname for them that can handle TLS i just have the IP!

So your 100+ origins don’t present a proper certificate for the hostname you are calling it with, and you also don’t control the origin? That’s kind of bogus.

Is this scenario something that would be solved with a load balancer? Is the hostname/cert on all these origins the same, but you need to point to different origins?

That doesnt seem to override, it simply redirects the current request to a different hostname. The protocol semantics still are all in place.

i am sorry! Why this is bogus! you have your origins all with servers listening for the same servername (ww.tcl.com) requests and they can pretty happily handle TLS handshake if you can reach to them for ww.tcl.com! the thing is you can not publicly reach to them using that servername (you need to first reach them using IP and then do your TLS handshake using SNI)! this the exact reason SNI has been added to HTTPS specification in the first place btw.

Exactly, that’s why i asked in the title to extend the current workrer fetch api to accept passing SNI extension!

Which brings us back to @cscharff’s response :wink:

You cant override any host related information.

And I told you those origins are different IT departments… going back to them and tell them: hey please change all your sever-configs you’ve got new servernames! And then add them to tcl.com Zone, etc etc it’s like weeks (or even months) of planning and scheduling will all these parties. I guess i’d be better off just write smthg low level using NodeJS https lib myself which already properly supports SNI and forget about using official worker fetch API altogether! which is unfortuante btw it’s a nice and compact API

You told me?

It doesnt really matter whether they are different departments or not. On a regular plan Cloudflare simply does not allow what you want. You could talk with them about an Enterprise plan, however I do agree that it might be better to simply implement such a very custom implementation yourself.

Sorry, but you cannot override the SNI host with Workers.

Allowing SNI overrides could create the same kinds of security problems as overriding the Host header, as described here.

As described later in that thread, we do have an option called resolveOverride that sort of allows overriding the Host header, but only in a very specific way that is carefully controlled to avoid security problems.

However, we do not have any similar option for overriding SNI, and we don’t currently have any plans to add such an option.

1 Like

Thanks for your help, yeah i guess I will put together smthg using nodejs https lib.

Ok thanks! So does this mean even using nodejs https lib will not work in this case? So that would be a request/response in the context of worker but not using fetch API?

Workers is not based on Node.js, so those APIs are not available. The only way to make an HTTP request from a worker is by using fetch(). Sorry.

1 Like

That makes more sense, but the way to do this is by using a resolve override in the worker.

fetch(event.request, { cf: { resolveOverride: 'us-east.example.com' } })

Put your origin dns in the resolveOverride and it should hit that origin, but with the original request’s host/sni info.

You can manipulate most parts of a subrequest, the only requirement is that the SNI and the HTTP Host Header on the request are the same.

Thank you, so i guess this will be available only for enterprise accounts? (the resolveOverride feature I mean)