
Regelbasierter Linter für OpenSSH-Client-Konfigurationsdateien, der doppelte Hosts, fehlende Identitätsdateien, schwache Algorithmen, Probleme mit der Wildcard-Reihenfolge und gefährliche Einstellungen erkennt und eine JSON-Ausgabe sowie CI-freundliche Exit-Codes bietet.
Lint deine ~/.ssh/config auf häufige Fehler.
Prüft auf doppelte Host-Blöcke, fehlende Identitätsdateien, Probleme mit der Wildcard-Reihenfolge, schwache Algorithmen, doppelte Direktiven und mehr. Unterstützt Include-Direktiven mit Zykluserkennung.
https://github.com/user-attachments/assets/4d995679-baed-4f20-9ba8-8f3ec94c64fd
curl -fsSL https://raw.githubusercontent.com/Noah4ever/sshconfig-lint/main/install.sh | bash
Setze VERSION=v0.1.0 oder INSTALL_DIR=~/.local/bin, um die Standardwerte zu überschreiben.
brew tap Noah4ever/tap
brew install sshconfig-lint
optionaler Befehl untap Noah4ever/tap zum Entfernen des Taps und um die Tap-Liste sauber zu halten.
cargo install sshconfig-lint
sshconfig-lint-bin - vorgefertigte Binärdateien
yay -S sshconfig-lint-bin
paru -S sshconfig-lint-bin
Hole dir eine Binärdatei von der Releases-Seite.
# lint the default ~/.ssh/config
sshconfig-lint
# lint a specific file
sshconfig-lint --config /path/to/config
# json output
sshconfig-lint --format json
# treat warnings as errors (useful in CI)
sshconfig-lint --strict
# skip Include resolution
sshconfig-lint --no-includes
line 4: [warning] WILDCARD_ORDER (wildcard-host-order) Host 'github.com' appears after 'Host *' (line 1); it will never match because Host * already matched (hint: move Host * to the end of the file)
line 7: [warning] DUP_HOST (duplicate-host) duplicate Host block 'github.com' (first seen at line 4) (hint: remove one of the duplicate Host blocks)
line 3: [error] MISSING_IDENTITY (identity-file-exists) IdentityFile not found: ~/.ssh/id_missing (hint: check the path or remove the directive)
Die Ausgabe ist nach Datei und Zeilennummer sortiert, sodass sie über verschiedene Läufe hinweg deterministisch ist (stabil für CI-Diffs und Snapshots).
Fehler sind rot, Warnungen gelb, Informationen cyan. Farben werden automatisch deaktiviert, wenn stdout kein Terminal ist oder wenn NO_COLOR gesetzt ist.
| Code | Bedeutung |
|---|---|
| 0 | Sauber, keine Fehler gefunden |
| 1 | Mindestens ein Fehler-Level-Fund (oder Warnung mit --strict) |
| 2 | Konfigurationsdatei nicht gefunden |
Jeder Fund hat einen stabilen Code, nach dem Sie in Skripten greppen oder suchen können.
Funde enthalten wenn möglich einen Hinweis, z. B. „verschiebe Host * an das Ende der Datei“.
Host github.com gitlab.com)Include conf.d/*.conf extra.conf)IdentityFile ~/.ssh/id # my key)ProxyCommand "ssh -W %h:%p bastion")cargo test # run all tests
cargo test --lib # unit tests only
cargo clippy # lint
cargo fmt --check # formatting
src/
main.rs CLI
lib.rs Public API (lint_file, lint_str)
model.rs AST types
lexer.rs Tokenizer
parser.rs Builds config AST from tokens
resolve.rs Include expansion + cycle detection
report.rs Text and JSON formatters
rules/
mod.rs Rule trait and runner
basic.rs Built-in rules
tests/
fixtures/ Sample config files
cli.rs CLI integration tests
integration.rs Fixture-based tests
Rule-Trait in src/rules/basic.rsrun_all() in src/rules/mod.rsSiehe CONTRIBUTING.md für weitere Details.
MIT
| Code | Regel | Schweregrad | Beschreibung |
|---|
DUP_HOST | duplicate-host | warning | Zwei Host-Blöcke mit demselben Muster |
MISSING_IDENTITY | identity-file-exists | error | IdentityFile-Pfad existiert nicht |
WILDCARD_ORDER | wildcard-host-order | warning | Host * erscheint vor spezifischen Mustern |
WEAK_ALGO | deprecated-weak-algorithms | warning | Schwacher oder veralteter Algorithmus (3des-cbc, arcfour, hmac-md5, ssh-dss, etc.) |
DUP_DIRECTIVE | duplicate-directives | warning | Gleiche Direktive in einem Gültigkeitsbereich wiederholt (nur der erste Wert wirkt) |
INSECURE_OPT | insecure-option | warning | Gefährliche Einstellung wie StrictHostKeyChecking no oder ForwardAgent yes bei Host * |
UNSAFE_CTRL_PATH | unsafe-control-path | warning | ControlPath fehlt %h, %p, %r (oder %C) — Verbindungen könnten einen Socket teilen |
INCLUDE_CYCLE | include-cycle | error | Zirkuläre Include-Kette |
INCLUDE_READ | include-read | error | Eingebundene Datei kann nicht gelesen werden |
INCLUDE_GLOB | include-glob | error | Ungültiges Include-Glob-Muster |
INCLUDE_NO_MATCH | include-no-match | info | Include-Muster hat keine Dateien gefunden |