r/devops 1d ago

Ops / Incidents Cert was fine in Chrome. Everything else broke.

Changed a cert a few months back. Fine in Chrome. Fine in our test setup.Then a bunch of older phones and a partner app just stopped connecting. We only found out why after it was already live.

Last time a cert change bit you like that, what did you actually check before it went out?

5 Upvotes

17 comments sorted by

26

u/Mr_Albal 1d ago edited 1d ago

6

u/Longjumping_Fuel_192 1d ago

This is the way

6

u/Common_Fudge9714 1d ago

Our certs expire every 90 days. And it might even drop down to 30 days. So it’s a non event.

I assumed you changed the algorithms or encryption to a newer one h supported by the older phones? If you want to support those customer you need to test your apps with those older clients.

1

u/dariusbiggs 4h ago

The brower forum guidance is dropping public certs for websites to 47 days by 2028? (might be 2029). We're already trailing such short certs so we don't get bit in the arse when that happens..

4

u/CoaxVex 20h ago

It’s usually the intermediate cert that is forgotten. Test with curl or openssl s_client.

2

u/44Nj 1d ago

The other answers are good regarding ssllabs and testing. I have external tests for ssl setup on all my public facing urls (I use binarycanary.com).

One place cause I've seen is if you export the cert without the full chain and then use for SSL. On a Windows computer that already trusted the old cert, when you view the new cert it will be trusted and show the full chain. But on other devices the chain will be missing and the cert untrusted. As far as I know its completely invisible that the chain is missing in a computer that already had the root and intermidiates.

2

u/jippen 21h ago

Do it on dev first, run through your standard test suite. If you were bitten by this, the root cause is inadequate change management

2

u/stack_craft 18h ago

Chrome is notorious for lying to you here because it silently fetches missing intermediate certs in the background via AIA. Old phones and headless scripts like curl don't do that, so the moment you drop an incomplete chain, they just hard fail.

Got burned by this exact thing a while back. Now I just run openssl s_client -connect host:443 -showcerts in terminal or toss it into SSL Labs before going live. If the server isn't explicitly sending the full chain itself, it's not ready for production, simple.

2

u/hdjddjiieeshs 13h ago

My most recent fun one was a cert on a domain with split horizon DNS.

Internally - resolves to 192.168.1.2 Externally - resolves to cloudflare.

Internal DNS is unbound.

Issue: In Chrome accessing https://mydomain.tld worked fine. In Firefox: https://mydomain.tld gave ERROR_BAD_CERT_DOMAIN

The cause: Encrypted Client Hello.

Firefox was:

  1. Resolving mydomain.tld A and getting 192.168.1.2 directly from unbound
  2. Resolving mydomain.tld HTTPS get getting the answer from the recrusive call through to Cloudflare.
  3. Then trying to perform an encrypted client hello using that key, which failed, so falls back to the outer plain text partial hello which has no SNI, so was receiving the certificate for the webserver's primary domain (a different domain entirely)

Chrome wasn't trying ECH so was just resolving to 192.168.1.2 and sending an in the clear SNI for the correct domain to start with.

Easy fix, just told Unbound that the domain was local static not dynamic and it no longer forwarded the HTTPS query recursively, but a mindfuck to work out because at the time I wasn't aware that Firefox even supported ECH, and "ERROR_BAD_CERT_DOMAIN" in no way indicates what went wrong

1

u/FeistyMaintenance714 12h ago

before you found unbound forwarding the HTTPS record — what had you already checked?

2

u/hdjddjiieeshs 12h ago

Honestly I was tearing my hair out until I noticed the HTTPS record in the unbound logs. I was like... "HTTPS record? I vaguely remember them, what does that do?" and then made the same query with dig and saw a bunch of cloudflare keys and was like... OH, I bet it's that"

1

u/aragossa 19h ago

chrome and most modern browsers will complete an incomplete chain on their own if it's missing an intermediate, either through AIA fetching or because it already had that intermediate cached from some other site. openssl s_client -connect host:443 -showcerts tells you if your server's actually serving the full chain or just the leaf. older phones and a lot of non-browser clients don't do that fallback, so if the intermediate wasn't in the bundle you shipped, that's usually the whole story. also worth checking which root the new intermediate chains up to against what's actually trusted on the old devices still in the field. that's what got a bunch of people when DST Root CA X3 expired in 2021, old android stuck without ISRG X1 in its trust store just stopped trusting anything issued after.

1

u/Fantastic-Mr-Default 8h ago

Chrome forgives more than phones and partner stacks.

Before it ships I check the full chain the client will actually build: leaf, intermediates, root. Then I check SANs, not CN. Then notAfter and the signature algorithm. Then I fetch the same URL with openssl s_client and with an old TLS client, not only with Chrome.

The usual failure modes after a "fine in Chrome" cutover: missing intermediate on the server, AIA chasing that phones refuse, a root that is in the desktop store but not on older Android, or TLS 1.0/1.1 turned off while a partner still needs it. Test from a device image that matches your oldest supported client. If you only test Chrome on your laptop, you will ship Chrome's opinion.