Problema
En entornos de producción con Windows Server 2022 se habilita la característica OpenSSH Server para ofrecer SFTP o acceso remoto a scripts de backup. Con frecuencia los administradores observan que las transferencias funcionan durante varios ciclos y, de repente, aparecen fallos sin un mensaje de error claro. Los síntomas típicos son:
- Conexiones SFTP que se cierran después de un tiempo sin razón aparente.
- Mensajes de “Connection closed by remote host” en los logs del cliente.
- Intermitencia que parece seguir un patrón de éxito‑fallo‑éxito.
- Ningún cambio reciente en la configuración del daemon (
sshd_config) ni en la red.
Este comportamiento es frustrante porque los backups pueden quedar incompletos y el equipo de operaciones pierde tiempo revisando credenciales, permisos de archivo y la configuración de cifrado, sin encontrar la causa raíz.
Causa
OpenSSH en Windows Server no es un port directo de la versión Linux; depende de componentes del subsistema de Windows y de la cuenta bajo la que corre el servicio. Las causas más habituales de los fallos intermitentes son:
-
Cuenta de servicio con privilegios insuficientes
El serviciosshdse ejecuta bajo la cuentaNT SERVICE\sshd. Cuando el proceso necesita crear una sesión de usuario para la autenticación, recurre a la cuenta que se especifica en el archivo de configuración (AuthorizedKeysFile,PasswordAuthentication, etc.). Si esa cuenta es un dominio o un usuario con membresías especiales, el proceso puede colgarse al intentar cargar perfiles o validar grupos, provocando timeouts. -
Política de contraseñas complejas y expiración
Windows impone políticas de complejidad y expiración que, combinadas con la forma en que OpenSSH valida contraseñas, pueden generar rechazos silenciosos después de varios intentos exitosos. La caché de credenciales de LSA a veces se invalida de forma inesperada. -
Problemas de sincronización de perfil de usuario
Cuando el usuario que se autentica no tiene un perfil cargado (por ejemplo, una cuenta local sin directorio de perfil), el daemon intenta crear uno bajo el contexto del servicio. Si la ruta del perfil está en una unidad de red o tiene ACLs restrictivas, la creación falla y la conexión se corta. -
Configuración de permisos NTFS sobre la carpeta del usuario
OpenSSH verifica que el directorio home del usuario sea accesible solo por él. Si la ACL permite a grupos como Administrators o Authenticated Users acceso de escritura, el daemon rechaza la sesión por motivos de seguridad, pero el mensaje llega al cliente como un cierre abrupto. -
Bugs específicos de la versión 8.9p1‑1 (o versiones cercanas) en Windows
En la rama de OpenSSH distribuida con Windows Server 2022 se reportó un bug que afecta la autenticación de usuarios locales sin pertenecer a grupos privilegiados. El fallo se manifiesta como desconexiones intermitentes y se soluciona creando un usuario local dedicado al servicio.
Solución
La estrategia consiste en aislar la autenticación a una cuenta local mínima y asegurarse de que el entorno de esa cuenta cumpla los requisitos de OpenSSH. Los pasos genéricos son:
-
Crear una cuenta local exclusiva para SSH/SFTP
- Nombre descriptivo (p.ej.
sshd_user). - Contraseña que cumpla la política de complejidad, pero sin expiración automática.
- Sin membresías de grupo adicionales; solo la pertenencia implícita a Users.
- Nombre descriptivo (p.ej.
-
Asignar un directorio home con permisos estrictos
- Crear
C:\Users\sshd_user(o cualquier ruta que prefiera). - Configurar ACLs:
FullControlsolo parasshd_userySYSTEM. - Eliminar herencia de permisos de carpetas superiores.
- Crear
-
Actualizar
sshd_configpara usar la cuenta recién creada- Establecer
Match User sshd_usery definirChrootDirectoryoForceCommand internal-sftpsegún la necesidad. - Asegurarse de que
PasswordAuthentication yes(si se usa contraseña) oPubkeyAuthentication yes(si se usan llaves) esté habilitado.
- Establecer
-
Desactivar expiración de contraseña y políticas de bloqueo para esa cuenta
- En
Local Security Policy→ Password Policy → Maximum password age →0(nunca). - En Account Lockout Policy → Account lockout threshold →
0(desactivar bloqueo temporal).
- En
-
Reiniciar el servicio OpenSSH
Restart-Service sshdonet stop sshd && net start sshd.
-
Validar que el servicio corre bajo la cuenta correcta
- Verificar en el Task Manager → Details que el proceso
sshd.exetiene el SIDNT SERVICE\sshd. - Los sub‑procesos que manejan la sesión deben aparecer con el SID del usuario
sshd_user.
- Verificar en el Task Manager → Details que el proceso
Alternativas
- Uso de autenticación basada en claves: elimina la dependencia de la política de contraseñas y reduce la superficie de error.
- Crear un grupo de servicio dedicado y añadir la cuenta al mismo, siempre que el grupo no tenga privilegios elevados.
- Actualizar OpenSSH a la última versión disponible en el repositorio de PowerShell/Win32‑OpenSSH, ya que los parches posteriores corrigen el bug mencionado.
Cuándo aplicar esta solución
Aplica cuando observes:
- Fallos de SFTP/SSH que aparecen de forma intermitente sin cambios en la red ni en la configuración del daemon.
- Logs de
sshdque muestran Connection closed sin códigos de error claros. - La cuenta usada para la autenticación es un dominio o un usuario con pertenencia a grupos administrativos.
No es necesario si:
- Todas las conexiones son estables y el problema está claramente ligado a una actualización de red o firewall.
- Se usan exclusivamente llaves públicas y la cuenta ya es local sin membresías adicionales.
Código
# 1. Crear usuario local sin privilegios
net user sshd_user "ContraseñaComplexa123!" /add /expires:never /passwordchg:no
# 2. Quitar al usuario de grupos adicionales (excepto Users)
net localgroup Administrators sshd_user /delete
net localgroup "Remote Desktop Users" sshd_user /delete
# 3. Crear directorio home y establecer ACLs estrictas
mkdir "C:\Users\sshd_user"
icacls "C:\Users\sshd_user" /inheritance:r
icacls "C:\Users\sshd_user" /grant:r "sshd_user:(OI)(CI)F" "SYSTEM:(OI)(CI)F"
# 4. Forzar que la contraseña no expire
wmic useraccount where name='sshd_user' set PasswordExpires=False
# 5. Reiniciar servicio OpenSSH
Restart-Service sshd
Verificación
-
Conexión básica
sftp sshd_user@<IP_DEL_SERVIDOR>La sesión debe abrirse sin solicitar cambio de contraseña.
-
Revisar logs de
sshdGet-Content "C:\ProgramData\ssh\logs\sshd.log" -Tail 20 -WaitNo deben aparecer líneas con Failed password o Connection closed después de la autenticación.
-
Comprobar permisos del home
icacls "C:\Users\sshd_user"Sólo
sshd_userySYSTEMdeben tener acceso total. -
Ejecutar un backup de prueba
Inicie el proceso de backup SFTP y confirme que el archivo llega al destino sin interrupciones.
Notas adicionales
- Si el entorno usa cuentas de dominio, crear un trust local y mapearla a un usuario local puede evitar el bug, pero implica mayor complejidad de gestión.
- En versiones anteriores de Windows Server, el servicio
sshda veces necesita la política Allow log on locally para la cuenta de servicio; verificar queNT SERVICE\sshdestá incluido en Log on as a service. - Mantener el paquete
Win32-OpenSSHactualizado reduce la exposición a bugs conocidos; la instalación se realiza conAdd-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0. - Cuando se usa
ChrootDirectory, la carpeta raíz del chroot debe ser propiedad deSYSTEMy no escribible por el usuario, de lo contrario el daemon aborta la sesión.
Con estos pasos, la mayoría de los fallos intermitentes de OpenSSH en Windows Server 2022 desaparecen, y los backups SFTP vuelven a ejecutarse de forma estable.