SSLyze: Auditing SSL/TLS Configurations Like a Pro

sslyze: Audits SSL/TLS configurations

TLS misconfigurations are still one of the most common findings I write up in assessment reports — weak ciphers left enabled, expired or misissued certificates, missing security headers on the handshake side, renegotiation flaws that never got patched. SSLyze is the tool I reach for when I need a fast, thorough, and scriptable audit of a server’s SSL/TLS configuration rather than eyeballing openssl s_client output line by line.

This article covers what SSLyze does, how it’s architected, installation, full command syntax with real output, and how I use it across pentests, compliance audits, and incident response.

What SSLyze Does

SSLyze is a Python-based tool (with a fast C-based scanning engine, nassl, under the hood) that analyzes a server’s SSL/TLS configuration. It checks:

  • Which SSL/TLS protocol versions are supported (SSLv2, SSLv3, TLS 1.0 through TLS 1.3)
  • Which cipher suites are accepted per protocol
  • Certificate chain validity, trust, expiration, and hostname matching
  • Support for known-vulnerable configurations (Heartbleed, ROBOT, CCS injection, session renegotiation)
  • OCSP stapling status
  • HTTP security headers relevant to TLS (HSTS)
  • Certificate transparency compliance

Architecture and Internal Working

SSLyze separates concerns into two layers:

  1. nassl — a low-level Python binding around OpenSSL that lets SSLyze open connections at arbitrary protocol versions and cipher configurations, including some that modern OpenSSL builds disable by default (like SSLv2/SSLv3), which is essential for detecting genuinely legacy, vulnerable servers.
  2. Scan commands (plugins) — each check (cipher suite support, certificate info, Heartbleed, etc.) is implemented as an independent “scan command” module. When you run a scan, SSLyze dispatches each requested scan command against the target concurrently using a thread pool, which is why it’s dramatically faster than testing each cipher manually with OpenSSL.

Results are aggregated into a single report, which can be output as human-readable text or structured JSON for automation.

Installation

Via pip (recommended):

pip install --user sslyze

Via Kali/Debian:

sudo apt update
sudo apt install sslyze -y

Verify:

sslyze --version

Basic Syntax

sslyze [options] target_host[:port]

Command Examples

1. Full default scan (recommended starting point)

sslyze example.com

This runs the full default suite: protocol support, cipher suites, certificate info, and common vulnerability checks all in one pass.

Sample output snippet:

 TLS 1.2                       
------------------------------
  Cipher Suites:
    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256      Preferred
    TLS_RSA_WITH_AES_128_CBC_SHA               

 TLS 1.3
------------------------------
  Cipher Suites:
    TLS_AES_256_GCM_SHA384    Preferred

 Certificate #1
------------------------------
  Subject: example.com
  Issuer: DigiCert Global G2 TLS RSA SHA256 2020 CA1
  Validity: OK - Certificate is not expired
  Hostname Validation: OK - Certificate matches server hostname

2. Checking a specific vulnerability

sslyze --heartbleed example.com
sslyze --robot example.com

3. Checking a non-standard port (e.g., mail server STARTTLS)

sslyze --starttls=smtp mail.example.com:587

4. Scanning multiple targets at once

sslyze example.com example.org:8443 10.0.0.5

5. Outputting JSON for automation/integration

sslyze --json_out=results.json example.com

This JSON can be parsed downstream to feed into a dashboard, ticketing system, or CI/CD security gate.

6. Checking only specific protocol support

sslyze --tlsv1_0 --tlsv1_1 example.com

This is useful for confirming whether legacy protocols that should have been disabled are still accepted.

7. Certificate-only scan

sslyze --certinfo example.com

Configuration and Tuning

  • --regular runs the standard default set of scan commands (protocol + cipher + cert + common vulns).
  • --mozilla_config=intermediate compares the discovered configuration against Mozilla’s recommended TLS configuration levels (modern, intermediate, old), which is a fast way to benchmark compliance.
sslyze --mozilla_config=intermediate example.com

Real-World Use Cases

PCI-DSS / compliance audits: Confirming that legacy TLS 1.0/1.1 and weak ciphers are actually disabled across a card-processing environment, with JSON output feeding directly into an audit report.

Penetration testing: Quickly flagging weak cipher suites, expired certs, or Heartbleed-vulnerable legacy servers during the external assessment phase.

Incident response: After a suspected TLS downgrade or MITM incident, running sslyze against affected servers to confirm current configuration hasn’t been tampered with or left in a weakened state.

DevSecOps / CI integration: Adding an sslyze --json_out step to a deployment pipeline so any new server that goes live with a bad TLS config fails the build automatically.

Workflow and Tool Integration

# Step 1: Discover live HTTPS hosts
amass enum -passive -d example.com | httpx -silent -ports 443 > https_hosts.txt

# Step 2: Run SSLyze against every discovered host
while read host; do
  sslyze --json_out="${host}_sslyze.json" "$host"
done < https_hosts.txt

# Step 3: Parse JSON for weak ciphers across the fleet
python3 parse_sslyze_json.py *_sslyze.json

I usually pair sslyze findings with testssl.sh or sslscan output as a second opinion, since cross-validating cipher and protocol support across two independent tools catches edge cases either one alone might miss.

Performance Optimization

  • Scan multiple hosts in one invocation (sslyze host1 host2 host3) rather than looping shell calls where possible — SSLyze parallelizes internally.
  • Use --json_out for large fleets instead of parsing text output; it’s far more reliable for automation.
  • Skip --robot on hosts you already know are patched and modern, since ROBOT checks add extra round-trips per cipher tested.

Troubleshooting

  • Connection refused / timeout — confirm the port and protocol; STARTTLS-based services (SMTP, IMAP, FTP) need the --starttls= flag rather than a direct TLS handshake.
  • “Could not connect” on legacy protocol checks — the target may be genuinely rejecting SSLv2/SSLv3, which is actually a good sign; verify with openssl s_client -connect host:443 -ssl3 as a cross-check.
  • Outdated nassl errors after a Python upgrade — reinstall via pip install --upgrade sslyze to rebuild against your current Python version.

Best Practices and Common Mistakes

  • Don’t stop at the default scan — explicitly test STARTTLS services (SMTP, IMAP) separately since they’re often overlooked.
  • Cross-reference certificate expiration and chain trust findings against the actual certificate authority’s status, not just SSLyze’s output alone.
  • Avoid treating “TLS 1.3 supported” as automatically secure — still check for weak fallback ciphers on TLS 1.2 that might be negotiated by older clients.

FAQ

Does SSLyze replace a manual OpenSSL check? For almost all practical purposes yes — it’s faster, more thorough, and easier to script, though a manual openssl s_client check is still handy for one-off debugging.

Can SSLyze test STARTTLS-based protocols like SMTP or IMAP? Yes, using the --starttls=<protocol> flag with the appropriate service name.

Is SSLyze safe to run against production systems? Generally yes — it’s a read-only configuration audit, not an exploitation tool, but always confirm scope and authorization first, especially with vulnerability-specific checks like Heartbleed.

Lab Example

Spin up an Nginx server in a lab VM with a deliberately weak config (TLS 1.0 enabled, weak ciphers allowed), then run:

sslyze --mozilla_config=intermediate 192.168.56.20

Compare the output against the Mozilla intermediate baseline to see exactly which settings need to change, then fix the Nginx config and re-scan to confirm remediation.

Summary

SSLyze turns what used to be a tedious, manual TLS audit into a fast, automatable, and thorough process. Whether I’m doing a one-off pentest or building continuous compliance checks into a pipeline, it gives me a reliable, structured view of exactly how a server’s TLS stack is configured — and exactly what needs fixing.

References

  • Official GitHub repository: https://github.com/nabla-c0d3/sslyze
  • Documentation: https://nabla-c0d3.github.io/sslyze/documentation
  • Man page / help: sslyze --help
Total
0
Shares

Leave a Reply

Previous Post
sslscan: Tests SSL/TLS ciphers and vulnerabilities

sslscan: Tests SSL/TLS ciphers and vulnerabilities

Next Post
amass: Subdomain enumeration tool

Amass: Complete Guide to Subdomain Enumeration and Attack Surface Mapping Using Kali Linux

Related Posts