How to Debug Connection Issues When Running testssl.sh
Use the --debug=<1-6> flag to retain temporary files in /tmp/testssl.*, inspect the raw OpenSSL s_client output, and adjust MAX_OSSL_FAIL or MAX_SOCKET_FAIL environment variables to prevent premature aborts during transient failures.
When testssl.sh fails to establish a TLS connection, the root cause often hides in OpenSSL handshake details or network timeouts. This guide explains how to leverage the built-in debug infrastructure in the drwetter/testssl.sh repository to diagnose connection failures by examining temporary files, interpreting failure counters, and using the debugme helper function.
How testssl.sh Handles Connection Failures
Two core components manage connection problems according to the source code.
$OPENSSL s_client invocations – All TLS handshakes are executed via OpenSSL's s_client command (defined around line 36 in testssl.sh). This is the actual mechanism performing network probes and capturing server responses.
connectivity_problem function – Located at lines 2579-2595, this function tracks failure counts using NR_OSSL_FAIL and NR_SOCKET_FAIL counters. It aborts execution when reaching MAX_OSSL_FAIL (OpenSSL errors) or MAX_SOCKET_FAIL (TCP errors) thresholds, printing a fatal error message when limits are exceeded.
Debug Infrastructure and Flags
Debug Levels (--debug)
The --debug=<0-6> parameter (documented near line 21621) controls verbosity and file retention:
0– No debug output (default)1-2– Preserves temporary files in/tmp/or the current directory for post-run analysis3-6– Activates verbose internal diagnostics via thedebugmehelper
The debugme Helper Function
Defined at lines 834-837, debugme executes commands only when DEBUG is set to 2 or higher. It prints diagnostics to stderr and archives output in the temporary directory, allowing you to see exactly what commands were executed during the scan.
Temporary Directory Structure
Each execution creates $TEMPDIR (default /tmp/testssl.<PID>, implemented at line 21658). This directory stores critical intermediate data:
- Raw handshake data:
$TEMPDIR/<host>.s_client.txt - Parsed server responses:
$TEMPDIR/<host>.parse_tls_serverhello.txt - Error streams:
$ERRFILE
Failure Thresholds
Environment variables control abort behavior to prevent infinite loops on broken targets:
MAX_OSSL_FAIL– Maximum OpenSSL handshake failures before fatal exit (default is typically low for fast failure)MAX_SOCKET_FAIL– Maximum TCP connection failures before fatal exit
When connectivity_problem detects threshold breaches, it issues a fatal error suggesting you increase the corresponding limit.
Special Debug Options
The -Z flag forces TLS fallback SCSV testing (referenced at lines 18898-18899). Combined with --debug=1, it generates extra log files (*tls_fallback_scsv.txt) useful when normal handshakes are rejected by the server.
Step-by-Step Debugging Workflow
Follow this sequence to isolate connection problems.
-
Run with debug retention
testssl.sh --debug=2 example.com:443Note the
TEMPDIRpath printed in the output summary. -
Inspect temporary files
cat /tmp/testssl.XXXXXX/example.com.s_client.txt -
Handle OpenSSL-specific failures
If you see "openssl s_client connect problem", increase the threshold to bypass transient TLS issues:
MAX_OSSL_FAIL=20 testssl.sh --debug=1 example.com:443 -
Handle TCP-level failures
For "TCP connect problem" errors, verify reachability with
telnetorncfirst, then adjust:MAX_SOCKET_FAIL=15 testssl.sh --debug=1 example.com:443 -
Force fallback testing
testssl.sh -Z --debug=1 example.com:443
Practical Code Examples
Basic Debug Run with File Retention
# Retain all temporary files for inspection
testssl.sh --debug=2 example.com:443
After completion, examine the directory path printed in the output summary.
Custom Temporary Directory
TEMPDIR=$(mktemp -d)
testssl.sh --debug=2 --tempdir "$TEMPDIR" example.com:443
# Inspect raw OpenSSL output
cat "$TEMPDIR/example.com.s_client.txt"
Override Failure Thresholds
# Allow 15 OpenSSL failures before aborting
MAX_OSSL_FAIL=15 testssl.sh --debug=1 example.com:443
# Allow 10 TCP timeouts
MAX_SOCKET_FAIL=10 testssl.sh --debug=1 example.com:443
Debug TLS Fallback Issues
testssl.sh -Z --debug=1 example.com:443
cat "$TEMPDIR/example.com.tls_fallback_scsv.txt"
Key Source Files
Understanding these files in the repository helps trace connection logic:
testssl.sh(main script) – Line 36 defines the$OPENSSL s_clientinvocation; line 21658 creates$TEMPDIR; line 21621 documents debug flagsdebugmefunction – Lines 834-837 implement the conditional execution wrapper that logs commands only whenDEBUG ≥ 2connectivity_problemfunction – Lines 2579-2595 contain the failure counting and abort logic for both OpenSSL and socket errorsutils/resume.sh– Helper for session resumption tests usings_clientutils/checkcert.sh– Extracts certificates vias_client -showcertsetc/client-simulation.txt– Data file used by the client simulation engine; useful when debugging simulated browser handshakes
Summary
- Enable debugging with
--debug=2to preserve temporary files in/tmp/testssl.<PID>for post-scan analysis - Inspect raw output in
$TEMPDIR/<host>.s_client.txtto see exact OpenSSL error messages and server responses - Adjust thresholds using
MAX_OSSL_FAILandMAX_SOCKET_FAILenvironment variables for flaky networks or slow targets - Use
-Zflag with--debug=1to diagnose TLS fallback SCSV rejection issues - Check the
debugmefunction at line 834 to understand how conditional logging wraps sensitive commands
Frequently Asked Questions
How do I see the exact OpenSSL error when testssl.sh fails to connect?
Run testssl.sh with --debug=2 and inspect the *.s_client.txt file in the temporary directory printed at the end of the scan. This file contains the raw stderr and stdout from the $OPENSSL s_client command that failed, including specific handshake error codes.
What is the difference between MAX_OSSL_FAIL and MAX_SOCKET_FAIL?
MAX_OSSL_FAIL counts failures occurring during the TLS handshake phase (certificate validation errors, protocol version mismatches), while MAX_SOCKET_FAIL counts TCP-level connection failures (timeouts, connection refused, network unreachable). Increase the relevant variable based on which error message appears in the connectivity_problem output at lines 2579-2595.
Where are the debug log files stored?
By default, logs are stored in /tmp/testssl.<PID>/. When using --debug=1 or higher, the script prints the exact TEMPDIR path at the end of execution. You can also specify a custom location with --tempdir /path/to/dir to make files easier to locate.
Why does testssl.sh abort even with --debug enabled?
The script uses hardcoded failure thresholds in the connectivity_problem function. If NR_OSSL_FAIL exceeds MAX_OSSL_FAIL (or the socket equivalent), it calls fatal and exits regardless of debug settings. Override these limits by setting the environment variables (e.g., MAX_OSSL_FAIL=50) before invoking the script.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →