Skip to content

Releases: capitan0n/sshd-lint

v1.5.2 – CI housekeeping

Choose a tag to compare

@capitan0n capitan0n released this 02 Oct 22:35

sshd-lint 1.5.2

Maintenance release. The linter behaves exactly as in 1.5.1.

Changes

  • CI: Moved dependabot.yml from .github/workflows/ to .github/, where GitHub expects it. Dependabot was ignoring the config before, so automated dependency and Actions update PRs now actually run.
  • Version bumped to 1.5.2.

Upgrade

pip install -U sshd-lint

No config, CLI or exit-code changes. Upgrading is optional if you're on 1.5.1.

Full changelog: v1.5.1...v1.5.2

v1.5.0 — catch silently-missed findings; correct Match/Include scoping

Choose a tag to compare

@capitan0n capitan0n released this 13 Aug 12:40

Focus of this release: eliminating cases where a valid config was silently
under-reported, and correctly modelling Match/Include scoping.

Fixed — findings that were silently missed

  • LoginGraceTime 0 (no time limit) was never reported
  • Time suffixes like 10m / 1h caused the rule to be skipped entirely
  • ClientAliveCountMax 0 silently defeats the idle timeout even when an interval is set
  • KbdInteractiveAuthentication (8.7+) and PubkeyAcceptedKeyTypes (<8.5) were not checked
  • Values the linter can't interpret are now reported instead of skipped

Fixed — false positives

  • HostCertificate was wrongly flagged as a duplicate directive
  • Include globs matching a directory were reported as CRITICAL

Changed — Match / Include semantics

  • An Include inside a Match block now inherits that scope
  • A Match left open in an included file now correctly scopes the rest of the parent file, as sshd behaves
  • Every finding now carries the source file it came from

Changed — exit codes and I/O

  • Unreadable or missing config exits 66; invalid --openssh-version exits 64 (no longer confused with a security verdict)
  • SIGPIPE / SIGINT exit cleanly (141 / 130) without a traceback
  • JSON findings gained a file field
  • NO_COLOR environment variable honoured

Other

  • New tricky.conf and edge.conf sample configs
  • README rewritten

Full config-by-config behaviour is documented in the README.

v1.4.1 — CLI/docs reflect installed command name

Choose a tag to compare

@capitan0n capitan0n released this 31 Jul 09:34

Update --help epilog and README to use the installed sshd-lint command instead of python sshd_lint.py. No functional changes to the analyzer.

v1.4.0 — CLI correctness and exit code semantics

Choose a tag to compare

@capitan0n capitan0n released this 31 Jul 08:04

⚠️ Breaking changes

  • --version short flag changed from -v to -V. -v is now reserved for a future verbosity flag.
  • Usage errors now exit 64 (EX_USAGE) instead of 2, and a missing config file exits 66 (EX_NOINPUT) instead of 1. Previously a mistyped flag exited 2, which a CI gate would read as "CRITICAL findings found". Findings verdicts (0/1/2) are unchanged.

Fixes

  • The shebang was not on line 1, so chmod +x sshd_lint.py && ./sshd_lint.py did not work as documented. Fixed.

Improvements

  • Errors now print one line plus a pointer to --help, instead of dumping the full usage block.
  • ASCII banner on --version.
  • README: added sample output, corrected the JSON example, and fixed the GitHub Actions snippet (the old one collapsed exit 1 and 2 into a single failure).

v1.3.0 — Initial public release

Choose a tag to compare

@capitan0n capitan0n released this 04 Jul 13:36

First public release of sshd_lint, a zero-dependency static analyzer
for OpenSSH sshd_config files. Designed for offline auditing and
CI/CD integration.

Features

  • 34 rules covering authentication, cryptography, access control,
    forwarding, logging, and Match-block semantics
  • Include glob expansion with symlink-safe deduplication
  • Duplicate directive detection (with correct handling of cumulative
    directives like AllowGroups)
  • Text and JSON output; exit codes (0/1/2) designed for CI/CD gates
  • Compliance references: CIS Benchmark, Mozilla OpenSSH Guidelines,
    NIST SP 800-53

Requirements

  • Python 3.9+
  • No external dependencies