A TLS certificate checklist for your website
Eight things to get right on every HTTPS site, how to check each one yourself, and which of them an outside-in scan reports.
By the TrustSek editorial team · Last reviewed
- Module
- TLS and web hygiene · 20%
- Expiry flagged
- Under 30 days
- Protocols
- TLS 1.2 and 1.3 only
A certificate problem is one of the few security issues every visitor sees. An expired certificate puts a full-page warning in front of your site, and API clients and apps simply stop connecting. Most of these failures are avoidable, and the rest are quick to find. This checklist covers what to get right on each HTTPS host, how to check it yourself, and what TrustSek reports.
The examples use example.com. Replace it with your own hostname.
1. Expiry: automate renewal
Certificates are getting shorter. Under the CA/Browser Forum's Baseline Requirements, publicly trusted TLS certificates issued from 15 March 2026 may be valid for at most 200 days. The limit falls to 100 days from 15 March 2027 and to 47 days from 15 March 2029. A process that relies on someone remembering once a year no longer works.
Automate renewal with ACME (RFC 8555), the protocol behind Let's Encrypt and supported by many commercial certificate authorities, or use your platform's managed certificates. Then check that the automation actually runs:
- renewal starts well before expiry, typically when about a third of the lifetime remains
- the renewed certificate is loaded, which may need a reload of the web server, load balancer or CDN
- a failed renewal reaches a person, not only a log file
- certificates installed by hand (appliances, VPN gateways, old servers) are on a list with an owner and a date
Check the dates yourself:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -dates -issuer -subject
2. Chain: serve the intermediates
A server should send its own certificate followed by the intermediate certificates that link it to a trusted root. Browsers often repair a missing intermediate from their cache, so the site looks fine in your browser while command-line tools, older phones and other servers calling your API fail.
Check the chain the server actually sends:
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
Look for Verify return code: 0 (ok) and for more than one certificate in the output. Use the full-chain file your certificate authority or ACME client provides, not the leaf certificate alone.
3. Hostnames: cover every name you serve
A certificate is valid only for the names listed in its Subject Alternative Name (SAN) field. Browsers ignore the older Common Name. Make sure the certificate covers every name that reaches the server, typically both example.com and www.example.com, and any other names pointed at the same host.
Wildcards match one level only: *.example.com covers shop.example.com but not example.com itself, and not eu.shop.example.com. A wildcard also spreads one private key across many services, so a leak on one exposes them all. Prefer named certificates where automation makes that easy.
To see the names a certificate covers:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -ext subjectAltName
4. Protocol versions: TLS 1.2 and 1.3 only
TLS 1.0 and TLS 1.1 were formally deprecated by the IETF in 2021 (RFC 8996). RFC 9325 recommends TLS 1.2 as the minimum and TLS 1.3 (RFC 8446) wherever it is available. Still offering the old versions rarely helps a real user and is a visible sign that the configuration has not been reviewed.
On nginx, for example:
ssl_protocols TLSv1.2 TLSv1.3;
Test that the old versions are refused. A handshake that succeeds here means the server still accepts TLS 1.1 (your local OpenSSL build must itself still support it for the test to mean anything):
openssl s_client -connect example.com:443 -servername example.com -tls1_1 </dev/null
5. Ciphers: forward secrecy and AEAD
With TLS 1.2, the server chooses from the cipher suites you allow. Allow only suites with forward secrecy (ECDHE key exchange) and authenticated encryption (AES-GCM or ChaCha20-Poly1305). Disable RC4, DES and 3DES, export and NULL suites, and anything based on MD5. TLS 1.3 has a short, fixed list and needs no tuning.
Rather than writing a cipher string by hand, start from the Mozilla SSL Configuration Generator on its “intermediate” profile, which gives a tested configuration for common servers.
6. HSTS: stop the first request going out in cleartext
A redirect from http:// to https:// protects visitors only after their first request, which is still sent in cleartext and can be intercepted. HTTP Strict Transport Security (RFC 6797) tells the browser to use HTTPS for your site from then on, and not to let the user click through certificate warnings.
Strict-Transport-Security: max-age=31536000; includeSubDomains
Start with a short max-age, a few hours, to confirm nothing breaks, then raise it. Add includeSubDomains only when every subdomain serves HTTPS, because browsers cache the header and it is hard to undo. The preload list removes even the first cleartext request, but requires max-age of at least one year, includeSubDomains and preload, and is slow to leave. The security headers guide covers HSTS alongside the other headers.
7. CAA: name the authorities allowed to issue
A CAA record (RFC 8659) lists the certificate authorities allowed to issue certificates for your domain. Publicly trusted authorities must check it before issuing, so a request through any other authority is refused.
example.com. 3600 IN CAA 0 issue "letsencrypt.org"
example.com. 3600 IN CAA 0 issuewild ";"
example.com. 3600 IN CAA 0 iodef "mailto:security@example.com"
This example allows one authority, forbids wildcard certificates and asks for reports of refused requests. Before publishing, list every authority your organisation and your suppliers actually use, including CDNs and hosting platforms that issue on your behalf, or their renewals will start failing.
8. Certificate transparency: know what has been issued
Publicly trusted certificates are recorded in public certificate transparency (CT) logs (RFC 6962), and major browsers require it. Anyone can search those logs, which cuts both ways:
- you can see every certificate issued for your domain, and spot one you did not request
- anyone else can see every hostname you have put in a certificate, including staging and internal names
Search the logs for your domain now and then, for example on crt.sh, or use a CT monitoring service. Treat an unexpected certificate as a security event. Keep internal hostnames out of public certificates where you can.
How TrustSek reports these
TrustSek's TLS and web security module makes one TLS connection to port 443 on the domain you enter, plus one HTTPS and one HTTP request, as a browser would. It reads the certificate and the protocol version and cipher agreed in that handshake. It is a reading at one point in time, of that one host.
| Checklist item | What a scan reports | Severity |
|---|---|---|
| Expiry | SSL certificate expiring soon with under 30 days left; SSL certificate expired | High |
| Trust | Self-signed certificate | High |
| Connection | TLS handshake failed, when something listens on 443 but no TLS session completes | High |
| Protocol versions | Weak TLS version, when the handshake settles on TLS 1.0 or 1.1 | Medium |
| Ciphers | Weak cipher suites detected, when the agreed suite uses RC4, DES, 3DES, MD5, NULL, export or anonymous ciphers | High |
| HSTS | HSTS header missing on the HTTPS response | Medium |
| Redirect | HTTP not redirecting to HTTPS | Medium |
| CAA | CAA record missing, reported in the email security module with the other DNS records | Medium |
A site with no HTTPS at all is reported separately, and a certificate on the abuse.ch SSL Blacklist is a critical finding. Certificate transparency is used differently: TrustSek reads the CT logs to map your subdomains for the attack surface module.
What a scan does not check, so check it yourself with the commands above:
- Chain completeness and hostname coverage. The scan does not validate the chain the server sends or whether the certificate names match.
- Every version and cipher the server accepts. One handshake shows what the server agrees to with a modern client. A server that still accepts TLS 1.0 alongside TLS 1.3 will agree to 1.3, and the old version is not flagged.
- Other hosts. Only the domain you enter is connected to. Subdomains, mail servers and APIs on other names need their own checks.
- HSTS details. The scan reports whether the header is present, not its
max-ageor directives.
“No finding” means none of the conditions above were seen in that reading. It does not mean the host is secure. The methodology explains how severity feeds the score.
A short checklist
Renewal automated and alerting on failure. Full chain served. Every served name in the SAN list. TLS 1.2 and 1.3 only. Forward-secret AEAD ciphers. HSTS on every HTTPS response. CAA naming the authorities you use. Someone watching the CT logs for your domain.
Check your domain's certificate and TLS setup
See the certificate, protocol and headers your domain serves today, alongside email security and the rest of the outside-in score.
Sources
- RFC 8996: Deprecating TLS 1.0 and TLS 1.1
- RFC 9325: Recommendations for Secure Use of TLS and DTLS
- RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3
- RFC 8555: Automatic Certificate Management Environment (ACME)
- RFC 6797: HTTP Strict Transport Security (HSTS)
- RFC 8659: DNS Certification Authority Authorization (CAA) Resource Record
- RFC 6962: Certificate Transparency
- CA/Browser Forum: Baseline Requirements for TLS Server Certificates
- Mozilla SSL Configuration Generator
- HSTS Preload List Submission