# ssh-audit: auditing SSH server and client configuration from the command line

> ssh-audit inspects the algorithms an SSH server or client offers, flags weak or legacy ones, and can test a host against a hardening policy. It is a Python 3.10-3.14 tool with no dependencies, and it is best treated as a configuration report, not a vulnerability scanner.

**jtesta/ssh-audit** — SSH server & client security auditing (banner, key exchange, encryption, mac, compression, compatibility, security, etc)

- Repository: https://github.com/jtesta/ssh-audit
- Stars: 4,316 · Forks: 231
- Language: Python
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/jtesta-ssh-audit

## What ssh-audit actually inspects

An SSH handshake is a negotiation, and most operators never see the terms. ssh-audit connects to a host, reads the banner, and then enumerates the key exchange, host key, encryption and message authentication code algorithms the server offers. It annotates each algorithm with security information: when it became available, whether it was removed or disabled, and whether it is classified as unsafe, weak or legacy. From the recognized software version it also produces recommendations, telling you which algorithms to append or remove. The same analysis runs against clients: with -c the tool starts a server on port 2222 and audits the client software that connects to it. This is aimed at engineers who own SSH configuration, whether on a handful of servers or a fleet listed in a targets file. It is not aimed at people who want a scanner that finds exploitable bugs; nothing in the README claims that.

## How the audit works and where policy scans fit

The mechanism is deliberately shallow. ssh-audit speaks enough of the SSH protocol to complete negotiation and observe what the peer advertises; it does not log in, and it does not need credentials. Everything it reports comes from that exchange plus a built-in historical database covering OpenSSH, Dropbear SSH and libssh. The output has two layers. The standard audit is descriptive: here is what the server offers, here is how each algorithm is rated, here is what the tool suggests changing. The policy layer is prescriptive: -P runs a scan against a built-in policy or a custom policy file, and -M goes the other way, generating a policy file from a target server you consider correctly configured. That inversion is the interesting design choice. Instead of shipping one opinion about a hardened configuration, the project lets you record your own reference host and then measure the rest of your fleet against it. The trade-off is that a policy generated from a badly configured host will bless that configuration everywhere.

## Installing ssh-audit and running a first audit

The README lists pre-built packages, and the repository carries build files for Docker, PyPI, Snap and a Windows executable. The Dockerfile builds on python:3-alpine, copies ssh-audit.py and src/ into the image, exposes port 2222 for client auditing, and drops to the nobody:nogroup user before setting the entrypoint to python3 /ssh-audit.py. If you run from source instead, the entry point at the repository root is ssh-audit.py. The README states the tool supports Python 3.10 through 3.14 and has no dependencies, so a plain interpreter is enough.

A first audit is one command against a hostname or IP address. The usage text gives the positional argument as host, and the default timeout for connection and reading is 5 seconds.

```bash
python3 ssh-audit.py host
```

You should see the banner, a device or software identification, and grouped lists of key exchange, host key, encryption and MAC algorithms with their security annotations. To keep the output machine-readable, the usage text documents -j for JSON output and -jj for indentation.

```bash
python3 ssh-audit.py -jj host
```

For a fleet, the usage text describes -T targets.txt as a file containing a list of target hosts, one per line, in HOST[:PORT] format, with --threads controlling concurrent scans.

```bash
python3 ssh-audit.py -T targets.txt --threads N
```

Finally, to see what the built-in policies are before applying one, run -L. Adding -v shows the policy change logs, which tells you how the policies have shifted over time.

## The limits of a handshake-only audit

ssh-audit sees what a server advertises to an unauthenticated peer. It does not read sshd_config, so it cannot tell you that a per-user Match block permits password authentication for one account, or that an AllowUsers directive is missing. It does not validate host key file permissions, and it does not confirm that the algorithms it recommends are actually the ones your clients will negotiate. Those are configuration facts that live behind the handshake. The tool is also the wrong choice if you need to demonstrate that a specific weakness is exploitable; it rates algorithms, it does not attack them. One exception sits in the usage text: --dheat continuously performs the DHEat DoS attack (CVE-2002-20001) against a target using N concurrent sockets, and --conn-rate-test collects metrics related to susceptibility to that vulnerability. Those flags turn a passive audit into active traffic against a live host, so they belong in a controlled test window, not a routine scan. The README does not document a rollback or undo path for anything the tool changes, because it changes nothing on the target.

