Self-hosted service
testssl/testssl.sh avatar
testssl/testssl.sh

testssl.sh: a bash TLS scanner you clone instead of install

Testing TLS/SSL encryption anywhere on any port

9,217 stars1,146 forksShellGPL-2.0

At a glance

What is it?
testssl.sh checks any TLS or STARTTLS service on any port from a single shell script, with no package manager involved. It is a good fit for one-off audits and CI checks, and a poor fit for anyone who wants a long-running web service or a supported stable branch with more than n-1 maintenance.
Who is it for?
Adopt testssl.sh if you need a scriptable TLS audit on a host you already control, and you are comfortable tracking the 3.3dev branch or pinning 3.2. Do not adopt it as a network service: the README states it is intended as a standalone CLI tool and that running it as a web service may pose security risks.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What testssl.sh checks that a browser padlock does not

A browser tells you whether the certificate chain validated and whether the page loaded. It does not tell you that the same host still accepts TLS 1.0, that it offers a 3DES cipher suite, or that its STARTTLS handshake on port 25 leaks information. testssl.sh exists for that gap. The README describes it as a free command line tool which checks a server's service on any port for the support of TLS/SSL ciphers, protocols as well as some cryptographic flaws.

The audience is narrow and specific: engineers who need to audit a service they are responsible for, and who want the result on their own machine rather than in a third party's dashboard. The README makes that a stated design goal under the heading Privacy: it is only you who sees the result, not a third party. That matters when the hostname itself is sensitive, for example an internal admin panel or a mail gateway that is not publicly resolvable.

The second audience is CI. Because the tool emits CSV, two JSON formats and HTML, its output can be diffed between builds. A pipeline that fails when a new weak protocol appears is a realistic use. What testssl.sh is not is a scanner for hosts you do not own. Nothing in the repository suggests it was built for wide internet sweeps, and the README advises validating input from all services which are queried.

How the bash-socket checks replace the bundled OpenSSL

Older versions of this tool were limited by whatever the system's openssl binary supported. The README states that most of those limitations are gone due to bash-socket-based checks, and that an old OpenSSL-bad version is supplied but you can also use any LibreSSL or OpenSSL version. Read that carefully: the script ships a fallback binary, but it is not the only path. Where a check can be done by opening a socket from bash directly, the client library stops being the ceiling on what can be tested.

The practical consequence is portability. According to the README, testssl.sh works on Linux, MacOS, FreeBSD, NetBSD, WSL2, MSYS2/Cygwin, and OpenBSD needs bash. Other unixoid systems work if they have /bin/bash version 3.2 or newer plus standard tools like sed and awk. A silent check for binaries runs at startup, which is why a missing dependency shows up as an error at launch rather than halfway through a scan.

That architecture also explains the output formats. Because the script drives the handshakes itself rather than parsing one tool's report, it can normalize findings into CSV, JSON and HTML from the same run. The trade-off is that everything is shell. There is no library to import, no API to call, and no way to embed a single check into a Python process without shelling out to the script.

Installing testssl.sh and running a first scan

There is no package to install. The README's documented path is a shallow clone of the development branch:

bash
git clone --depth 1 https://github.com/testssl/testssl.sh.git --branch 3.3dev

After that you cd into the directory and run the script directly. The README notes you can just run it from the pulled/cloned directory, so no build step follows the clone. If you would rather not keep the repository on disk, the README gives a container image on GHCR, which supports linux/amd64, linux/386, linux/arm64, linux/arm/v7, linux/arm/v6 and linux/ppc64le:

bash
docker run --rm -it ghcr.io/testssl/testssl.sh <your_cmd_line>

The README also shows building the image yourself from a cloned checkout:

bash
docker build . -t imagefoo && docker run --rm -t imagefoo testssl.net

One caution about the branch. The README says 3.3dev is the latest development branch which evolved from 3.2 stable, and that the point of development is that there will be changes and changes might need a bit time to mature. If you are hestitant with respect to changes, the README tells you to use 3.2. The clone command above deliberately fetches 3.3dev, so if you want the stable line you have to change the branch name yourself.

For the first real run, point it at a host you control. The README's own example target in the Docker build line is testssl.net. Expect a text report where, in the README's words, you can tell easily whether anything is good or bad. If you want the machine-readable form instead, that is what the CSV and JSON options are for, and the README lists HTML as a third output.

Where testssl.sh is the wrong tool

The README is unusually direct about one boundary. testssl.sh is intended to be used as a standalone CLI tool. While the project tried to apply best practise security measures and sanitize external input, the README says it cannot guarantee that the program is without any vulnerabilities, and that running as a web service may pose security risks. If your plan is to wrap this in a Flask endpoint and let anyone submit a hostname, the project itself is telling you not to.

There is a second boundary in the support policy. Given the current manpower, the README states, only n-1 versions are supported. 3.3.dev is where development happens before 3.4 becomes stable and 3.2 becomes old-stable. Version 3.0.10 was the last one in that line and there will not be more updates. So a pinned, long-lived, security-patched release is not something this project offers. You either ride the development branch or accept a stable branch that will eventually be superseded.

The third limitation is the licence and the warranty. The README states usage of the program is without any warranty, use it at your own risk. It is also GPLv2, which matters if you intend to redistribute a modified scanner rather than merely run it.

Finally, consider what a shell script cannot do. It cannot be imported as a module, and it cannot be embedded in a process that needs a stable in-memory API. If your requirement is programmatic per-connection checks inside a long-running service, a library with a language binding is a better shape than a CLI you fork.

testssl.sh compared with a library-based scanner

The obvious alternative category is a TLS scanner written as a library, where you import it and call a function per host. The difference in approach is not cosmetic. A library-based scanner gives you a return value in your own process, which is convenient for building a service, but it constrains the checks to whatever that library's TLS stack exposes. testssl.sh takes the opposite route: it drives handshakes from bash sockets and can fall back to a bundled or system OpenSSL, which is how the README says it escaped the limitations of disabled features in the openssl client.

A second alternative is the online TLS grading services that many teams use for a quick look. Those are convenient and require nothing installed, but they invert the privacy property. The scan runs on someone else's infrastructure against a hostname you submitted. testssl.sh's stated position is that only you see the result. For an internal hostname, that difference decides the choice.

A third alternative is to script openssl s_client yourself. That is essentially what this tool started as, and it is still viable for one protocol check. What you give up is the accumulated check set and the normalized CSV and JSON output, which is the part that takes real effort to reproduce. If you only ever need to confirm that a certificate chain validates, writing ten lines around openssl is cheaper than maintaining a clone.

Licence, attribution and the cost of tracking 3.3dev

testssl.sh is GPLv2. For most users that means running it changes nothing about their own code. The README adds a request that is not a licence term: if you offer a scanner based on testssl.sh as a public or paid service, you are strongly encouraged to mention to your audience that you are using this program and where to get it from. The stated reason is that it helps the project get bugfixes and feedback. Treat that as a community norm rather than an obligation, and note that the README phrases it as encouragement, not a condition.

The upgrade cost is the part worth planning for. The repository carries a CHANGELOG.md and publishes snapshot releases from 3.3dev, alongside bugfix releases on the 3.2 line such as v3.2.4. Because the README's clone command fetches the development branch by default, a naive setup will silently pick up changes on every pull. If you run this in CI, pin a specific commit or a snapshot tag rather than tracking the branch tip. There is no documented rollback procedure in the README, so the version you pin is the version you keep until you deliberately move.

The Docker path changes the calculus slightly. The Dockerfile builds on openSUSE Leap and installs bash, procps, grep, gawk, sed, coreutils, busybox, ldns, libidn2-0, socat, openssl and curl into a scratch image, then symlinks busybox applets. That means the container pins its own dependency set, so a host upgrade does not move the tool underneath you. The cost is image size and the need to rebuild when you want a newer script revision.

Editorial conclusion

Adopt testssl.sh if you need a scriptable TLS audit on a host you already control, and you are comfortable tracking the 3.3dev branch or pinning 3.2. Do not adopt it as a network service: the README states it is intended as a standalone CLI tool and that running it as a web service may pose security risks. Before relying on it, verify which branch you cloned, confirm your bash is at least 3.2, and check whether your distribution ships a packaged version at all, because the README's only documented install path is a git clone or the ghcr.io/testssl/testssl.sh container.

Frequently asked questions

What is testssl.sh?

It is a free command line tool that checks a server's service on any port for the support of TLS/SSL ciphers, protocols and some cryptographic flaws. It is distributed as a bash script rather than a compiled binary, and the README lists CSV, two JSON formats and HTML as output options.

How do I install testssl.sh?

The README's documented method is a shallow git clone of the 3.3dev branch, after which you run the script from the cloned directory with no build step. Alternatively you can pull the container image from ghcr.io/testssl/testssl.sh.

How do I use testssl.sh on Windows?

The README states that Windows works through MSYS2, Cygwin or WSL/WSL2. The requirement is a bash of version 3.2 or newer plus standard tools such as sed and awk, and the script performs a silent check for binaries when it starts.

How do I use testssl.sh in Kali?

The README does not describe a Kali-specific installation path. Its documented route is the same everywhere: clone the 3.3dev branch and run the script from the cloned directory, or use the GHCR container image.

Is testssl.sh safe to run?

The README states that usage is without any warranty and at your own risk, and that while the project applied best practise security measures and sanitizes external input, it cannot guarantee the program is free of vulnerabilities. It explicitly warns that running it as a web service may pose security risks.

What is a good alternative to testssl.sh?

The README does not name a competing tool. The meaningful distinction is between this CLI, which drives handshakes from bash sockets and keeps results local, and hosted TLS grading services that run the scan on someone else's infrastructure against a hostname you submit.

Official sources

  1. License: GPL-2.0
  2. Project website
  3. README
  4. Releases
  5. testssl/testssl.sh on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/testssl-testssl-sh.svg)](https://hysenlabs.com/projects/testssl-testssl-sh)