Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
What's Inside a TLS Certificate? X.509, SAN, Chain of Trust and File Formats
A TLS certificate is an X.509 document, signed by a CA, that binds a public key to the names in its SAN list; the client trusts it because the chain of signatures reaches a root in its trust store. With real runs we read the fields with openssl and .NET's X509CertificateLoader, and see the one-level limit of wildcards, Let's Encrypt's cross-signed Generation Y chain, and how a missing intermediate breaks curl but is hidden in .NET by AIA.
The Certificate Lifecycle: CSR, Domain Validation, Certificate Transparency, Revocation and the 47-Day Future
A certificate is requested with a CSR, the CA validates the domain with HTTP-01, DNS-01 or TLS-ALPN-01, the certificate is written to CT logs, and revocation now rests on CRLs and short lifetimes rather than OCSP. With SC-081v3 the maximum lifetime drops to 200 days on 15 March 2026, 100 in 2027 and 47 in 2029; through crt.sh, a real CRL and CSR generation in .NET we see why manual renewal is over.
Automatic Certificates with Let's Encrypt and ACME: Certbot, Nginx, Wildcards and Renewal with ARI
Getting a certificate with ACME takes account, order, authorization, challenge and finalize steps; Certbot does it on Nginx with webroot or the nginx plugin, gets wildcards with DNS-01, and thanks to ARI renews when the CA suggests. With real runs on Pebble we watch a revoked certificate renew itself through ARI, and look at profiles, 6-day and IP certificates, and the cost of closing port 80.
Certificates in .NET and Kestrel: dev-certs, Loading PEM/PFX, SNI, Reload on Renewal and HttpClient Validation
Kestrel reloads a PEM or PFX certificate from configuration without a restart, but it watches only Path, notices the change in about five seconds and restarts the endpoint; as a non-root user it cannot read Certbot's files, so a deploy hook is needed. With real runs we look at dev-certs' SSL_CERT_DIR setting on Linux, SNI with ServerCertificateSelector, and trusting an internal CA in HttpClient with CustomRootTrust instead of turning validation off.
Certificates on Managed Platforms: Caddy, Azure App Service, Key Vault, Front Door and cert-manager on Kubernetes
On managed platforms the platform obtains and renews the certificate, but each has a limit that will catch you: Caddy hits rate limits without a /data volume, the App Service managed certificate has no wildcard, Front Door wants a direct CNAME, and cert-manager changes the key on every renewal. With real runs of Caddy, cert-manager and Envoy Gateway against Pebble, we watch pinning break on renewal.
Enforcing HTTPS: HTTP→HTTPS Redirects, Rolling Out HSTS Gradually, Preload and Mixed Content
To enforce HTTPS you redirect at the layer where TLS terminates, reject HTTP with 400 instead of redirecting on APIs, and roll HSTS out gradually from 5 minutes to a year; a subdomain inventory is a must before includeSubDomains. With real runs we see the UseHttpsRedirection loop and the non-secure cookie behind a proxy, 301 turning a POST into a GET, HSTS locking an HTTP-only subdomain, and an absolute http:// URL in an Angular build being blocked as mixed content.
mTLS and Internal Certificates: Client Certificate Authentication in ASP.NET Core and Running Your Own CA
In mTLS the client also proves its identity with a certificate and a signature made with its private key; because public CAs are dropping the client authentication EKU, you need your own internal CA with an offline root. In ASP.NET Core we set up AddCertificate with CustomRootTrust and issuer-and-CN partner mapping, and with real runs we see Kestrel's silent rejection at the TLS layer, revocation, and how Nginx forwarding the certificate in a header can be faked without the private key.
Monitoring Certificates and Preventing Outages: Inventory, Expiry Alerts, TLS Testing and Real Incident Examples
To prevent certificate outages you measure the certificate the client sees from the outside, not the file on disk: a lifetime-based alert on the blackbox exporter's last_chain metric, a probe_success alert, and an inventory with CT logs and CAA. In the lab we reproduce an unreloaded renewal, a missing intermediate, a wrong SAN, a cross certificate that misleads earliest_cert_expiry and clock skew, and test the alerts with promtool and the TLS config with testssl.sh.