Puertos “abiertos” pese a estar bloqueados en Windows Server 2022 con Plesk: diagnóstico y cierre real

Tras una caída de un Windows Server 2022 con Plesk, Nmap seguía mostrando los puertos 110/143/1433/3306 “abiertos” pese a bloquearlos. Esta guía explica por qué ocurre y cómo conseguir un cierre real: diagnóstico, endurecimiento por capas, verificación externa y medidas para evitar que se repita.

Índice

Contexto y síntoma

Después de un apagón del servidor (Windows Server 2022 21H2) se observaron tres efectos en cascada: pérdida de reglas de firewall gestionadas por Plesk (frontend de Windows Defender Firewall), asignación temporal de una IP APIPA 169.254.x.x y disrupciones de correo. Tras reponer reglas y eliminar la APIPA todo pareció normal, pero al bloquear 110 (POP3), 143 (IMAP), 1433 (SQL Server) y 3306 (MySQL) —tanto desde Plesk como desde Windows Defender Firewall— Nmap seguía reportándolos como “open”. ¿Qué está pasando y cómo cerrarlos de verdad?

Por qué un puerto parece abierto cuando crees que está bloqueado

  • Proceso local aún escuchando: si el servicio sigue en “LISTEN”, el puerto está abierto localmente, aunque el firewall pueda bloquear conexiones externas. Un escaneo desde el propio host verá el puerto abierto por diseño.
  • Reglas ligadas al perfil equivocado: el cambio de red a Public (típico al aparecer una APIPA) invalida reglas aplicadas solo a Domain/Private.
  • Ámbitos de IP mal definidos: bloqueos limitados a una IP anterior o a una subred concreta dejan huecos cuando el servidor cambia de dirección.
  • Falta de cobertura IPv6: si IPv6 está habilitado y solo se bloqueó IPv4, habrá exposición por la pila v6.
  • Tráfico local que el firewall no filtra: conexiones loopback o locales pueden “saltar” reglas que afectan solo al tráfico entrante desde la red.
  • Plesk reescribe o desincroniza reglas: la extensión Firewall de Plesk puede restaurar plantillas que permitan puertos durante cambios de configuración.
  • Capas externas: un firewall/NAT del proveedor (NSG/SG) puede permitir o denegar independientemente; si pruebas solo desde dentro, confundes el estado real.

Guía de diagnóstico exprés

Aplica estos pasos en orden. El objetivo es comprobar desde fuera, identificar qué escucha, confirmar perfil/alcance activo y eliminar permisos accidentales.

  1. Comprobación desde un vantage point externo (no desde el propio servidor): nmap -Pn -sS -p 110,143,1433,3306 TUIPPUBLICA O desde PowerShell en otra máquina Windows Test-NetConnection TUIPPUBLICA -Port 1433 -InformationLevel Detailed Un escaneo local puede ver puertos abiertos que el firewall impediría a clientes externos.
  2. Ver qué procesos están en LISTEN: Get-NetTCPConnection -State Listen | Sort-Object LocalPort | Format-Table -Auto Para cada puerto (ejemplo: 110) \$pid = (Get-NetTCPConnection -State Listen -LocalPort 110).OwningProcess Get-Process -Id \$pid | Select-Object Id, ProcessName, Path Si un servicio que no necesitas está escuchando, apágalo y deshabilítalo antes de jugar con el firewall.
  3. Confirmar perfil de red y estado del firewall: Get-NetConnectionProfile Get-NetFirewallProfile | Select-Object Name, Enabled, DefaultInboundAction Con APIPA es frecuente que el perfil activo sea Public. Asegúrate de que tus reglas operan en el perfil correcto.
  4. Descubrir “Allow” activos sobre esos puertos: Get-NetFirewallRule -Enabled True -Action Allow | Get-NetFirewallPortFilter | Where-Object { $.Protocol -eq 'TCP' -and $.LocalPort -match '^(110|143|1433|3306)$' } | Format-List * Si aparece alguna regla “Allow” inesperada, deshabilítala o elimínala. Repite para UDP 1434 (SQL Browser).
  5. Revisar ámbitos de IP (que no se hayan quedado atados a una IP vieja): Get-NetFirewallRule -DisplayName '110','143','1433','3306' | Get-NetFirewallAddressFilter | Format-List LocalAddress,RemoteAddress
  6. Comprobar cobertura IPv6 y UDP:
    • Para SQL Server, además de 1433/TCP, verifica 1434/UDP (servicio Browser).
    • Confirma que las reglas no están limitadas a IPv4 si el host tiene IPv6.
  7. Capas externas del proveedor (cloud/hosting): confirma que el Security Group o firewall externo también bloquea.
  8. Sincronización con Plesk:
    • En Plesk → ExtensionesFirewall, reaplica la configuración o reinstala la extensión si se “reseteó”.
    • Evita reglas ligadas a una interfaz o IP concreta que puedan cambiar al reaparecer una APIPA.

Matriz de puertos y verificación

