Kort svar
"self signed certificate in certificate chain" betyder at klienten fandt et selvsigneret certifikat (typisk en root) i kæden, som ikke ligger i klientens trust store. Enten taler du med en server der bruger en intern CA, eller også sidder en TLS-inspektions-proxy i midten og genudsteder certifikater med sin egen root. Fixet er at tilføje den rigtige root til trust store'en — ikke at deaktivere certifikat-validering.
OpenSSL-koderne 18 og 19
I openssl s_client-output svarer fejlen til to verify-koder:
- 18 —
self signed certificate: serverens leaf-certifikat er selv selvsigneret (ingen rigtig CA bag). - 19 —
self signed certificate in certificate chain: kæden ender i en selvsigneret root som klienten ikke stoler på.
openssl s_client -connect internal.example.com:443 -servername internal.example.com 2>/dev/null \ | grep "Verify return code"
De tre typiske årsager
- TLS-inspektion (corporate proxy): Mange virksomheder dekrypterer udgående HTTPS i en proxy/firewall, der genudsteder hvert certifikat med virksomhedens egen root. Klienter på maskiner uden den root installeret fejler. Det er derfor det "virker hjemme, men ikke på kontoret".
- Intern CA: Serveren bruger et certifikat fra en privat PKI. Roden skal distribueres til alle klienter (typisk via MDM/GPO), ellers fejler valideringen.
- Forkert genereret selvsigneret certifikat: En udvikler lavede et selvsigneret certifikat til et miljø der nu rammes af rigtige klienter.
Sådan retter du det — den rigtige måde
Tilføj den selvsignerede root til klientens trust store, så valideringen igen er meningsfuld:
# Linux (system-wide) sudo cp corporate-root.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates # Test specifikt mod en kendt root uden at ændre systemet openssl s_client -connect internal.example.com:443 -CAfile corporate-root.crt # curl mod en intern CA curl --cacert corporate-root.crt https://internal.example.com
For Java og .NET skal root'en ind i den relevante trust store i stedet for systemets — se "virker i browser, ikke i Java/.NET".
Det du IKKE skal gøre
Fristelsen er at slå validering fra: curl -k, verify=False i Python, eller NODE_TLS_REJECT_UNAUTHORIZED=0. Det får fejlen til at forsvinde — og fjerner samtidig hele beskyttelsen mod man-in-the-middle. Kode der kører i produktion med validering slået fra er en sårbarhed, ikke et fix. Tilføj den korrekte root i stedet.
Hold styr på interne og selvsignerede certifikater
Selvsignerede og interne certifikater er svære at holde styr på, fordi de ikke dukker op i offentlige Certificate Transparency-logs. CertControl opdager også interne endpoints via collector-agenten, viser hvilke der bruger selvsignerede eller intern-CA-certifikater, og sporer deres udløb — så de ikke bliver et blindt punkt i jeres certifikat-overblik.
Ofte stillede spørgsmål
Hvorfor virker det hjemme men ikke på arbejdspladsen?
Fordi firmanetværket sandsynligvis kører TLS-inspektion: en proxy dekrypterer trafikken og genudsteder certifikater med firmaets egen root. Den root er installeret på firma-administrerede maskiner, men ikke på din egen.
Er det sikkert at tilføje en intern root til trust store'en?
Ja, hvis du stoler på den part der ejer root'en (typisk din egen organisation). Det er den korrekte måde at håndtere interne CA'er på. Det er noget helt andet end at slå validering helt fra.
Hvad er forskellen på kode 18 og 19?
Kode 18 betyder at serverens eget certifikat er selvsigneret. Kode 19 betyder at kæden ender i en selvsigneret root som klienten ikke stoler på — ofte en intern CA eller en inspektions-proxy.
Kan jeg ikke bare bruge curl -k?
Du kan, men så validerer du ikke længere serverens identitet og er sårbar over for man-in-the-middle. Brug det højst til engangs-fejlfinding, aldrig i kode der kører i produktion.