
Linter basado en reglas para archivos de configuración del cliente OpenSSH que detecta hosts duplicados, archivos de identidad faltantes, algoritmos débiles, problemas de orden de comodines y configuraciones peligrosas con salida JSON y códigos de salida aptos para CI.
Un motor para cada lugar donde cambia tu configuración SSH.
sshconfig-lint encuentra errores semánticos en las configuraciones del cliente OpenSSH: hosts duplicados, rutas de identidad rotas, opciones inseguras, algoritmos débiles, orden de comodines y cadenas de Include enredadas. Usa los mismos códigos de reglas localmente, en hooks de Git, GitHub Actions y editores.
Prueba el playground privado en el navegador · Aprende con ejemplos interactivos · Lee todas las reglas
El verificador del navegador se ejecuta en tu dispositivo. El contenido de la configuración no se sube y no se recopila telemetría.
# check ~/.ssh/config
sshconfig-lint
# check one or more repository configs
sshconfig-lint .ssh/config infrastructure/ssh_config
# fail on warnings and errors
sshconfig-lint .ssh/config --strict
brew tap Noah4ever/tap
brew install sshconfig-lint
cargo install sshconfig-lint
yay -S sshconfig-lint-bin
La página de releases proporciona binarios verificados para Linux, macOS y Windows. El instalador de conveniencia verifica la suma de comprobación del release antes de instalar:
curl -fsSL https://raw.githubusercontent.com/Noah4ever/sshconfig-lint/main/install.sh | bash
Establece VERSION=v0.5.0 o INSTALL_DIR=~/.local/bin para sobrescribir los valores predeterminados.
La Action oficial está disponible en el GitHub Marketplace.
name: SSH config
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Noah4ever/[email protected]
with:
paths: |
.ssh/config
infrastructure/ssh_config
strict: true
Los hallazgos aparecen como anotaciones en el archivo y la línea exactos. La Action descarga el release que coincide con su etiqueta y verifica SHA256SUMS antes de la ejecución.
Para repositorios con GitHub Code Scanning habilitado, SARIF se puede subir por separado:
- run: sshconfig-lint .ssh/config --format sarif > sshconfig-lint.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: sshconfig-lint.sarif
repos:
- repo: https://github.com/Noah4ever/sshconfig-lint
rev: v1.0.0
hooks:
- id: sshconfig-lint-strict
Usa id: sshconfig-lint cuando las advertencias no deban bloquear un commit. Sobrescribe files: en tu proyecto cuando las configuraciones usen otra convención de nombres.
Instala la extensión de VS Code desde el Marketplace o ejecuta:
code --install-extension NoahThiering.sshconfig-lint
La extensión inicia sshconfig-lint lsp, descarga una vez un binario verificado que coincide y luego funciona sin conexión. Reconoce .ssh/config, ssh_config y dot_ssh/config de chezmoi. No se recopila telemetría. Su código fuente está disponible en editors/vscode.
El ejemplo probado de editors/neovim usa el cliente LSP
integrado de Neovim. Copia su pequeño módulo Lua en tu configuración e inícialo con:
require("sshconfig_lint").setup()
Usa el mismo servidor sshconfig-lint lsp que VS Code y admite una ruta
personalizada al binario.
Cualquier editor con soporte LSP puede iniciar:
sshconfig-lint lsp
El servidor de lenguaje v0.5 publica diagnósticos de línea completa al abrir, cambiar y guardar. Los búferes sin título ejecutan reglas solo de contenido; los archivos guardados además resuelven Include y rutas del sistema de archivos. Los hallazgos de Includes anidados se adjuntan al archivo incluido y se limpian con el documento raíz.
sshconfig-lint --format text
sshconfig-lint --format json
sshconfig-lint --format github
sshconfig-lint --format sarif
Los hallazgos JSON contienen severity, code, rule, line, file, message, hint y documentation. Los códigos de reglas y los códigos de salida son interfaces de automatización estables.
| Salida | Significado |
|---|---|
0 | Ningún hallazgo de nivel de error, y ninguna advertencia con --strict |
1 | Al menos un hallazgo bloqueante |
2 | Al menos una configuración solicitada no se pudo leer |
| Código | Regla | Severidad |
|---|---|---|
INVALID_VALUE | Valor de directiva no válido | error |
DUP_HOST | Bloque Host duplicado | warning |
MISSING_IDENTITY | IdentityFile no encontrado | error |
WILDCARD_ORDER | Orden de comodines en Host | warning |
WEAK_ALGO | Algoritmo débil | warning |
DUP_DIRECTIVE | Directiva duplicada | warning |
INSECURE_OPT | Opción insegura | warning |
UNSAFE_CTRL_PATH | ControlPath inseguro | warning |
INCLUDE_CYCLE | Ciclo de Include | error |
INCLUDE_DEPTH | Anidamiento de Include demasiado profundo | error |
INCLUDE_READ | No se puede leer el Include | error |
INCLUDE_GLOB | Patrón de Include no válido |
Las guías de reglas muestran el fragmento roto exacto, una configuración corregida, por qué importa y cómo verificar el resultado con OpenSSH.
INVALID_VALUE verifica puertos, contadores de reintentos y solicitudes, ajustes de alive, ForwardX11Timeout, RequiredRSASize, ControlPersist, interruptores booleanos, ObscureKeystrokeTiming, valores de tiempo de OpenSSH, StreamLocalBindMask, IPQoS y conjuntos de valores documentados como AddressFamily, ControlMaster, StrictHostKeyChecking, LogLevel y PubkeyAuthentication. Los valores entre comillas y sin distinción de mayúsculas aceptados por OpenSSH siguen siendo válidos. El linter acepta sintaxis moderna sin intentar inferir la versión del cliente SSH que consumirá la configuración.
Las comprobaciones del sistema de archivos omiten rutas que contienen tokens de porcentaje o variables de entorno porque su valor final depende del contexto de la conexión. LOCAL_COMMAND_DISABLED es igualmente conservador: se suprime cuando un Include sin resolver o cualquier posible PermitLocalCommand yes podría hacer efectivo el comando. Resuelve los Includes a través de la CLI normal o un documento guardado del editor para obtener el resultado más preciso.
Requiere Rust 1.85 o superior.
cargo test --all
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt -- --check
Consulta CONTRIBUTING.md, la hoja de ruta pública, el contrato de estabilidad v1 y la política de seguridad.
MIT
| error |
INCLUDE_NO_MATCH | Include no coincide con ningún archivo | info |
NEGATED_HOST | Host solo tiene patrones negados | warning |
PROXY_CONFLICT | Conflicto entre ProxyCommand y ProxyJump | warning |
REVOKED_HOST_KEYS_UNREADABLE | El archivo RevokedHostKeys no se puede leer | error |
MISSING_CERTIFICATE | CertificateFile no encontrado | error |
LOCAL_COMMAND_DISABLED | LocalCommand no está habilitado | warning |
INVALID_TOKEN | Token de porcentaje no válido | error |
INVALID_SYNTAX | Sintaxis no válida | error |
UNKNOWN_DIRECTIVE | Directiva desconocida | error |
DEPRECATED_OPTION | Opción obsoleta | warning |
INVALID_MATCH | Condición Match no válida | error |
CONTROL_PERSIST_UNUSED | ControlPersist sin ControlMaster | warning |
UPDATE_HOSTKEYS_ASK_PERSIST | UpdateHostKeys ask con ControlPersist | warning |