PuertoServicio típicoProceso habitual en Plesk/WindowsComando de inspecciónApagado/limitación recomendada
110/TCPPOP3MailEnable POPGet-NetTCPConnection -State Listen -LocalPort 110Detener y deshabilitar POP si no se usa.
143/TCPIMAPMailEnable IMAPGet-NetTCPConnection -State Listen -LocalPort 143Detener y deshabilitar IMAP si no se usa.
1433/TCPSQL Serversqlservr.exeGet-NetTCPConnection -State Listen -LocalPort 1433Limitar a 127.0.0.1 o deshabilitar TCP/IP si es local-only.
1434/UDPSQL Browsersqlbrowser.exenetstat -ano -p udp | findstr 1434Bloquear UDP o deshabilitar Browser si no es necesario.
3306/TCPMySQLmysqld.exeGet-NetTCPConnection -State Listen -LocalPort 3306bind-address=127.0.0.1 en MySQL si es local-only.

Correcciones y endurecimiento por capas

La estrategia más robusta es “apagar, limitar, bloquear”. Es decir: primero detén servicios innecesarios, luego limita escuchas a localhost o redes internas, y finalmente blinda con firewall.

Apagar o inhabilitar servicios que no usas

  • POP3/IMAP (en Plesk para Windows suele ser MailEnable): en services.msc detén “MailEnable POP Service” y “MailEnable IMAP Service” y pon Startup type en Disabled si no los necesitas.
  • SQL Server / MySQL expuestos: si solo se consumen localmente, haz que no escuchen externamente.
    • SQL Server: en SQL Server Configuration ManagerSQL Server Network Configuration deshabilita TCP/IP o limita IPs a 127.0.0.1.
    • MySQL: en my.ini establece bind-address=127.0.0.1 y reinicia el servicio.

Bloqueo explícito en Windows Defender Firewall

Usa PowerShell para crear reglas de bloqueo claras, que apliquen en todos los perfiles (Domain/Private/Public) y cubran TCP/UDP e IPv4/IPv6.

New-NetFirewallRule -DisplayName "Bloqueo TCP 110,143,1433,3306" `
  -Direction Inbound -Action Block -Protocol TCP -LocalPort 110,143,1433,3306 -Profile Any

New-NetFirewallRule -DisplayName "Bloqueo UDP 1434 (SQL Browser)" \`
-Direction Inbound -Action Block -Protocol UDP -LocalPort 1434 -Profile Any

Equivalente con netsh si lo prefieres:

netsh advfirewall firewall add rule name="Bloquear TCP 110,143,1433,3306" dir=in action=block protocol=TCP localport=110,143,1433,3306 profile=any
netsh advfirewall firewall add rule name="Bloquear UDP 1434" dir=in action=block protocol=UDP localport=1434 profile=any

Perfil correcto y firewall activo

  • Fija el perfil del adaptador a Domain/Private según el entorno.
  • Asegúrate de que el firewall está activado en todos los perfiles:
Set-NetFirewallProfile -Profile Domain,Private,Public -Enabled True

Reaplicar / “resembrar” reglas en Plesk

  • Reinstala o actualiza la extensión Firewall si se perdió su estado tras la caída.
  • Aplica una plantilla de “bloquear por defecto” y abre solo lo necesario.
  • Evita reglas atadas a una IP concreta salvo que sea estática y controlada; usa alcances de subred o “Any” donde tenga sentido, junto a Match profile adecuado.

Verificación externa fiable

Después de aplicar cambios, valida desde fuera de tu red (idealmente desde Internet o un escáner en otra VPC/VNET).

nmap -Pn -sS -p 110,143,1433,3306 TUIPPUBLICA
Salida esperada: closed o filtered (no open)

Pruebas puntuales

Test-NetConnection TU\IP\PUBLICA -Port 1433
Test-NetConnection TU\IP\PUBLICA -Port 3306
Test-NetConnection TU\IP\PUBLICA -Port 110
Test-NetConnection TU\IP\PUBLICA -Port 143

Consejo: si ves filtered, el firewall está filtrando; si ves closed, no hay proceso escuchando. Ambos estados son aceptables para “no expuesto”.

Errores frecuentes que confunden

  • Escaneo local: el loopback no recorre el mismo camino del firewall. Siempre valida desde un punto externo.
  • Olvidar UDP 1434: cierras 1433/TCP pero el servicio Browser de SQL se delata por 1434/UDP.
  • Ignorar IPv6: si la pila v6 está activa y solo bloqueas IPv4, seguirás expuesto por v6.
  • Reglas ligadas a una IP antigua: tras APIPA/DHCP cambian direcciones/perfiles y las reglas dejan de aplicar.
  • Confiar solo en Plesk: recuerda que Plesk es un frontend; valida en PowerShell y, si hace falta, recrea reglas nativas.

Checklist rápido de cierre real

  1. Validar desde Internet: nmap -Pn -sS -p 110,143,1433,3306 TU_IP.
  2. Detener y deshabilitar POP/IMAP si no se usan.
  3. Restringir SQL Server/MySQL a 127.0.0.1 si son locales.
  4. Crear reglas Block para TCP 110/143/1433/3306 y UDP 1434 en Profile Any.
  5. Verificar perfil activo con Get-NetConnectionProfile; activar firewall en todos los perfiles.
  6. Reaplicar Firewall en Plesk con política “deny by default”.
  7. Repetir escaneo externo y guardar evidencia.

Scripts reutilizables

Descubrir reglas “Allow” activas para puertos sensibles

function Find-AllowRulesForPorts {
  param([int[]]$Ports = @(110,143,1433,3306))
  $regex = '^((' + ($Ports -join '|') + '))$'
  Get-NetFirewallRule -Enabled True -Action Allow |
    Get-NetFirewallPortFilter |
    Where-Object { $_.LocalPort -match $regex } |
    Format-Table -Auto
}
Find-AllowRulesForPorts

Crear bloqueos consistentes (TCP y UDP)

function Add-StandardBlocks {
  New-NetFirewallRule -DisplayName "Bloqueo TCP 110,143,1433,3306" `
    -Direction Inbound -Action Block -Protocol TCP -LocalPort 110,143,1433,3306 -Profile Any

