testssl.sh is a powerful bash-based SSL/TLS testing utility that performs comprehensive security assessments. It checks for protocol support, cipher vulnerabilities, certificate validity, and known TLS exploits more thoroughly than lighter tools like sslscan.
git clone --depth 1 https://github.com/drwetter/testssl.sh.git
cd testssl.sh
chmod +x testssl.sh
brew install testssl.sh
docker pull drwetter/testssl.sh
docker run --rm drwetter/testssl.sh https://example.com
# Most systems have these. testssl.sh may warn if missing:
apt-get install openssl curl dnsutils socat
# On Alpine/minimal systems: apk add openssl curl bind-tools socat
./testssl.sh https://example.com
./testssl.sh --quick https://example.com
./testssl.sh https://example.com:8443
./testssl.sh example.com:443
testssl.sh -t smtp mail.example.com:587 # STARTTLS
| Command | Description |
|---|
./testssl.sh https://example.com | Full comprehensive scan |
./testssl.sh --quick https://example.com | Fast scan (essential checks only) |
./testssl.sh example.com:443 | Custom port |
./testssl.sh -t smtp mail.example.com:587 | SMTP with STARTTLS |
./testssl.sh -t xmpp example.com:5222 | XMPP STARTTLS |
./testssl.sh --protocols https://example.com
./testssl.sh --ssl-v2 https://example.com # SSLv2 (deprecated)
./testssl.sh --ssl-v3 https://example.com # SSLv3 (deprecated)
./testssl.sh --tls1 https://example.com # TLS 1.0
./testssl.sh --tls1-1 https://example.com # TLS 1.1
./testssl.sh --tls1-2 https://example.com # TLS 1.2
./testssl.sh --tls1-3 https://example.com # TLS 1.3
| Command | Description |
|---|
--protocols | Test all supported protocols |
--ssl-v2 | Test SSLv2 support (should fail) |
--ssl-v3 | Test SSLv3 support (should fail) |
--tls1 | Test TLS 1.0 support (legacy) |
--tls1-1 | Test TLS 1.1 support (legacy) |
--tls1-2 | Test TLS 1.2 support (modern) |
--tls1-3 | Test TLS 1.3 support (latest) |
./testssl.sh --ciphers https://example.com
./testssl.sh --ciphers --strength https://example.com
./testssl.sh --weak https://example.com # Find weak ciphers
./testssl.sh --rc4 https://example.com # Check for RC4
| Command | Description |
|---|
--ciphers | List all supported ciphers |
--ciphers --strength | Show cipher strength ratings |
--weak | Highlight weak ciphers only |
--rc4 | Test specifically for RC4 support |
--null | Test for NULL ciphers |
--export | Test for export-grade ciphers |
./testssl.sh --sigalgs https://example.com
./testssl.sh --eccbrainpool https://example.com
./testssl.sh --curves https://example.com
| Command | Description |
|---|
--sigalgs | Show signature algorithms |
--eccbrainpool | Test ECC Brainpool curves |
--curves | List supported elliptic curves |
--dsa | Check DSA key support |
./testssl.sh --heartbleed https://example.com
| Command | Description |
|---|
--heartbleed | Test OpenSSL Heartbleed vulnerability |
./testssl.sh --ccs https://example.com
| Command | Description |
|---|
--ccs | Test CCS Injection vulnerability |
./testssl.sh --robot https://example.com
| Command | Description |
|---|
--robot | Test ROBOT decryption vulnerability |
./testssl.sh --poodle https://example.com
| Command | Description |
|---|
--poodle | Test POODLE downgrade vulnerability |
./testssl.sh --beast https://example.com
| Command | Description |
|---|
--beast | Test BEAST cipher block chaining issue |
./testssl.sh --crime https://example.com
| Command | Description |
|---|
--crime | Test CRIME compression attack |
./testssl.sh --breach https://example.com
| Command | Description |
|---|
--breach | Test HTTP compression vulnerability |
./testssl.sh --lucky13 https://example.com
| Command | Description |
|---|
--lucky13 | Test Lucky13 timing attack |
./testssl.sh --freak https://example.com
| Command | Description |
|---|
--freak | Test FREAK export key vulnerability |
./testssl.sh --logjam https://example.com
| Command | Description |
|---|
--logjam | Test Logjam DHE downgrade attack |
./testssl.sh --drown https://example.com
| Command | Description |
|---|
--drown | Test DROWN SSLv2 attack |
./testssl.sh --sweet32 https://example.com
| Command | Description |
|---|
--sweet32 | Test 64-bit block cipher vulnerability |
./testssl.sh --padding-oracle https://example.com
| Command | Description |
|---|
--padding-oracle | Test padding oracle vulnerability |
./testssl.sh --ticketbleed https://example.com
| Command | Description |
|---|
--ticketbleed | Test TLS session ticket vulnerability |
./testssl.sh --cert https://example.com
./testssl.sh --cert-validity https://example.com
./testssl.sh --cert-chain https://example.com
| Command | Description |
|---|
--cert | Display full certificate information |
--cert-validity | Check certificate expiration and validity |
--cert-chain | Show certificate chain (CA hierarchy) |
--cert-signalg | Display signature algorithm |
--cert-extensions | Show certificate extensions |
./testssl.sh --cert-info https://example.com # Full analysis
./testssl.sh --self-signed https://example.com
./testssl.sh --verify-hostname https://example.com
| Command | Description |
|---|
--cert-info | Detailed certificate information |
--self-signed | Check if certificate is self-signed |
--verify-hostname | Verify hostname matches certificate |
--wildcard | Check for wildcard certificate |
./testssl.sh --hsts https://example.com
./testssl.sh --headers https://example.com
| Command | Description |
|---|
--hsts | Check HSTS header |
--headers | Check security-related HTTP headers |
--hpkp | Check HTTP Public Key Pinning |
./testssl.sh -t smtp mail.example.com:587
./testssl.sh -t pop3 mail.example.com:110
./testssl.sh -t imap mail.example.com:143
./testssl.sh -t xmpp example.com:5222
./testssl.sh -t ldap ldap.example.com:389
| Command | Description |
|---|
-t smtp host:587 | Test SMTP with STARTTLS |
-t pop3 host:110 | Test POP3 with STARTTLS |
-t imap host:143 | Test IMAP with STARTTLS |
-t xmpp host:5222 | Test XMPP with STARTTLS |
-t ldap host:389 | Test LDAP with STARTTLS |
-t ftp host:21 | Test FTP with STARTTLS |
./testssl.sh --json https://example.com > results.json
./testssl.sh --json --outfile results.json https://example.com
| Command | Description |
|---|
--json | Output results in JSON format |
--json --outfile file.json | Save JSON output to file |
./testssl.sh --csv https://example.com > results.csv
./testssl.sh --csv --outfile results.csv https://example.com
| Command | Description |
|---|
--csv | Output results in CSV format |
--csv --outfile file.csv | Save CSV to file |
./testssl.sh --html https://example.com > results.html
./testssl.sh --html --outfile results.html https://example.com
| Command | Description |
|---|
--html | Generate HTML report |
--html --outfile file.html | Save HTML report to file |
./testssl.sh --logfile results.log https://example.com
./testssl.sh --append https://example.com # Append to existing log
| Command | Description |
|---|
--logfile file.log | Save output to log file |
--append | Append to log instead of overwriting |
./testssl.sh --file hosts.txt
| Command | Description |
|---|
--file hosts.txt | Test list of hosts (one per line) |
while IFS= read -r host; do
./testssl.sh --json --outfile "${host//\//_}.json" "https://$host"
done < hosts.txt
cat hosts.txt | parallel ./testssl.sh --json --outfile {}.json https://{}
name: SSL/TLS Testing
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Clone testssl.sh
run: git clone --depth 1 https://github.com/drwetter/testssl.sh.git
- name: Run testssl
run: |
./testssl.sh/testssl.sh --json \
--outfile results.json \
https://example.com
- name: Upload results
uses: actions/upload-artifact@v2
with:
name: ssl-test-results
path: results.json
stage('SSL/TLS Security Scan') {
steps {
sh '''
git clone --depth 1 https://github.com/drwetter/testssl.sh.git
./testssl.sh/testssl.sh --json \
--outfile results.json \
https://example.com
'''
archiveArtifacts artifacts: 'results.json'
}
}
ssl_tls_scan:
stage: security
script:
- git clone --depth 1 https://github.com/drwetter/testssl.sh.git
- ./testssl.sh/testssl.sh --json --outfile results.json https://example.com
artifacts:
paths:
- results.json
./testssl.sh --fast https://example.com # Skip slow tests
./testssl.sh --slow https://example.com # Run additional slow tests
./testssl.sh --nofallback https://example.com # Skip fallback checks
| Command | Description |
|---|
--fast | Faster scan, skip slower vulnerability tests |
--slow | Include additional slow/thorough tests |
--nofallback | Disable protocol fallback testing |
--servername name | TLS SNI (needed for shared hosting) |
./testssl.sh --severity HIGH https://example.com
./testssl.sh --severity CRITICAL https://example.com
| Command | Description |
|---|
--severity HIGH | Show only high/critical findings |
--severity CRITICAL | Show only critical findings |
| Feature | testssl.sh | sslscan | sslyze |
|---|
| Protocol vulnerability checks | Comprehensive | Basic | Good |
| Cipher analysis | Detailed | Detailed | Detailed |
| Certificate analysis | Full | Limited | Moderate |
| Speed | Slower | Fast | Fast |
| Language | Bash | C | Python |
| STARTTLS support | Yes | Yes | Yes |
| Output formats | JSON/CSV/HTML | XML | JSON/CSV |
| Automation friendly | Very | Moderate | Good |
| CVE detection | Yes (Heartbleed, POODLE, etc.) | Limited | Moderate |
# Quick scan for major issues
./testssl.sh --quick https://example.com
# Detailed compliance audit
./testssl.sh --severity HIGH https://example.com
# Integration with monitoring
./testssl.sh --json --outfile scan.json https://example.com
# Compare against baseline
./testssl.sh --json https://example.com | jq .findings[]
# Check certificate renewal alerts
./testssl.sh --cert-validity https://example.com
#!/bin/bash
host=$1
./testssl.sh --html --outfile "${host}_report.html" "https://$host"
./testssl.sh --json --outfile "${host}_data.json" "https://$host"
echo "Report saved: ${host}_report.html"
#!/bin/bash
for host in $(cat hosts.txt); do
days_left=$(./testssl.sh --cert-validity "https://$host" | grep -oP '\d+(?= days)')
if [ "$days_left" -lt 30 ]; then
echo "ALERT: $host expires in $days_left days"
fi
done
#!/bin/bash
host=$1
timestamp=$(date +%s)
./testssl.sh --ciphers --strength "https://$host" > "ciphers_${timestamp}.txt"
# Compare with previous runs
diff ciphers_*.txt
| Finding | Severity | Action |
|---|
| SSLv2/v3 enabled | CRITICAL | Disable immediately |
| TLS 1.0/1.1 enabled | HIGH | Disable or plan removal |
| Weak ciphers (RC4, DES) | HIGH | Remove from supported ciphers |
| Self-signed certificate | MEDIUM | Use CA-signed certificate |
| Expired certificate | CRITICAL | Renew certificate |
| Certificate chain issues | MEDIUM | Complete chain configuration |
| Missing HSTS header | MEDIUM | Add HSTS header |
| Known vulnerabilities | CRITICAL | Patch immediately |
# Test with SNI for multi-domain hosting
./testssl.sh --servername example.com https://shared-ip.com
# Save baseline for comparison
./testssl.sh --json https://example.com > baseline.json
# Test only without certificate validation (dev environments)
./testssl.sh --noverify https://test.internal:8443
# Enable verbose logging for debugging
./testssl.sh -v https://example.com
# Run specific test only
./testssl.sh --heartbleed https://example.com
./testssl.sh --drown https://example.com