## Where ssh-audit sits next to general scanners

The obvious alternative is a general-purpose vulnerability scanner such as OpenVAS or Nessus, or a configuration compliance framework like OpenSCAP. The difference in approach is scope. A general scanner enumerates services, maps them to known CVEs and produces findings across an entire host; SSH is one plugin among hundreds, and the depth of SSH algorithm analysis depends on what that plugin implements. ssh-audit does one protocol and does it at the level of individual algorithms and their history, including version compatibility analysis across OpenSSH, Dropbear and libssh. That narrowness is why it can tell you that a specific MAC is legacy rather than merely present. It is also why it will not tell you about the web server on the same box. Many teams run both: the general scanner for breadth, ssh-audit for the SSH configuration detail that a generic plugin tends to compress into a single finding.

## Maintenance, packaging and licence

The repository is not archived, and the last push was on 2026-07-09. Release tags show v3.3.0 in October 2024, v3.2.0 in April 2024, and v3.9.0 on 2026-07-04, so the gap between v3.3.0 and v3.9.0 is wide even though the project has since shipped again. The README describes jtesta/ssh-audit as the updated and maintained fork of arthepsy/ssh-audit, which the README attributes to inactivity in the original. Packaging is spread across Makefile.docker, Makefile.pypi, snapcraft.yaml, build_snap.sh and build_windows_executable.sh, which means upgrade paths differ by channel: a PyPI install, a Homebrew formula, a container image and a Snap package can lag each other. The licence is MIT, which is permissive and imposes no copyleft obligation on your own code; the repository ships a LICENSE file at the root. That is a factual description of the licence text, not legal advice, and anyone redistributing a modified build should read the file themselves.

## Conclusion

Adopt ssh-audit if you need a fast, dependency-free read on which SSH algorithms a host advertises, and if you are willing to read the output rather than treat it as a pass/fail gate. Skip it if you need authenticated configuration review, exploit validation, or anything beyond what the SSH handshake exposes. Before rolling it out, verify two things yourself: that the built-in policy you intend to use matches your platform's expectations (run -L and read the policy list, including the change logs with -v), and that your Python version falls in the 3.10 to 3.14 range the README states. The tool's own -M flag is the fastest way to see how far your current servers are from the configuration you consider correct.

## FAQ

### How do I install ssh-audit?

The README points to pre-built packages and the repository ships build files for Docker, PyPI, Snap and a Windows executable. Running from source needs only Python 3.10 to 3.14, since the tool has no dependencies and the entry point is ssh-audit.py at the repository root.

### How do I use ssh-audit?

Pass a hostname or IP address as the positional argument to run a standard audit of that server. Add -j or -jj for JSON output, -T to scan a file of targets, and -P to run a policy scan against a built-in or custom policy.

### What is ssh-audit?

It is a tool for auditing SSH server and client configuration. It grabs the banner, gathers key exchange, host key, encryption and MAC algorithms, and reports security information and recommendations based on the recognized software version.

### What is an alternative to ssh-audit?

A general vulnerability scanner covers SSH as one plugin among many, whereas ssh-audit analyzes the SSH protocol down to individual algorithms and their history. The two are complementary: the general scanner gives breadth across services, ssh-audit gives depth on the SSH negotiation itself.

## Sources

- [Issues](https://github.com/jtesta/ssh-audit/issues)
- [jtesta/ssh-audit on GitHub](https://github.com/jtesta/ssh-audit)
- [License: MIT](https://github.com/jtesta/ssh-audit/blob/master/LICENSE)
- [README](https://github.com/jtesta/ssh-audit/blob/master/README.md)
- [Releases](https://github.com/jtesta/ssh-audit/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jtesta-ssh-audit