New-NetFirewallRule -DisplayName "Bloqueo UDP 1434 (SQL Browser)" \`
-Direction Inbound -Action Block -Protocol UDP -LocalPort 1434 -Profile Any
}
Add-StandardBlocks

Comprobar qué proceso escucha en un puerto específico

function Get-ListenerProcess {
  param([int]$Port)
  $pid = (Get-NetTCPConnection -State Listen -LocalPort $Port -ErrorAction SilentlyContinue).OwningProcess
  if ($pid) { Get-Process -Id $pid | Select-Object Id, ProcessName, Path } else { "Nada en LISTEN en $Port" }
}
Get-ListenerProcess -Port 1433

Consideraciones específicas de Plesk en Windows

  • Reaplicar la plantilla: en Plesk → Herramientas y configuraciónFirewall, selecciona una configuración estricta (bloquear por defecto) y aplica cambios.
  • Persistencia: si tras reiniciar el servidor reaparecen reglas “Allow”, reinstala la extensión y purga la configuración previa antes de reimportar.
  • MailEnable: si no harás POP/IMAP, desinstala o deshabilita los servicios correspondientes desde services.msc y desde el panel de Plesk (Sección Correo).
  • Logs para auditoría: captura la salida de Get-NetFirewallRule y los resultados de Nmap posteriores al cambio para documentar el estado final.

Resultado observado y lecciones

Restaurar el backup del día anterior resolvió la exposición práctica en el caso descrito, pero es una mitigación temporal. Para evitar recurrencias, aplica el paquete completo: apaga servicios no usados, limita escuchas a localhost, bloquea con reglas explícitas en todos los perfiles (incluido UDP 1434 e IPv6), y mantén Plesk sincronizado. La verificación externa es el “oráculo” final: si fuera no ven open, has cerrado de verdad.

Resumen ejecutivo:

  1. Valida desde fuera.
  2. Apaga POP/IMAP/SQL si no se usan o limítalos a localhost.
  3. Bloquea 110/143/1433/3306 (TCP) y 1434 (UDP) en todos los perfiles, con cobertura IPv6.
  4. Reaplica el firewall en Plesk; evita reglas atadas a IPs volátiles.
  5. Repite el escaneo para confirmar y registra evidencias.

Preguntas frecuentes

¿Por qué Nmap desde el propio servidor dice “open” si desde fuera está cerrado?
Porque el escaneo local ve el estado de escucha del proceso, no la política efectiva para clientes externos. Windows Filtering Platform no trata igual loopback que tráfico entrante por NIC.

¿Debo deshabilitar IPv6 para simplificar?
No es necesario ni recomendable. Es mejor asegurar que las reglas de bloqueo apliquen a ambas pilas (por defecto lo hacen si no restringes AddressFamily).

¿Cómo cierro SQL Server sin romper conexiones locales?
Limítalo a 127.0.0.1 en el Administrador de Configuración o desactiva TCP/IP si usas solo Shared Memory. Complementa con la regla de firewall.

¿Qué estado de Nmap debo esperar?
closed indica que no hay proceso escuchando; filtered indica que el firewall bloquea. Ambos te sirven según tu estrategia.

Plantilla de acciones recomendadas

  1. Detén POP/IMAP/SQL/MySQL si no se usan.
  2. Limita SQL/MySQL a 127.0.0.1 si son locales.
  3. Crea reglas de bloqueo para 110, 143, 1433, 3306 (TCP) y 1434 (UDP).
  4. Activa el firewall en Domain/Private/Public.
  5. Reaplica configuración en Plesk con política estricta.
  6. Escanea desde fuera y documenta resultados.

Con todo lo anterior, transformarás un “parece abierto” en un cerrado de verdad y evitarás sorpresas cuando el servidor cambie de IP, perfil o cuando Plesk rehaga reglas tras una incidencia.

Índice