How to Simulate Different Client Environments for TLS Compatibility Testing with testssl.sh

Yes, testssl.sh can simulate different client environments by mimicking the TLS handshake behavior of real-world browsers, operating systems, and TLS clients using its built-in client simulation engine.

The open-source security testing tool testssl.sh includes a comprehensive client simulation feature that allows security engineers and system administrators to verify server compatibility without maintaining a fleet of physical devices. According to the drwetter/testssl.sh source code, this feature emulates the exact protocol versions, cipher suites, and TLS extensions supported by specific client implementations to identify compatibility regressions before they impact production users.

How Client Simulation Works in testssl.sh

When you invoke the client simulation feature, testssl.sh performs actual TLS handshakes against your target server while impersonating various known clients. The simulation does not rely on static configuration guesses—it executes live OpenSSL s_client connections (or raw socket handshakes when using --ssl-native) using the precise parameters advertised by each simulated client.

The system distinguishes between current clients—those relevant for modern compatibility testing—and a larger historical archive of 126 total client signatures. By default, the tool tests only current clients, but you can expand coverage using environment variables.

The Core Implementation: run_client_simulation()

The heart of this functionality resides in the run_client_simulation() function within the main testssl.sh script. This function orchestrates the entire simulation workflow, from data loading to result aggregation.

Loading Client Data from etc/client-simulation.txt

The simulation engine sources client capabilities from etc/client-simulation.txt, which contains Bash associative arrays defining each client's parameters. Each entry specifies:

  • Supported TLS protocols and cipher suites
  • Elliptic curves and signature algorithms
  • DH/RSA key-size limits
  • SNI handling behavior
  • TLS extension support

This data file is historically derived from the Qualys SSL Labs clients API using utils/update_client_sim_data.pl, though the repository now maintains a curated static list supplemented by etc/client-simulation.wiresharked.txt for Wireshark-captured client signatures.

Executing Simulated Handshakes

For each client marked as current (or all clients when ALL_CLIENTS is enabled), the script iterates through the client database and constructs OpenSSL commands with exact options required by that specific client implementation. The execution loop at testssl.sh lines 5292-5310 handles:

  1. Determining the service type (HTTP, SMTP, etc.) based on --service, --starttls, or --assume-http flags
  2. Building the OpenSSL s_client command line with protocol and cipher restrictions matching the simulated client
  3. Collecting handshake results including negotiated protocol, cipher suite, curve, and forward-secrecy status
  4. Formatting output into aligned columns or structured formats (JSON/XML/CSV)

Running Client Simulation Scans

Activate client simulation using the -c or --client-simulation flag. The tool evaluates your server against the default set of current client environments and reports which connections succeed, fail, or negotiate down to weaker protocols.


# Basic client simulation against HTTPS service

testssl.sh -c example.com:443

# Quiet mode with JSON output for CI/CD integration

testssl.sh -c --quiet --json example.com:443 > compatibility_report.json

Customizing Client Simulations

Testing All 126 Client Signatures

By default, testssl.sh tests only clients marked as current in the data file. To simulate all 126 known client signatures—including legacy and historical browsers—set the environment variable ALL_CLIENTS to true:


# Test every available client signature

ALL_CLIENTS=true testssl.sh -c example.com:443

# Combine with full client suite and JSON output

ALL_CLIENTS=true testssl.sh -c -q --json example.com:443 > comprehensive_scan.json

This variable is handled at testssl.sh lines 191-192 and expands the simulation scope to include outdated clients that may still exist in enterprise environments.

Adding Custom Client Signatures

You can extend the simulation database to include proprietary or specialized client environments:

  1. Edit etc/client-simulation.wiresharked.txt to add your custom client signature, following the existing format
  2. Regenerate the compiled data file:
cd utils
./update_client_sim_data.pl > ../etc/client-simulation.txt

After regeneration, your custom client appears in subsequent simulations without modifying the core script logic.

Summary

  • testssl.sh simulates different client environments through the run_client_simulation() function, which executes actual TLS handshakes using client-specific parameters.
  • Client capabilities are defined in etc/client-simulation.txt, sourced from historical SSL Labs data and Wireshark captures.
  • Use the -c or --client-simulation flag to run compatibility checks against current client signatures.
  • Set ALL_CLIENTS=true to test all 126 known client signatures instead of only current ones.
  • Extend simulations by editing etc/client-simulation.wiresharked.txt and running utils/update_client_sim_data.pl.

Frequently Asked Questions

How does testssl.sh determine which cipher suites a simulated client supports?

The script loads predefined client profiles from etc/client-simulation.txt, which contains Bash associative arrays mapping each client name to its specific protocol versions, cipher suites, elliptic curves, and extension support. These profiles are historically derived from the Qualys SSL Labs API and Wireshark captures of real client handshakes.

Can I test compatibility with a specific old browser, like Internet Explorer 11?

Yes. Set ALL_CLIENTS=true when running testssl.sh -c to include legacy browsers and operating systems in the simulation. By default, only clients marked as current are tested, but enabling ALL_CLIENTS expands the scan to cover all 126 archived client signatures, including outdated versions.

What is the difference between client-simulation.txt and client-simulation.wiresharked.txt?

etc/client-simulation.txt is the generated Bash data file consumed by the script during execution. etc/client-simulation.wiresharked.txt is the human-editable source file where you can add new client signatures based on Wireshark captures. After editing the wiresharked file, you run utils/update_client_sim_data.pl to regenerate the compiled version.

Does client simulation work with STARTTLS protocols like SMTP and FTP?

Yes. The run_client_simulation() function detects the service type based on the --service, --starttls, or --assume-http flags. It adjusts the OpenSSL s_client parameters accordingly, allowing you to test TLS compatibility for mail servers, FTP servers, and other STARTTLS-enabled services against various client environments.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →