Wildcard certificate redirect subdomains to the first visited domains

Until now i had 3 separate certificates to serve both root domain and two other subdomains

certificate 1 (-d example.com) for example.com
certificate 2 (-d a.example.com) for a.example.com
certificate 3 (-d b.example.com) for b.example.com

and it works without problem. Now I would like to use a wildcard certificate to serve all of them, I correctly issued the certificate

certificate 4 (-d *.example.com -d example.com)

but when I use it on the 3 different istances of nginx I start to have a problem I can't solve:

I can correctly visit the first website I connect to in the browser but then I cannot reach the other two (or they redirect me to the first visited); if i clear all the browser data I can again correctly connect to one of the three website but then again I cannot reach the others.

Here the nginx configurations:

  1. example.com
  server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name:443$request_uri;
}

  server {
    listen 443;
    server_name example.com;
    ssl_certificate /path/to/wildcard_cert_fullchain.pem;
    ssl_certificate_key /path/to/wildcard_cert_privkey.pem;
    [...]
}
  1. a.example.com
  server {
    listen 80;
    server_name a.example.com;
    return 301 https://$server_name:443$request_uri;
}

  server {
    listen 443;
    server_name a.example.com;
    ssl_certificate /path/to/wildcard_cert_fullchain.pem;
    ssl_certificate_key /path/to/wildcard_cert_privkey.pem;
    [...]
}
  1. b.example.com
  server {
    listen 80;
    server_name b.example.com;
    return 301 https://$server_name:443$request_uri;
}

  server {
    listen 443;
    server_name b.example.com;
    ssl_certificate /path/to/wildcard_cert_fullchain.pem;
    ssl_certificate_key /path/to/wildcard_cert_privkey.pem;
    [...]
}

I don't think is strictly browser related, maybe it's some problem with nginx configuration (caching maybe?) because it's causing problem even outside client browsing, in the communication between subdomains

1 Like

Hi @Mollio, and welcome to the LE community forum :slight_smile:

In order to obtain an LE wildcard cert you will need to use DNS authentication.
That is likely your biggest hurdle.
Once that works, you can either share that single wildcard cert or replicate the process to each server and have three separate similar wildcard certs.
[both will work - so either way is OK]

Q #1: Do you already have a wildcard cert?
It seems like you have one.

Q #2: Is there any other redirection used (that hasn't been shown)?
[or perhaps the HTML code itself has some sort of base reference assigned to the single domain]

1 Like

Hi @rg305! thank you for answering

Yeah, I already got a wildcard certificate

the only thing I forgot to mention is that the 3 separate webserver are behind a proxy server that redirect connection requests by SNI, then the webservers terminate the TLS

3 Likes

Q #3 The proxy server doesn't terminate TLS?

1 Like

no it doesn't, it routes the connection based on the SNI to the correct webserver in upstream

1 Like

So the proxy's only reason for existence is to share the single external IP to various SNI separated systems?

If so, we must assume that it is truly transparent and is NOT part of the problem.
:crossed_fingers:

2 Likes

exactly, it's out of the equation

1 Like

Q #4 Do you have individual access and error logs for each web server?
#4b If so, do they confirm the SNI separation?

1 Like

sure, every webserver got it's logs, each of them has proxy_protocol header passed over too

1 Like

So you have reviewed the logs and still can't figure out why you end up on the base domain server...

Q #2 (part B - again - and updated):

Is there anything in the HTML code or within an .htaccess file that might cause this?

1 Like

No, there're no such sort of restriction at html level.
Mind the problem occur only when I setup the single wildcard certificate (that has *.example.com example.com as SANs) on the three separate nginx configs. If I setup three different, not wildcard, certificate (example.com on webserver1, a.example.com on webserver2 and b.example.com on webserver3) all html connection are restricted to the correct webserver and don't interferes with each other
Wildcarding is a new territory for me and although i didn't expect such strange beheaviour from a certificate, the problem might be something related to the webserver configuration, ssl caching maybe? but I can't wrap my head around how the *.example.com instead of a.example.com could cause that with the webserver config I showed you in the OP

