Guía completa y práctica para desactivar TLS trece en un sitio específico de IIS sobre Windows Server dos mil veintidós con PowerShell o AppCmd, y alternativas para mantener mTLS sin deshabilitar el protocolo. Incluye verificación, reversión y notas de operación segura en entornos de producción.
Panorama y motivo
En entornos que usan autenticación por certificado de cliente (mTLS), la adopción de TLS trece puede provocar fallos cuando la aplicación o la configuración del servidor intentan solicitar el certificado del cliente tras el intercambio inicial. En TLS doce esto se resolvía frecuentemente mediante renegociación; sin embargo, TLS trece limita este mecanismo. En Windows Server dos mil veintidós (IIS diez), existen tres caminos claros:
- Desactivar TLS trece solo en el binding HTTPS del sitio afectado, sin tocar el resto del servidor.
- Conservar TLS trece y ajustar HTTP.sys para que el certificado del cliente se negocie durante el primer handshake (workaround).
- Desactivar TLS trece globalmente en Schannel para todo el sistema.
La recomendación principal para minimizar el impacto es actuar por binding del sitio en IIS.
Lo esencial
- IIS permite controlar características TLS por binding mediante el atributo
sslFlags
. Un solo bit desactiva TLS trece sobre TCP para ese binding, sin afectar a otros sitios. - El bit correspondiente a “Disable TLS trece over TCP” se añade con una operación OR a los
sslFlags
existentes para no perder otras opciones como SNI, desactivar HTTP dos o desactivar QUIC. - Si necesitas mantener TLS trece con mTLS, puedes activar “Negotiate Client Certificate” en HTTP.sys para que el certificado se solicite en el primer handshake.
- También es posible desactivar TLS trece de forma global mediante el Registro del sistema (Schannel), lo cual impacta a todos los servicios que usen ese proveedor.
Recomendación principal por sitio en IIS
Esta opción evita el riesgo de deshabilitar TLS trece para todo el servidor y mantiene el control granular por aplicación o dominio.
PowerShell con el módulo WebAdministration
El siguiente script añade el bit de “Disable TLS trece over TCP” al sslFlags
del binding HTTPS indicado, preservando cualquier otro valor ya configurado (por ejemplo, SNI o deshabilitar HTTP dos o QUIC):
Import-Module WebAdministration
\$site = "Default Web Site" # <-- cámbialo por tu sitio
\$bindingInfo = "\*:443:" # <-- IP\:PUERTO\:HOSTHEADER (vacío = sin host header)
Ruta al binding HTTPS del sitio
\$filter = "system.applicationHost/sites/site\[@name='\$site']/bindings/binding\[@protocol='https' and @bindingInformation='\$bindingInfo']"
Lee flags actuales y añade el bit 32 (Disable TLS 1.3 over TCP)
\$current = (Get-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter \$filter -Name 'sslFlags').Value
\$new = (\[int]\$current) -bor 32
Aplica el nuevo valor
Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter \$filter -Name 'sslFlags' -Value \$new
Opcional: recicla el pool o reinicia el sitio para cortar conexiones persistentes
Restart-WebAppPool -Name 'NombreDelPool'
iisreset /noforce
Notas clave
sslFlags
es un campo por bits. No sobrescribas valores existentes: usa OR para añadir solo el bit deseado. Ejemplo: si ya tienes SNI (bit uno) y desactivar QUIC (bit dieciséis), añadir “Disable TLS trece over TCP” implica OR con treinta y dos. Resultado: uno + dieciséis + treinta y dos = cuarenta y nueve.- El cambio afecta a nuevas conexiones. Para que sea inmediato en todos los clientes, recicla el App Pool o reinicia el sitio.
- Si el sitio ofrece HTTP tres (QUIC), recuerda que TLS trece se usa siempre sobre QUIC. Si tu objetivo es evitar TLS trece por completo, además desactiva QUIC en el binding (bit por desactivar QUIC) o a nivel del servidor.
AppCmd como alternativa directa
Si ya conoces el valor final de sslFlags
que necesitas (por ejemplo, SNI + Disable TLS trece = treinta y tres):
%windir%\system32\inetsrv\appcmd.exe set site /site.name:"Default Web Site" ^
/bindings.[protocol='https',bindingInformation='*:443:'].sslFlags:33
Para confirmar el resultado con PowerShell:
Get-WebBinding -Name "Default Web Site" -Protocol https |
Select-Object protocol,bindingInformation,sslFlags | Format-Table -AutoSize
Consideraciones de operación
- Certificados y SNI: si usas SNI, asegúrate de que
bindingInformation
incluye el host y que el certificado correcto está asociado a ese binding. - HTTP dos y HTTP tres: deshabilitar TLS trece sobre TCP no afecta a QUIC. Para eliminar cualquier ruta de TLS trece, desactiva también QUIC en el binding o a nivel global.
- Pruebas: valida desde un equipo cliente con herramientas de línea de comandos antes de poner en producción.
Solución con certificados de cliente sin deshabilitar el protocolo
Si debes conservar TLS trece y a la vez usar mTLS, puedes indicarle a HTTP.sys que negocie el certificado en el primer intercambio. Esto evita la dependencia de renegociación posterior.
Registro en HTTP.sys
Ejemplo de clave para un binding de todo el sistema en la dirección cero punto cero punto cero punto cero y puerto cuatrocientos cuarenta y tres. El valor “DefaultFlags = dos” habilita negociar certificado de cliente:
HKLM\SYSTEM\ControlSet001\Services\HTTP\Parameters\SslBindingInfo\0.0.0.0:443
DWORD DefaultFlags = 2
Después de ajustar el registro, reinicia el servicio HTTP o el servidor según tus políticas de cambio para garantizar que la configuración se aplique a todas las conexiones.
Uso de netsh
También puedes gestionar el binding SSL de HTTP.sys con netsh
. El parámetro relevante es clientcertnegotiation=enable
. La sintaxis exacta depende de tu entorno, pero la idea es agregar o actualizar el certificado asociado a la IP y puerto con la negociación de certificado habilitada:
netsh http show sslcert
REM Basado en la salida anterior, vuelve a agregar o actualiza el binding
REM con clientcertnegotiation habilitado
netsh http add sslcert ipport=0.0.0.0:443 certhash=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX appid={00000000-0000-0000-0000-000000000000} certstorename=MY clientcertnegotiation=enable
Advertencia: aunque este enfoque resuelve la mayoría de escenarios prácticos, puede no ajustarse estrictamente a ciertas interpretaciones del estándar. Úsalo bajo tu criterio y documenta la excepción para auditoría.
Ventajas y límites
- Ventaja: conservas TLS trece para clientes que no usan mTLS y evitas tocar otros sitios.
- Límite: añade complejidad en HTTP.sys; requiere gobierno de cambios claro y pruebas de compatibilidad.
Desactivar en todo el servidor con Schannel
Si tu política requiere eliminar TLS trece de forma global, puedes hacerlo con las claves de Schannel en el Registro. Impacta a todas las aplicaciones que usen Schannel, no solo IIS.
PowerShell para el Registro de Schannel
# Desactivar TLS 1.3 en modo servidor (inbound)
New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server' -Force | Out-Null
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server' -Name 'Enabled' -Value 0 -PropertyType DWord -Force | Out-Null
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server' -Name 'DisabledByDefault' -Value 1 -PropertyType DWord -Force | Out-Null
(Opcional) Desactivar TLS 1.3 como cliente (outbound)
New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client' -Force | Out-Null
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client' -Name 'Enabled' -Value 0 -PropertyType DWord -Force | Out-Null
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client' -Name 'DisabledByDefault' -Value 1 -PropertyType DWord -Force | Out-Null
Buenas prácticas: programa una ventana de mantenimiento y un reinicio controlado. Aunque algunos servicios toman el cambio tras reciclar procesos, un reinicio evita estados ambiguos en sesiones TLS persistentes.
Verificación y pruebas
Valida el resultado desde el servidor y desde un host externo.
Comprobación en IIS
Get-WebBinding -Name "MiSitio" -Protocol https |
Format-Table protocol,bindingInformation,sslFlags -AutoSize
Confirma que sslFlags
incluye el bit correspondiente a “Disable TLS trece over TCP”.
Pruebas remotas con OpenSSL
# Prueba forzando TLS 1.3 (debe fallar cuando está deshabilitado en el binding)
openssl sclient -connect dominio:443 -tls13
Prueba forzando TLS 1.2 (debe funcionar)
openssl s\client -connect dominio:443 -tls1\2
Pruebas con curl
# Falla si TLS trece está deshabilitado sobre TCP
curl -vk --tlsv1.3 https://dominio/
Debe funcionar con TLS doce
curl -vk --tlsv1.2 [https://dominio/](https://dominio/)
Comprobación de HTTP.sys para mTLS
netsh http show sslcert
REM Busca "Negotiate Client Certificate : Enabled" en la IP:puerto correspondiente
Tabla de opciones de sslFlags
Referencia rápida de los bits más habituales en sslFlags
para bindings HTTPS de IIS. Usa OR para combinarlos según tu escenario:
Bit | Valor | Significado | Cuándo usar |
---|---|---|---|
uno | 1 | Indica SNI (Server Name Indication). | Hosting múltiple por nombre con certificados por host. |
dos | 2 | Uso de certificados centralizados. | Cuando empleas almacén central de certificados. |
cuatro | 4 | Desactivar HTTP dos en HTTPS. | Diagnóstico o compatibilidad con clientes antiguos. |
dieciséis | 16 | Desactivar QUIC (HTTP tres) en el binding. | Evitar ruta de QUIC cuando necesitas control solo por TCP. |
treinta y dos | 32 | Desactivar TLS trece sobre TCP en el binding. | Solucionar problemas de mTLS en ese sitio sin tocar el resto. |
Nota: la lista anterior se centra en las opciones relevantes para este artículo.
Escenarios de uso
- Aplicación con mTLS roto tras migración: añade el bit de “Disable TLS trece over TCP” en el binding del sitio afectado. Si además usas HTTP tres, desactívalo para evitar rutas alternativas.
- Plataforma multisitio: aplica el cambio solo a los sitios que lo requieran. Mantén TLS trece en sitios que no usan mTLS para conservar beneficios de seguridad y rendimiento.
- Requisitos normativos específicos: si el cliente exige TLS doce por contrato, aplica la política por binding y documenta la excepción.
Ejemplos listos para copiar
Función idempotente para un solo sitio
function Disable-Tls13OnHttpsBinding {
param(
[Parameter(Mandatory=$true)][string]$SiteName,
[Parameter(Mandatory=$true)][string]$BindingInformation # Ej: ":443:" o "0.0.0.0:443:" o ":443:dominio.com"
)
Import-Module WebAdministration
$filter = "system.applicationHost/sites/site[@name='$SiteName']/bindings/binding[@protocol='https' and @bindingInformation='$BindingInformation']"
$prop = Get-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter $filter -Name 'sslFlags'
if (-not $prop) { throw "Binding HTTPS no encontrado para $SiteName con $BindingInformation" }
$current = [int]$prop.Value
$desired = $current -bor 32
if ($desired -ne $current) {
Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter $filter -Name 'sslFlags' -Value $desired | Out-Null
Write-Host "Actualizado sslFlags de $current a $desired"
} else {
Write-Host "Sin cambios: TLS trece ya estaba deshabilitado sobre TCP (sslFlags=$current)"
}
}
Ejemplo:
Disable-Tls13OnHttpsBinding -SiteName "Default Web Site" -BindingInformation "*:443:"
Aplicar a múltiples sitios automáticamente
Import-Module WebAdministration
$bindings = Get-WebBinding | Where-Object { $_.protocol -eq 'https' }
foreach ($b in $bindings) {
$filter = "system.applicationHost/sites/site[@name='$($b.itemXPath.Split(\"'\")[1])']/bindings/binding[@protocol='https' and @bindingInformation='$($b.bindingInformation)']"
$current = (Get-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter $filter -Name 'sslFlags').Value
$new = ([int]$current) -bor 32
if ($new -ne $current) {
Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter $filter -Name 'sslFlags' -Value $new | Out-Null
Write-Host "Binding $($b.bindingInformation): sslFlags $current -> $new"
} else {
Write-Host "Binding $($b.bindingInformation): sin cambios"
}
}
Reversión limpia por sitio
Para revertir, elimina el bit de “Disable TLS trece” conservando el resto:
Import-Module WebAdministration
$site = "Default Web Site"
$bindingInfo = "*:443:"
$filter = "system.applicationHost/sites/site[@name='$site']/bindings/binding[@protocol='https' and @bindingInformation='$bindingInfo']"
\$current = (Get-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter \$filter -Name 'sslFlags').Value
Quita el bit 32 con AND sobre el complemento
\$new = (\[int]\$current) -band (-bnot 32)
Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter \$filter -Name 'sslFlags' -Value \$new
Preguntas frecuentes
¿Desactivar TLS trece en el binding afecta a otros sitios del servidor?
No. El cambio es específico del binding HTTPS sobre el que se aplica.
¿Qué pasa si el cliente intenta usar HTTP tres?
HTTP tres usa QUIC y TLS trece por diseño. Si no desactivas QUIC, el cliente podría seguir negociando TLS trece por esa vía. Si deseas evitarlo, añade el bit de “desactivar QUIC” en el binding o desactívalo globalmente.
¿Es necesario reiniciar el servidor tras modificar sslFlags
?
No suele ser necesario. Los cambios aplican a nuevas conexiones. Para acelerar la adopción en clientes con conexiones persistentes, recicla el App Pool o reinicia el sitio.
¿Cuándo conviene la solución de HTTP.sys?
Cuando debas conservar TLS trece por razones de seguridad o compatibilidad, pero tu aplicación depende de solicitar el certificado de cliente en el primer intercambio. Documenta el cambio y pruébalo a conciencia.
¿Cómo verifico rápidamente desde un Linux o macOS?
Con openssl s_client
o curl
forzando la versión del protocolo, tal como se muestra en la sección de verificación.
Riesgos y recomendaciones de seguridad
- Reducción de superficie moderna: desactivar TLS trece te priva de mejoras de seguridad y rendimiento. Mantén un plan para volver a habilitarlo cuando sea viable.
- Telemetría y alertas: monitoriza errores de negociación TLS, códigos de estado y quejas de clientes. Revisa logs de IIS y del sistema.
- Cobertura de pruebas: valida navegadores, SDKs y agentes automatizados. Determina si existen clientes que solo negocian HTTP tres.
- Política de certificados: asegúrate de que la cadena de confianza, EKUs y revocación están al día; muchos problemas atribuidos a TLS trece en realidad son fallos de la PKI.
Reversión y plan de salida
- Por binding: elimina el bit correspondiente en
sslFlags
y recicla el proceso de trabajo. - Global: establece
Enabled=1
yDisabledByDefault=0
en las claves de Server y Client para TLS trece de Schannel y reinicia durante una ventana de mantenimiento. - Documentación: registra quién, cuándo y por qué se aplicaron los cambios; adjunta evidencias de pruebas.
Notas para operación diaria
- Incluye la comprobación de
sslFlags
en tus auditorías de configuración. - Automatiza con scripts idempotentes para evitar errores manuales.
- Versiona los archivos de configuración de IIS (
applicationHost.config
) o usa desired state con tu herramienta de automatización favorita.
Resumen ejecutivo
- Es posible y seguro desactivar TLS trece por sitio en IIS ajustando
sslFlags
del binding HTTPS mediante PowerShell o AppCmd. - Si necesitas mantener TLS trece junto con mTLS, habilita la negociación de certificado en HTTP.sys para forzar la solicitud en el primer intercambio.
- Como última opción, deshabilita TLS trece globalmente en Schannel, planificando reinicio y comunicando el cambio.
- Verifica con herramientas de línea de comandos y documenta el estado de cada binding.
Apéndice de comandos rápidos
Objetivo | Comando | Resultado esperado |
---|---|---|
Ver bindings y sslFlags | Get-WebBinding -Protocol https | ft protocol,bindingInformation,sslFlags | Lista todos los bindings HTTPS con sus flags actuales. |
Desactivar TLS trece por sitio | Set-WebConfigurationProperty ... -Name 'sslFlags' -Value ($current -bor 32) | El binding niega TLS trece sobre TCP en nuevas conexiones. |
Forzar prueba con TLS trece | openssl sclient -connect dominio:443 -tls13 | Falla la negociación si el sitio lo tiene deshabilitado. |
Forzar prueba con TLS doce | openssl sclient -connect dominio:443 -tls12 | Se establece la conexión exitosamente si TLS doce está habilitado. |
Ver estado de HTTP.sys | netsh http show sslcert | Indica si “Negotiate Client Certificate” está habilitado por IP:puerto. |
Seguridad: desactivar protocolos modernos debe ser una medida temporal mientras resuelves incompatibilidades. Planifica volver a TLS trece una vez que la aplicación o el proxy frontal negocien el certificado de cliente en el primer intercambio.
Conclusión
Con los mecanismos disponibles en IIS y HTTP.sys puedes corregir de forma quirúrgica los fallos de mTLS relacionados con TLS trece sin comprometer la postura de seguridad del resto de tu plataforma. Empieza por el ajuste por binding, valida con pruebas controladas y documenta tanto el cambio como la ruta de reversión.