
Линтер на основе правил для конфигурационных файлов клиента OpenSSH, который обнаруживает дублирующиеся хосты, отсутствующие файлы identity, слабые алгоритмы, проблемы с порядком подстановочных знаков и опасные настройки, с выводом в формате JSON и кодами возврата, удобными для CI.
Проверьте ваш ~/.ssh/config на распространённые ошибки.
Проверяет на дублирующиеся блоки хостов, отсутствующие файлы идентификации, проблемы с порядком подстановок, слабые алгоритмы, дублирующиеся директивы и многое другое. Поддерживает директивы Include с обнаружением циклов.
https://github.com/user-attachments/assets/4d995679-baed-4f20-9ba8-8f3ec94c64fd
curl -fsSL https://raw.githubusercontent.com/Noah4ever/sshconfig-lint/main/install.sh | bash
Установите VERSION=v0.1.0 или INSTALL_DIR=~/.local/bin, чтобы переопределить значения по умолчанию.
brew tap Noah4ever/tap
brew install sshconfig-lint
дополнительно можно выполнить untap Noah4ever/tap, чтобы удалить tap и оставить список tap чистым
cargo install sshconfig-lint
sshconfig-lint-bin — предварительно собранные бинарные файлы
yay -S sshconfig-lint-bin
paru -S sshconfig-lint-bin
Загрузите бинарный файл со страницы релизов.
# проверить стандартный ~/.ssh/config
sshconfig-lint
# проверить конкретный файл
sshconfig-lint --config /path/to/config
# вывод в формате json
sshconfig-lint --format json
# считать предупреждения ошибками (полезно в CI)
sshconfig-lint --strict
# пропустить разрешение Include
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)
Вывод сортируется по файлу и номеру строки, что делает его детерминированным при разных запусках (стабилен для сравнений в CI и снимков).
Ошибки отображаются красным, предупреждения — жёлтым, информационные сообщения — голубым. Цвета автоматически отключаются, если stdout не является терминалом или установлена переменная NO_COLOR.
| Код | Значение |
|---|---|
| 0 | Чисто, ошибок не найдено |
| 1 | Обнаружена хотя бы одна ошибка (или предупреждение с флагом --strict) |
| 2 | Файл конфигурации не найден |
Каждое замечание имеет стабильный код, который можно использовать в скриптах для поиска или сопоставления.
Замечания по возможности содержат подсказку, например «перенесите Host * в конец файла».
Host github.com gitlab.com)Include conf.d/*.conf extra.conf)IdentityFile ~/.ssh/id # my key)ProxyCommand "ssh -W %h:%p bastion")cargo test # запустить все тесты
cargo test --lib # только модульные тесты
cargo clippy # линтинг
cargo fmt --check # проверка форматирования
src/
main.rs CLI
lib.rs Публичный API (lint_file, lint_str)
model.rs AST типы
lexer.rs Токенизатор
parser.rs Строит AST конфигурации из токенов
resolve.rs Раскрытие Include + обнаружение циклов
report.rs Текстовые и JSON форматтеры
rules/
mod.rs Трейт Rule и исполнитель
basic.rs Встроенные правила
tests/
fixtures/ Примеры конфигурационных файлов
cli.rs Интеграционные тесты CLI
integration.rs Тесты на основе фикстур
Rule в src/rules/basic.rsrun_all() в src/rules/mod.rsПодробнее см. в CONTRIBUTING.md.
MIT
| Код | Правило | Важность | Описание |
|---|
DUP_HOST | duplicate-host | предупреждение | Два блока Host с одинаковым шаблоном |
MISSING_IDENTITY | identity-file-exists | ошибка | Путь IdentityFile не существует |
WILDCARD_ORDER | wildcard-host-order | предупреждение | Host * стоит раньше конкретных шаблонов |
WEAK_ALGO | deprecated-weak-algorithms | предупреждение | Слабый или устаревший алгоритм (3des-cbc, arcfour, hmac-md5, ssh-dss и т.д.) |
DUP_DIRECTIVE | duplicate-directives | предупреждение | Одна и та же директива повторяется в одной области (действует только первое значение) |
INSECURE_OPT | insecure-option | предупреждение | Опасная настройка, например StrictHostKeyChecking no или ForwardAgent yes в Host * |
UNSAFE_CTRL_PATH | unsafe-control-path | предупреждение | В ControlPath отсутствуют %h, %p, %r (или %C) — соединения могут использовать один сокет |
INCLUDE_CYCLE | include-cycle | ошибка | Циклическая цепочка Include |
INCLUDE_READ | include-read | ошибка | Невозможно прочитать включённый файл |
INCLUDE_GLOB | include-glob | ошибка | Некорректный шаблон Include glob |
INCLUDE_NO_MATCH | include-no-match | информация | Шаблон Include не соответствует ни одному файлу |