1 Like

some more info:
during the troubleshooting I narrowed down the problem a bit more, I noticed that once I visit the website that use the wildcard I cannot visit the other two anymore, even if those 2 do not use the wildcard certificate.
For example if I setup a.example.com to use the wildcard certificate (that again, contains both *.example.com and example.com as domains) but the other two webserver use the old normal certificate (so -d example.com certificate for example.com webserver and -d b.example.com certificate for b.example.com) and the first website that I visit through the browser (every browser behave the same) is a.example.com I cannot access the other two website; It's like that once the handshake happen with the a.example.com wildcard certificate the browser start to catch every call to b.example.com and to example.com and redirect them to a.example.com which gives me an error page.
If I delete the browser cache and cookies, and try again starting by visiting the other two sites first, they behave correctly, I can jump from one to another without problem. But as soon as I visit the one with the wildcard certificate I cannot visit them anymore

Then your system doing SNI logic is NOT doing it as you would expect.
Meaning that it may be doing it in reverse order and matching the SNI from the SAN.

SOLVED!

Writing those previous long messagges helped me because in the meantime I had other browser's pages open on another tabs and when I got back to them I tried to refresh the page that had an error on and it went to the correct website! So I thought that there was something on the webserver or proxy that has a cache timeout of more or less 10 minutes.
On the webserver I already did some test on the ssl cache but that was not the case so I got back to analyze the entire connection path and found the problem to be a misconfigured parameter in the proxy server, the proxy_timeout directive.
I didn't had that parameter specified on my configuration so it defaulted to a value of 10 minutes; set it up to 3 seconds et voilà! problem solved :heart_eyes:

thank you for your support @rg305 , I hope that this can help someone in the future

1 Like

after some testing, I can't do that, it feels like clunky workaround because even if it solve that problem, new ones arises: when those webservers need some time (>3s) to process and serve the content, the connection is terminated early and fails to do so. Anyway here's the proxy stream block configs:

stream {

  map $ssl_preread_server_name $upstream {
    default          0.0.0.0;
    example.com      upstream_example;
    a.example.com    upstream_a_example;
    b.example.com    upstream_b_example;

  }

  server {
    listen 10.1.1.10:443;
    ssl_preread on;
    proxy_protocol on;
    proxy_connect_timeout 5s;
    proxy_timeout 10m;
    proxy_pass $upstream;
  }

  upstream upstream_example {
    server 10.1.1.11:443;
  }

  upstream upstream_a_example {
    server 10.1.1.12:443;
  }

  upstream upstream_b_example {
    server 10.1.1.13:443;
  }

}

@rg305 is the SNI match config correct?

I can't really get why the server_name read creates this domain overlap, it makes no sense to me

did some progress and inspecting the tcp packets with tcpdump i found that the SNI present in the hello packets of connections to ALL three webserver is always example.com, even for a.example.com and b.example.com so the proxy cannot distinguish where to route what

now it starts to makes sense but from here, how can I move forward?

EDIT: I was wrong, after some more digging to get the correct tcp data, I found that the command

tcpdump -i any -s 1500 '(tcp[((tcp[12:1] & 0xf0) >> 2)+5:1] = 0x01) and (tcp[((tcp[12:1] & 0xf0) >> 2):1] = 0x16)' -nnXSs0 -ttt

gives me the correct SNI value and it's indeed correct, I'll get some rest and tomorrow I'll try again

Although the logic/flow shown seems correct, it is all within one stream {}.
[with a server {} within it]
Can you show how is that stream is called / being used (anywhere else)?

I don't know if I got what you are asking, the stream block exist only on the proxy server instance and the tls connections are then terminated on the 3 backend servers as I showed you

On review, I can't find anything wrong with the code shown.

I would not use 10m for proxy_timeout, but that doesn't seem to cause the problem.

even 1m would be ok but indeed that's not where to look; this is driving me crazy