Why SSL/TLS Analysis Matters More Than Ever
When users type your domain into a browser, they aren’t just visiting a website—they’re connecting to a promise of privacy, authenticity, and integrity. That promise is delivered through SSL/TLS. Yet, misconfigurations are common: weak ciphers left enabled, outdated protocols still exposed, missing intermediate certificates, or features like OCSP stapling and HSTS forgotten. Each oversight can be a foothold for attackers or a source of reliability issues and browser warnings.
This practical guide walks you through running a comprehensive SSL/TLS analysis using the widely respected testssl.sh tool—and how to do it easily online via https://www.web-psqc.com/security/ssl. You’ll learn how to interpret the results, prioritize fixes, and apply secure, modern configurations for popular servers. Whether you manage a single site or a fleet of services, this guide helps you catch and correct weaknesses before they impact users.
What Is testssl.sh?
testssl.sh is a mature, open-source command-line tool that probes a server’s SSL/TLS configuration—from supported protocols and cipher suites to certificate health, key exchange properties, compression and renegotiation status, and susceptibility to known TLS vulnerabilities like Heartbleed, POODLE, SWEET32, ROBOT, and more. It’s favored by security engineers because it:
- Runs without installing anything server-side
- Works against any TCP service that speaks TLS (HTTPS, SMTP, IMAPS, etc.)
- Uses OpenSSL and its own checks for deep protocol coverage
- Provides precise, actionable diagnostics
If you don’t want to install or run anything locally, you can leverage an online runner to perform similar checks from the cloud.
Running testssl.sh Online in Minutes
You can run a deep SSL/TLS scan directly in your browser at: https://www.web-psqc.com/security/ssl
Here’s a straightforward workflow:
- Open the site and enter your domain or host.
- Examples: example.com, www.example.com:443, mail.example.com:993
- If you rely on SNI for multi-certificate hosting, include the hostname—not just the IP.
- Select any available options.
- Typical options include full vs. quick scans, IPv4/IPv6 preference, and potentially special checks.
- Start the scan and wait for results.
- Depending on the target, a full scan can take a few minutes.
- Review the results by section and copy them into your notes or ticket system for remediation.
- If export options are available, save a report for audit trails.
Tip: Only scan systems you control or have authorization to test. An SSL/TLS scan is active testing and may be logged by the target’s security systems.
When to Run an SSL/TLS Analysis
- Before go-live and after major changes (web server upgrades, CDN/WAF changes, load balancer migrations)
- After certificate renewals or switching CA providers
- When enabling new features (HTTP/2, HTTP/3/QUIC, mutual TLS)
- Periodically (e.g., monthly) as part of security hygiene
- During incident response or compliance audits
Understanding Your Results (And What to Do About Them)
Below are the core areas testssl.sh evaluates, common findings, and direct actions you can take to improve your security posture.
1) Connectivity, SNI, and IP Families
- What you’ll see: Whether the host is reachable on the specified port, SNI handling (correct certificate served for hostname), IPv4 vs. IPv6 differences.
- Why it matters: Many edge stacks terminate TLS per SNI; mismatches can serve the wrong cert. IPv6 listeners are sometimes overlooked and left misconfigured.
- Fixes:
- Ensure SNI is correctly configured for all virtual hosts.
- Mirror TLS configuration across IPv4 and IPv6 listeners.
- Confirm the same certificate is presented on both IP families (unless intentionally distinct).
2) Certificate Health and Chain Completeness
- What you’ll see: Subject, SANs, key type (RSA/ECDSA), signature algorithm (e.g., SHA-256), expiration, chain completeness (intermediates), OCSP stapling status.
- Common issues:
- Missing intermediate certificate leads to “incomplete chain” errors.
- Short lifetimes surprise teams that forget renewal automation.
- SHA-1 signatures still lurking on older chains (should be replaced).
- Fixes:
- Install the full chain (server cert + intermediates). Most CAs provide a chain file.
- Automate renewal using ACME (e.g., Let’s Encrypt) and reload the server on renewal.
- Prefer ECDSA or RSA 2048+ server certs signed with SHA-256 or stronger.
- Enable OCSP stapling for better performance and revocation signaling.
- Bonus:
- Dual-stack certificates (RSA and ECDSA) can optimize compatibility and performance. Some servers can present both via separate certificates and SNI/ALPN logic.
3) Supported Protocol Versions
- What you’ll see: SSLv2/3, TLS 1.0/1.1/1.2/1.3 enablement.
- Best practice:
- Disable SSLv2, SSLv3, TLS 1.0, and TLS 1.1.
- Require TLS 1.2 and TLS 1.3. TLS 1.3 provides improved security and a streamlined handshake.
- Fixes:
- Update server configs to limit protocols to TLSv1.2 and TLSv1.3.
- Confirm your load balancer/CDN and upstreams align with this policy.
- Watch for:
- Legacy client requirements. If business-critical devices only support TLS 1.0, isolate them on a separate endpoint with strict access controls and a clear retirement plan.
4) Cipher Suites and Server Cipher Order
- What you’ll see: Enabled cipher suites for each protocol, indication of weak/obsolete ciphers (3DES/RC4/EXPORT/NULL), whether server enforces its own cipher order.
- Best practice:
- Enforce server cipher order to prevent clients choosing weaker options.
- Prefer AEAD ciphers: AES-GCM and ChaCha20-Poly1305.
- Remove CBC-based suites for TLS 1.2 where feasible; use only strong ECDHE-based suites.
- TLS 1.3 has a modern suite set by design (no RSA key exchange, no CBC).
- Fixes:
- Prune 3DES (SWEET32), RC4, EXPORT, NULL, and MD5/SHA1-based suites.
- Ensure only ECDHE or DHE key exchange is allowed (no plain RSA key exchange).
- Practical consideration:
- For mobile-heavy audiences, allow ChaCha20-Poly1305 to favor devices without AES acceleration.
5) Key Exchange, Forward Secrecy, and Curves
- What you’ll see: Key exchange methods (ECDHE/DHE/RSA), supported curves, PFS status, DH parameter size.
- Best practice:
- Require forward secrecy: ECDHE preferred, DHE with at least 2048-bit parameters if needed.
- Curves: X25519 and prime256v1 (secp256r1) are widely recommended. Avoid weak/obscure curves.
- Fixes:
- Disable plain RSA key exchange in TLS 1.2; use ECDHE suites.
- Regenerate DH params to 2048 bits or higher if DHE is used.
- Update curve preferences to favor X25519 and prime256v1.
6) ALPN, HTTP/2, and HTTP/3 Readiness
- What you’ll see: ALPN advertisement (h2, http/1.1), NPN status (legacy), HTTP/2 capability; some stacks also expose HTTP/3/QUIC.
- Why it matters:
- HTTP/2 requires ALPN and specific cipher/feature compatibility; misconfigurations can block h2.
- Fixes:
- Enable ALPN and include h2 where supported.
- Ensure cipher suites are compatible with HTTP/2 (no blacklisted ciphers, avoid compression).
- If deploying HTTP/3, validate QUIC and certificates on the relevant UDP ports.
7) Session Resumption and Tickets
- What you’ll see: Session IDs and tickets enabled/disabled, ticket lifetime.
- Best practice:
- Session resumption improves performance; rotate ticket keys regularly.
- For highly sensitive contexts, consider limiting session ticket lifetime and disabling 0-RTT.
- Fixes:
- Configure reasonable lifetimes and scheduled ticket key rotation.
- Balance performance gains with privacy and replay risk considerations.
8) Compression and Renegotiation
- What you’ll see: TLS-level compression status, CRIME/BREACH risk indicators, renegotiation support.
- Best practice:
- Disable TLS compression. Mitigate BREACH at the application layer if compressing HTTP responses.
- Disable client-initiated renegotiation. Use secure renegotiation as required by modern stacks.
- Fixes:
- Review server flags for compression and renegotiation; hard-disable where possible.
- For BREACH, mask or randomize secrets in compressed responses, or avoid compression on sensitive pages.
9) Known Vulnerabilities
testssl.sh checks for a variety of named issues. Common examples:
- Heartbleed (CVE-2014-0160): Ensure OpenSSL and libraries are patched; rotate keys if you were vulnerable.
- POODLE (SSLv3): Disable SSLv3 entirely.
- BEAST: Effectively mitigated by using TLS 1.2+ and AEAD ciphers.
- SWEET32 (3DES): Remove 3DES-based suites.
- FREAK/Logjam: Remove export and weak DH parameters; use strong ECDHE or DHE.
- DROWN: Ensure SSLv2/3 disabled on all related endpoints; don’t share certs/keys with obsolete services.
- ROBOT: Disable vulnerable RSA key exchange and ensure modern TLS 1.2/1.3 suites.
- CCS injection/Lucky13/Zombie POODLE/GOLDENDOODLE: Keep libraries patched; prefer AEAD; use current server versions.
Fixes typically involve a combination of software updates and configuration tightening. After changes, re-run the scan to confirm remediation.
Concrete Examples: Reading and Acting on Results
Below is a fictitious snippet of output and what it implies:
Protocols:
SSLv3: disabled
TLS1.0: enabled
TLS1.1: enabled
TLS1.2: enabled
TLS1.3: enabled
Cipher suites (TLS1.2):
ECDHE-RSA-AES128-GCM-SHA256 (strong)
ECDHE-RSA-AES256-GCM-SHA384 (strong)
ECDHE-RSA-CHACHA20-POLY1305 (strong)
ECDHE-RSA-AES256-SHA (CBC) [WEAK]
ECDHE-RSA-3DES-EDE-CBC-SHA (3DES) [WEAK]
Certificate:
RSA 2048, SHA256, expires in 12 days [WARNING]
Chain: incomplete [FAIL]
Vulnerabilities:
SWEET32: vulnerable (3DES present)
ROBOT: not vulnerable
Heartbleed: not vulnerable
Actions:
- Disable TLS 1.0 and 1.1; keep TLS 1.2 and 1.3.
- Remove CBC and 3DES from TLS 1.2 list.
- Install the intermediate to complete the chain.
- Renew the certificate ASAP and set up automated renewal.
How to Fix: Example Server Configurations
Below are starting points. Tailor them to your environment and keep your server software up-to-date.
Nginx (HTTPS)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# TLS 1.2 strong suites (AEAD only) + let TLS 1.3 defaults stand
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:
ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256';
# Curves and PFS
ssl_ecdh_curve X25519:secp256r1;
# Session resumption
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 10m;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# HSTS (be cautious with preload)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# ALPN handled automatically; enable HTTP/2
listen 443 ssl http2;
Notes:
- Provide full chain in ssl_certificate and keep keys secure.
- If using ECDSA certs, include parallel RSA certs for legacy clients or leverage dual-cert features.
Apache HTTPD (mod_ssl)
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:
ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256
SSLHonorCipherOrder on
SSLOpenSSLConfCmd Curves X25519:secp256r1
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Protocols h2 http/1.1
HAProxy (TLS termination example)
frontend https-in
bind :443 ssl crt /etc/haproxy/certs/example.pem alpn h2,http/1.1
ssl-default-bind-ciphers ECDHE+AESGCM:ECDHE+CHACHA20
ssl-default-bind-options no-sslv3 no-tls-tickets
http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains"
default_backend web
Adjust ssl-default-bind-ciphers for your HAProxy version and OpenSSL features; consider enabling tickets with proper rotation if you need resumption.
Running testssl.sh Locally (Optional)
If you prefer command-line control or need to scan internal hosts:
-
Install prerequisites and clone:
- git clone https://github.com/drwetter/testssl.sh
- cd testssl.sh
-
Common commands:
- Full scan: ./testssl.sh example.com
- Faster scan: ./testssl.sh --fast example.com
- Specific port: ./testssl.sh example.com:8443
- IPv6: ./testssl.sh -6 example.com
- Protocols only: ./testssl.sh -p example.com
- Cipher suites: ./testssl.sh -S example.com
- JSON output: ./testssl.sh --jsonfile out.json example.com
- Input list: ./testssl.sh -iL hosts.txt
-
Tuning tips:
- Use --severity to focus on issues of a certain level.
- Use --openssl
to test with a different OpenSSL build.
Even if you run it locally, cross-check with the online runner to see how your site looks from the outside world and different network vantage points.
Mapping Findings to Fixes: A Quick Playbook
- Incomplete certificate chain
- Install the correct intermediate(s); verify with a re-scan and an external checker.
- TLS 1.0/1.1 enabled
- Restrict protocols to TLS 1.2/1.3; confirm legacy dependencies, then disable old versions.
- Weak ciphers present (3DES/RC4/CBC)
- Remove them; stick to AEAD suites; enforce server order.
- No forward secrecy
- Switch to ECDHE suites; ensure modern curves are favored.
- ROBOT vulnerability
- Disable RSA key exchange in TLS 1.2; upgrade server/OpenSSL; prefer ECDHE.
- SWEET32 exposure
- Remove 3DES entirely.
- No OCSP stapling
- Enable stapling and verify the responder is reachable from the server.
- Missing HSTS
- Add HSTS once you’re confident all subresources are HTTPS; consider preload after testing.
- HTTP/2 not enabled
- Ensure ALPN is available and supported suites are used; enable h2 in server configuration.
- Compression/renegotiation enabled
- Disable TLS compression and client-initiated renegotiation.
Practical Advice for Smooth Remediation
- Make changes incrementally. Disable the riskiest items first (e.g., SSLv3/TLS1.0/3DES), then fine-tune ciphers.
- Roll out changes to a staging environment or a canary subset of servers behind a load balancer.
- Monitor error rates and client compatibility metrics. For public sites, keep an eye on analytics segments representing older devices.
- Document your TLS policy: protocols, ciphers, curves, session settings, stapling, HSTS, and certificate practices.
- Coordinate with your CDN/WAF provider to ensure consistent policy at the edge.
Dealing with Real-World Complexities
- Multi-CDN or Geo load balancing: Different regions may present different TLS stacks. Scan regionally (if the online tool supports specifying edges) and check IPv6 separately.
- SNI and multi-tenant hosting: Confirm that every hostname responds with the correct certificate and policy.
- Proxies and upstreams: If TLS is terminated at a load balancer, ensure that device is the focus of your scan, not just the origin servers.
- Dual certificates (RSA/ECDSA): Some clients prefer RSA. Provide both where possible; modern browsers tend to favor ECDSA for performance.
- Mutual TLS (mTLS): For private APIs, ensure client cert requirements don’t degrade protocol choices; separate public and private endpoints if needed.
- Application-layer pitfalls: Mixed content or redirect loops can undermine a perfect TLS posture. Audit redirects and resource loading.
Integrating SSL Checks into Your Workflow
- Scheduled scanning: Set calendar reminders or cron jobs to run local scans weekly and after deployments.
- CI/CD gates: Include a step that runs testssl.sh against staging and fails the pipeline if disallowed protocols or ciphers are detected.
- Alerting: Trigger notifications if a certificate is within 30 days of expiration or if configuration drift reintroduces weak settings.
- Asset inventory: Maintain a list of all TLS endpoints (including SMTP, IMAP, MQTT, and admin consoles), not just your main websites.
Example CI check script idea:
#!/usr/bin/env bash
set -euo pipefail
TARGET="${1:-example.com}"
TMP="$(mktemp)"
./testssl.sh --jsonfile "$TMP" --fast "$TARGET" >/dev/null
# Fail if TLS1.0 or TLS1.1 detected or if 3DES/RC4 present
if grep -E '"id":"protocol","finding":"TLS1\.[01].*enabled"' "$TMP"; then
echo "FAIL: Legacy TLS enabled"; exit 1
fi
if grep -E '3DES|RC4' "$TMP"; then
echo "FAIL: Weak ciphers present"; exit 1
fi
echo "PASS"
Tune the logic based on your JSON schema and organizational policy.
Using the Online Runner Effectively
At https://www.web-psqc.com/security/ssl:
- Start with a full scan for a baseline. Record the date and the target.
- Re-scan after each configuration change to verify improvements.
- Check both your apex domain and the www subdomain—sometimes they’re routed differently.
- Test alternate ports if you expose admin panels or APIs under different endpoints.
- If available, run both IPv4 and IPv6 scans to spot discrepancies.
- Save or screenshot key sections (protocols, ciphers, certificate chain) for your security documentation.
If you’re concerned about exposure during scanning:
- Schedule scans during off-peak hours.
- Whitelist the scanner IPs if your firewall blocks unknown sources.
- Do not scan third-party domains without authorization.
A Sensible Baseline TLS Policy (Public Websites)
- Protocols: TLS 1.2, TLS 1.3 only
- Ciphers (TLS 1.2): Only AEAD with ECDHE, including AES-GCM and ChaCha20-Poly1305
- TLS 1.3: Defaults (AES-GCM and ChaCha20) are fine; no customization usually required
- Curves: Prefer X25519, then prime256v1
- Certificates: RSA 2048+ or ECDSA P-256/384 with SHA-256; enable stapling
- HSTS: 1 year with includeSubDomains once ready; consider preload after verifying all subdomains
- ALPN/HTTP/2: Enabled; ensure compatibility
- Session resumption: Enabled; rotate ticket keys; consider 0-RTT disabled unless you’ve addressed replay risk
- Compression: Disabled
- Renegotiation: Client-initiated disabled
Frequently Missed Opportunities
- Not enabling TLS 1.3 even when supported by your server version
- Leaving ALPN off and missing HTTP/2 performance gains
- Incomplete chains causing intermittent browser errors
- Neglecting IPv6 listeners and exposing weaker configs on v6
- Forgetting about non-HTTPS services (SMTP STARTTLS, IMAPS, FTPS), which can be low-hanging fruit for attackers
Before and After: Visualizing Progress
Run a baseline scan, apply the recommended config changes, then re-scan:
- Expect to see TLS 1.0/1.1 removed, fewer cipher suites, and no weak options listed.
- Certificate chain should be complete, OCSP stapling active, and HSTS present.
- Vulnerability checks should all read “not vulnerable.”
Document these changes and store the report for audits and future regressions.
Final Checklist
- TLS 1.0/1.1 disabled everywhere
- Only AEAD ECDHE cipher suites in TLS 1.2
- TLS 1.3 enabled
- X25519 and prime256v1 preferred
- Certificate and full chain installed; OCSP stapling on
- HSTS configured appropriately
- ALPN advertising h2; HTTP/2 enabled
- No TLS compression; client renegotiation disabled
- Session resumption configured with sensible key rotation
- All public endpoints (including mail and APIs) scanned and remediated
- Regular scans scheduled; CI/CD guardrails in place
Wrapping Up
A robust SSL/TLS setup is more than passing a quick online grade—it’s about building a defensible, documented, and continuously verified posture that keeps pace with evolving threats and browser expectations. testssl.sh gives you the depth you need, and the online runner at https://www.web-psqc.com/security/ssl makes it simple to start today.
Use this guide to run a comprehensive analysis, understand what the results mean, and apply proven fixes. Then automate your checks so your configuration stays strong with every deployment and certificate renewal. Your users—and your future self—will thank you.