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

> Simulate diverse client environments for TLS testing with testssl.sh. Mimic browser OS and TLS client behavior to ensure compatibility across platforms.

- Repository: [Dirk Wetter/testssl.sh](https://github.com/drwetter/testssl.sh)
- Tags: how-to-guide
- Published: 2026-03-01

---

**Yes, [`testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/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`](https://github.com/drwetter/testssl.sh/blob/main/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`](https://github.com/drwetter/testssl.sh/blob/main/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](https://github.com/drwetter/testssl.sh/blob/3.3dev/testssl.sh#L5206-L5248)** 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](https://github.com/drwetter/testssl.sh/blob/3.3dev/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](https://github.com/drwetter/testssl.sh/blob/3.3dev/utils/update_client_sim_data.pl)**, though the repository now maintains a curated static list supplemented by **[etc/client-simulation.wiresharked.txt](https://github.com/drwetter/testssl.sh/blob/3.3dev/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](https://github.com/drwetter/testssl.sh/blob/3.3dev/testssl.sh#L5292-L5310)** 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.

```bash

# 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`](https://github.com/drwetter/testssl.sh/blob/main/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`:

```bash

# 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](https://github.com/drwetter/testssl.sh/blob/3.3dev/testssl.sh#L191-L192)** 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](https://github.com/drwetter/testssl.sh/blob/3.3dev/etc/client-simulation.wiresharked.txt)** to add your custom client signature, following the existing format
2. Regenerate the compiled data file:

```bash
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`](https://github.com/drwetter/testssl.sh/blob/main/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.