tlsx: How ProjectDiscovery Built a TLS Scanner That Handles 300 Concurrent Connections
Hook
Most TLS scanners complete every handshake they start. tlsx terminates connections early, grabbing certificate data before the handshake finishes—sometimes 10x faster than traditional tools.
Context
If you've ever tried to scan TLS certificates across a large infrastructure—say, an entire ASN or a /16 CIDR block—you know the pain. Traditional tools like openssl s_client work beautifully for individual hosts but crumble under scale. Even purpose-built scanners often lock you into a single TLS implementation, meaning you'll miss older servers running obsolete protocols or encounter compatibility issues with edge-case TLS stacks.
The security research community needed something different: a tool that could ingest thousands of targets, handle every TLS version from SSLv3 to TLS 1.3, extract certificate chains and metadata, fingerprint server configurations, and do it all without waiting for full handshakes to complete. ProjectDiscovery built tlsx to fill this gap, specifically targeting bug bounty hunters, penetration testers, and infrastructure teams who need to discover certificate misconfigurations, enumerate TLS capabilities, and map out TLS footprints across entire networks in minutes rather than hours.
Technical Insight
The architectural genius of tlsx lies in its multi-mode connection strategy and early termination capability. Instead of relying on a single TLS implementation, it supports three distinct modes: ctls (crypto/tls from Go's standard library), ztls (a low-level TLS library for granular control), and openssl (shelling out to the system's OpenSSL binary). The tool attempts connections with automatic fallback, starting with ctls and dropping down to ztls or openssl when it encounters incompatible or legacy TLS implementations. This ensures you can scan everything from modern TLS 1.3 servers to ancient SSLv3 endpoints without manually switching tools.
Here's where it gets interesting: tlsx implements pre-handshake termination, a technique that extracts certificate data during the ServerHello phase without completing the full TLS handshake. When you're scanning thousands of hosts just to collect certificate information, waiting for key exchange, cipher negotiation, and session establishment is pure waste. The pre-handshake mode lets you grab what you need and bail out:
# Standard scan with full handshake
echo 'example.com' | tlsx -json
# Pre-handshake termination for faster scanning
echo 'example.com' | tlsx -pre-handshake -json
# Scan an entire CIDR with 500 workers
echo '192.168.1.0/24' | tlsx -c 500 -port 443 -json -o results.json
The concurrency model defaults to 300 workers, which is aggressive but justified for reconnaissance scenarios. Each worker operates independently, processing targets from an input queue. You can pipe in diverse input formats—single IPs, CIDR ranges, ASN numbers, domain names, or even full URLs—and tlsx normalizes them internally. For ASN enumeration, it queries BGP data to resolve IP ranges, making it trivial to scan every IP address owned by a specific organization.
Fingerprinting capabilities go beyond basic certificate inspection. tlsx implements JARM (an active TLS fingerprinting method that sends malformed handshakes and analyzes server responses) and JA3 (which hashes the TLS ClientHello parameters). These fingerprints help identify server software, CDN providers, and load balancer configurations:
# Collect JARM and JA3 fingerprints
echo 'example.com' | tlsx -jarm -ja3 -json
# Output includes fingerprint data:
# {
# "host": "example.com",
# "port": "443",
# "jarm": "27d40d40d29d40d1dc42d43d00041d4689ee210389f4f6b4b5b1b93f92252d",
# "ja3": "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0",
# "tls_version": "tls13"
# }
The certificate validation engine deserves attention. tlsx performs comprehensive misconfiguration checks: expired certificates, self-signed certificates, hostname mismatches, revocation status via OCSP and CRL, and trust chain validation. You can configure the revocation checking strategy (soft-fail vs hard-fail), which matters when OCSP responders are unreachable. The soft-fail approach treats lookup failures as passes, while hard-fail marks them as errors—crucial for compliance audits where you need to be certain.
For cipher suite and TLS version enumeration, tlsx can probe a server with every combination to determine exactly what's supported. This is invaluable for security audits:
# Enumerate all supported TLS versions
echo 'example.com' | tlsx -enum
# Test specific cipher suites
echo 'example.com' | tlsx -cipher 'TLS_AES_128_GCM_SHA256' -json
The JSON output format is structured for pipeline processing. Every field is clearly defined, making it simple to filter results with jq, feed them into other tools, or store them in databases for historical comparison. The tool integrates naturally into automated workflows—you can trigger tlsx scans from CI/CD pipelines, compare certificate fingerprints over time to detect infrastructure changes, or build alerting systems that flag certificate misconfigurations before they cause outages.
Gotcha
The Go 1.24 requirement is frustrating. As of this writing, Go 1.24 isn't released yet (the latest stable is 1.22), which means you'll need to build from Go's development branch or wait for the next release cycle. This isn't a casual dependency issue—it suggests the codebase relies on features or fixes not yet available in stable Go, limiting immediate adoption.
The default concurrency of 300 workers is a double-edged sword. While it dramatically speeds up large scans, it's aggressive enough to trigger rate limiting on cloud providers, set off intrusion detection systems, or violate acceptable use policies if you're scanning third-party infrastructure. There's no built-in rate limiting or backoff mechanism, so you're responsible for tuning the worker count and understanding the network impact. For production environments or regulated industries, you'll want to dial this down significantly—but the tool doesn't guide you on appropriate values.
Certificate revocation checking with hard-fail can produce false positives in environments with unreliable OCSP or CRL infrastructure. If a certificate authority's OCSP responder is down or rate-limiting requests, perfectly valid certificates will be flagged as problematic. The soft-fail mode mitigates this, but it means you might miss genuinely revoked certificates if you're too permissive. There's no middle ground—you either fail open or fail closed, with no option for retry logic or timeout tuning.
Verdict
Use if: You're conducting large-scale TLS reconnaissance across IP ranges, ASNs, or subdomain lists and need speed without sacrificing data completeness. This tool excels in bug bounty scenarios where you're enumerating certificate metadata across an organization's entire infrastructure, security audits where you need to discover misconfigurations at scale, or threat intelligence operations where JARM and JA3 fingerprints help identify infrastructure patterns. It's perfect for teams already comfortable with Go tooling and command-line pipelines. Skip if: You need gentle, production-safe scanning with built-in rate limiting (testssl.sh offers this), require deep vulnerability analysis beyond certificate inspection (sslyze provides more comprehensive TLS testing), or need to run on stable Go versions without compiling from source. Also skip if you're scanning third-party infrastructure without explicit permission—the aggressive defaults can look like attacks.