Improve SGU logon resilience and client UX

This commit is contained in:
2026-09-01 10:37:40 -06:00
parent 3d0897316d
commit da01343985
27 changed files with 869 additions and 37 deletions
+10
View File
@@ -52,6 +52,16 @@ digits of the requested `AD` identity before any scraped metadata is trusted.
Missing metadata does not clear existing AD values and never changes the
password outcome.
Human-readable SGU values are decoded with BOM/header/meta detection, strict
UTF-8 validation, and a Windows-1252 fallback for the legacy portal. Names and
titles are normalized with Spanish-aware casing; particles such as `de`, `del`
and `de la` remain lowercase and Unicode accents are preserved. Values that
still contain the Unicode replacement character are not written to AD.
When `RemoteDesktopGroupDn` is configured, the broker also adds each successfully
synchronized SGU user to that dedicated AD security group. The laboratory
Windows client maps the group into its local **Remote Desktop Users** group.
The managed hierarchy is rooted at `OU=Usuarios-SGU`: `Docentes`, `Alumnos`,
and `Administrativos` are direct child OUs beneath it.
+79
View File
@@ -0,0 +1,79 @@
# Operación del SGU Authentication Broker
## Dónde se ejecuta
En el laboratorio, el broker se ejecuta en el controlador de dominio Windows
Server:
| Elemento | Valor |
|---|---|
| Equipo | `WIN-1AIQMMA1EPR.lci.lasalle.mx` |
| Servicio | `SGUAuthBroker` / `SGU Authentication Broker` |
| Ejecutable | `C:\Program Files\SGU\AuthBroker\SGU.AuthBroker.exe` |
| Configuración | `C:\Program Files\SGU\AuthBroker\appsettings.Production.json` |
| Endpoint cliente | `https://sgu-auth.lci.lasalle.mx:8443/v1/authenticate` |
| Salud | `https://sgu-auth.lci.lasalle.mx:8443/health/live` |
| Transporte | HTTPS 1.1 con certificado de cliente obligatorio (mTLS) |
El Credential Provider no se comunica directamente con Active Directory ni
conserva una contraseña. Envía la clave y la contraseña originales al broker;
el broker valida SGU, actualiza la cuenta de dominio y devuelve solamente el
dominio y el nombre de usuario canónico.
## Comprobación rápida
Ejecutar como administrador en Windows Server:
```powershell
Get-CimInstance Win32_Service -Filter "Name='SGUAuthBroker'" |
Select-Object Name, State, StartMode, PathName, ProcessId
Get-NetTCPConnection -LocalPort 8443 -State Listen
Get-NetFirewallRule -DisplayName 'SGU Authentication Broker (mTLS)'
sc.exe qfailure SGUAuthBroker
```
Desde un cliente que tenga el certificado mTLS:
```powershell
Invoke-WebRequest `
-Uri https://sgu-auth.lci.lasalle.mx:8443/health/live `
-CertificateThumbprint CLIENT_CERT_THUMBPRINT
```
Una petición sin un certificado cliente válido debe ser rechazada durante TLS.
Eso es comportamiento esperado, no una caída del servicio.
## Timeouts y recuperación
- El Credential Provider espera hasta **20 segundos** por el broker.
- El broker espera hasta **15 segundos** por SGU. Un portal que normalmente
tarda alrededor de seis segundos queda dentro del margen sin bloquear LogonUI
indefinidamente.
- El instalador configura recuperación del servicio con reinicios a los 5, 15
y 60 segundos y reinicia el contador de fallos después de 24 horas.
- Si el broker o SGU no está disponible, el Credential Provider entrega la
contraseña intacta a Windows. AD o el caché de inicio de sesión de Windows aún
debe validarla; el fallback no concede acceso por sí mismo.
Reiniciar o volver a desplegar el servicio produce una interrupción breve en un
laboratorio con una sola instancia. Antes de una demostración, comprobar
`Running` y el listener 8443.
## Diagnóstico
```powershell
Get-WinEvent -FilterHashtable @{
LogName='Application'
StartTime=(Get-Date).AddHours(-1)
} | Where-Object ProviderName -eq 'SGU Authentication Broker' |
Select-Object TimeCreated, LevelDisplayName, Id, Message
Get-Content 'C:\Program Files\SGU\AuthBroker\appsettings.Production.json' -Raw |
ConvertFrom-Json |
Select-Object -ExpandProperty Broker
```
Nunca habilitar registro de cuerpos HTTP: contienen la contraseña durante la
solicitud. Los certificados, no las contraseñas, proporcionan la identidad entre
el cliente y el broker.
+60
View File
@@ -0,0 +1,60 @@
# ADR 0001: no usar Redis como caché de contraseñas
- Estado: aceptado
- Alcance: autenticación SGU y fallback sin conexión
## Contexto
SGU puede tardar varios segundos o quedar temporalmente fuera de servicio. Se
consideró instalar Redis persistente en el mismo Windows Server que hospeda el
broker y Active Directory, almacenando un hash con sal/clave o una contraseña
cifrada.
## Decisión
No se almacenarán contraseñas, contraseñas cifradas, hashes, HMAC ni otros
verificadores de contraseña en Redis. Tampoco se instalará Redis en el
controlador de dominio.
El mecanismo de continuidad es el ya proporcionado por Windows:
1. una autenticación SGU exitosa sincroniza la contraseña original a AD;
2. AD valida esa contraseña mientras el controlador es accesible;
3. Windows conserva su verificador de inicio de sesión de dominio para equipos
desconectados;
4. si SGU o el broker no responde, el Credential Provider entrega la misma
credencial a Windows y deja que AD/LSA decidan.
## Motivos
- Un hash no permite recuperar la contraseña original. Comparar la contraseña
presentada contra otro verificador solo duplicaría el material atacable que
ya mantienen AD y Windows.
- Una contraseña cifrada es un secreto reversible; colocar la clave de descifrado
junto al broker convierte el caché en una bóveda de credenciales reutilizables.
- Un caché persistente aceptaría durante más tiempo una contraseña revocada y
añadiría una tercera fuente de verdad entre SGU y AD.
- Redis persistente escribe RDB/AOF a disco. La documentación de Redis recomienda
controles adicionales como TLS, ACL y cifrado del lado cliente.
- Redis Open Source no tiene un servicio Windows nativo propio; Redis documenta
Memurai o WSL para Windows. Ninguna opción debe ampliar la superficie de ataque
de un controlador de dominio.
- Microsoft recomienda reducir el software instalado en controladores de dominio
y tratarlos como sistemas sensibles de propósito único.
Referencias:
- <https://learn.microsoft.com/en-us/troubleshoot/windows-server/user-profiles-and-logon/cached-domain-logon-information>
- <https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/plan/security-best-practices/securing-domain-controllers-against-attack>
- <https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/>
- <https://redis.io/docs/latest/operate/oss_and_stack/install/archive/install-redis/install-redis-on-windows/>
- <https://redis.io/docs/latest/operate/rs/security/recommended-security-practices/>
## Alternativa permitida en el futuro
Redis podría ser útil para metadatos no secretos —nombre normalizado,
dependencia, puesto o control de tasa distribuido— si existe más de una instancia
del broker. En ese caso debe ejecutarse en un servidor miembro o VM Linux
separada, usar TLS y ACL, tener TTL corto y nunca participar en la decisión de
aceptar una contraseña. Con una sola instancia, un caché en memoria es más
simple y no añade otra dependencia al inicio de sesión.
+16
View File
@@ -80,6 +80,7 @@ certificate thumbprint:
-PublishPath C:\Deploy\broker `
-ServerCertificateSubject sgu-auth.lci.lasalle.mx `
-AllowedClientThumbprints CLIENT_CERT_THUMBPRINT `
-RemoteDesktopGroupDn 'CN=SG-Laboratorio-Usuarios-RDP,OU=Laboratorio,DC=lci,DC=lasalle,DC=mx' `
-CreateMissingOus `
-DisableCertificateRevocationCheckForLab
```
@@ -88,6 +89,8 @@ Verify the service and managed OUs:
```powershell
Get-Service SGUAuthBroker
Get-NetTCPConnection -LocalPort 8443 -State Listen
sc.exe qfailure SGUAuthBroker
Get-ADOrganizationalUnit -Filter * -SearchBase 'OU=Usuarios-SGU,DC=lci,DC=lasalle,DC=mx'
```
@@ -116,6 +119,7 @@ On Windows 10:
-BrokerEndpoint https://sgu-auth.lci.lasalle.mx:8443/v1/authenticate `
-ClientCertificateThumbprint CLIENT_CERT_THUMBPRINT `
-ServerCertificateThumbprint SERVER_CERT_THUMBPRINT `
-TimeoutSeconds 20 `
-InstallDotNetRuntime `
-DotNetRuntimeInstallerPath C:\SGUDeploy\prerequisites\dotnet-runtime-10.0.11-win-x64.exe
```
@@ -124,6 +128,18 @@ Use Lithnet's `Invoke-CredUI` test utility when available, or lock the VM and
select **Acceso institucional SGU** under sign-in options. Keep the built-in
Windows password tile visible.
Before testing through Hyper-V Enhanced Session/RDP, enable the dedicated lab
group and Windows PowerShell Remoting:
```powershell
.\Enable-LabRemoteAccess.ps1 `
-RemoteDesktopPrincipal 'LCI\SG-Laboratorio-Usuarios-RDP' `
-EnableAdministrativeFirewallGroups
```
See [`windows-client-onboarding.md`](windows-client-onboarding.md) for domain
join, RDP, WinRM, firewall, and error `0xC000015B` diagnostics.
## 6. Required end-to-end cases
1. Online valid `DO`, `AL`, and `AD` logons; verify each OU.
+6
View File
@@ -52,6 +52,12 @@ infrastructure:
to Windows. Windows must still validate it against AD or the cached domain
verifier, so this does not grant access without the last synchronized password.
Redis is deliberately not used for password continuity. A second persistent
password verifier duplicates attackable credential material, while a reversible
encrypted password becomes a credential vault. AD and Windows cached domain
logon already implement the required last-known-password behavior. See
[`decisions/0001-no-password-cache.md`](decisions/0001-no-password-cache.md).
The installer never registers a Credential Provider filter and never disables
Microsoft's password, PIN, smart-card, or Windows Hello providers.
+117
View File
@@ -0,0 +1,117 @@
# Alta de un equipo Windows en el laboratorio LCI
Esta guía configura un Windows 10/11 Pro o Enterprise para el dominio, RDP con
NLA y PowerShell Remoting. Está pensada para la red aislada del laboratorio; no
abre estos servicios en el perfil de red pública.
## 1. Prerrequisitos
- Una cuenta con permiso para unir equipos al dominio.
- DNS primario del adaptador apuntando al controlador de dominio
`192.168.50.10`.
- Conectividad con `lci.lasalle.mx` y hora sincronizada.
- Windows Pro, Enterprise o Education para actuar como host RDP.
```powershell
Get-NetAdapter
Set-DnsClientServerAddress -InterfaceAlias 'Ethernet' `
-ServerAddresses 192.168.50.10
Resolve-DnsName -Type SRV _ldap._tcp.dc._msdcs.lci.lasalle.mx
```
## 2. Unir el equipo al dominio
Abrir Windows PowerShell como administrador. El prompt solicita la contraseña
de forma interactiva y evita ponerla en el historial:
```powershell
$domainCredential = Get-Credential -UserName 'LCI\Administrator'
Add-Computer `
-DomainName 'lci.lasalle.mx' `
-Credential $domainCredential `
-Restart
```
Después del reinicio:
```powershell
(Get-CimInstance Win32_ComputerSystem) |
Select-Object Name, Domain, PartOfDomain
```
## 3. Habilitar acceso remoto
El grupo de dominio `LCI\SG-Laboratorio-Usuarios-RDP` es el único principal de
usuarios SGU agregado al grupo local **Remote Desktop Users**. El broker agrega
automáticamente a ese grupo cada cuenta que sincroniza; no concede permisos de
administrador.
Copiar `scripts\Enable-LabRemoteAccess.ps1` al equipo y ejecutar. El bypass se
limita a este proceso y no cambia la directiva persistente del equipo:
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass `
-File .\Enable-LabRemoteAccess.ps1 `
-RemoteDesktopPrincipal 'LCI\SG-Laboratorio-Usuarios-RDP' `
-EnableAdministrativeFirewallGroups
```
El script realiza de forma idempotente lo siguiente:
- habilita RDP y conserva Network Level Authentication;
- habilita las reglas RDP solo para el perfil Domain;
- autoriza el grupo SGU dedicado;
- habilita Windows PowerShell Remoting/WinRM;
- opcionalmente habilita administración remota de servicios, eventos y WMI,
también limitada al perfil Domain.
PowerShell Direct de Hyper-V no requiere abrir puertos en la VM y sigue siendo
la opción preferida para recuperación administrativa.
## 4. Instalar el Credential Provider
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass `
-File .\Install-CredentialProvider.ps1 `
-PublishPath C:\SGUDeploy\credential-provider `
-BrokerEndpoint https://sgu-auth.lci.lasalle.mx:8443/v1/authenticate `
-ClientCertificateThumbprint CLIENT_CERT_THUMBPRINT `
-ServerCertificateThumbprint SERVER_CERT_THUMBPRINT `
-TimeoutSeconds 20
```
Los binarios se guardan en un subdirectorio `versions` identificado por su
contenido. De esta forma se puede preparar una actualización aunque
`LogonUI.exe` todavía tenga cargada la DLL anterior; el reinicio obligatorio
activa la nueva versión.
Bloquear el equipo, abrir **Sign-in options** y elegir el icono azul con llave
del acceso SGU. El proveedor de contraseña de Microsoft debe permanecer visible.
## 5. Verificación
```powershell
Get-Service TermService, WinRM
Get-LocalGroupMember -Group 'Remote Desktop Users'
Test-WSMan localhost
Test-NetConnection sgu-auth.lci.lasalle.mx -Port 8443
```
Desde otro equipo administrador:
```powershell
Test-WSMan NOMBRE-DEL-EQUIPO
Enter-PSSession -ComputerName NOMBRE-DEL-EQUIPO -Credential LCI\Administrator
mstsc.exe /v:NOMBRE-DEL-EQUIPO
```
El mensaje “the user has not been granted the requested logon type” con evento
4625, `LogonType=10` y estado `0xC000015B` indica autorización RDP, no una
contraseña incorrecta. Comprobar que la cuenta pertenece a
`SG-Laboratorio-Usuarios-RDP` y que ese grupo aparece en **Remote Desktop Users**.
Las directivas de grupo de dominio prevalecen sobre la política local.
Microsoft documenta este derecho en:
<https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-userrights#allowlogonthroughremotedesktop>
y PowerShell Remoting en:
<https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/enable-psremoting>.