Metadata-Version: 2.4
Name: sshield
Version: 0.1.0
Summary: Audit SSH server and client configuration files for weak settings.
Author: Baran Ayaztas
License: MIT
Project-URL: Homepage, https://github.com/ReazGan/sshield
Project-URL: Issues, https://github.com/ReazGan/sshield/issues
Keywords: ssh,sshd,security,hardening,openssh,devsecops,static-analysis,cli,security-tools
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Security
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.1
Requires-Dist: rich>=13.7
Dynamic: license-file

# sshield

[![CI](https://github.com/ReazGan/sshield/actions/workflows/ci.yml/badge.svg)](https://github.com/ReazGan/sshield/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/sshield)](https://pypi.org/project/sshield/)

Audit SSH configuration for weak settings.

Most SSH incidents trace back to a config line nobody revisited: root login left
on, password auth still enabled, a legacy cipher hanging around, or a client set
to accept any host key. sshield reads your `sshd_config`, `ssh_config` and
`~/.ssh/config` and points at those lines.

Runs offline. Nothing leaves your machine.

![sshield flagging root login, empty passwords, weak ciphers and password auth](https://raw.githubusercontent.com/ReazGan/sshield/main/docs/screenshot.svg)

## Install

```
pip install sshield
```

## Usage

```
sshield                         scan the current directory
sshield /etc/ssh/sshd_config    scan a single file
sshield --min high              only high and critical findings
sshield --json                  machine-readable output
```

Exit status is `0` when clean, `1` when there is a finding at or above the fail
level (`--fail-on`, default `high`), and `2` on error.

## What it checks

**Server (`sshd_config`)**

| Check | Severity | What it finds |
|-------|----------|---------------|
| `empty-passwords` | critical | `PermitEmptyPasswords yes`. |
| `legacy-protocol` | critical | SSH protocol 1 enabled. |
| `permit-root-login` | high | `PermitRootLogin yes`. |
| `weak-algorithms` | high | Broken ciphers/MACs/KEX (CBC, arcfour, hmac-md5/sha1, DH group1, ...). |
| `password-auth` | medium | Password authentication enabled. |
| `pubkey-disabled` | medium | Public-key auth turned off. |
| `x11-forwarding`, `permit-tunnel` | low | Forwarding/tunnelling left on. |

**Client (`ssh_config` / `~/.ssh/config`)**

| Check | Severity | What it finds |
|-------|----------|---------------|
| `no-host-key-checking` | high | `StrictHostKeyChecking no` (defeats MITM protection). |
| `known-hosts-devnull` | high | `UserKnownHostsFile /dev/null`. |

Settings are read last-wins, the way sshd resolves them, and commented-out
defaults are ignored, so a stock config stays quiet.

## License

MIT
