¿Sitio web caído, pero el servidor es accesible? Rastrear la falla desde DNS hasta la aplicación
“SSH Funciona, el Sitio No” — Comienza con la Pregunta Correcta
Las alertas comienzan a dispararse, los usuarios dicen que el sitio está muerto, y tu primera prueba te da un extraño tipo de alivio: SSH aún te deja entrar. Ese momento se siente reconfortante porque el servidor no ha desaparecido. Pero también es donde comienza mucha mala resolución de problemas, porque “aún puedo iniciar sesión” no es lo mismo que “el sitio web debería estar funcionando”.

La pregunta útil no es “¿qué puedo reiniciar primero?” Es “¿qué capa falló primero?” Una sesión SSH funcionando prueba que la máquina es alcanzable en el puerto 22. No prueba que el dominio se resuelva correctamente. No prueba:
- que los puertos 80 y 443 sean alcanzables
- que HTTPS esté saludable
- que la aplicación detrás del servidor web esté respondiendo
Esta guía está construida alrededor de esa distinción, y se mantiene enfocada en el diagnóstico en lugar de intentar convertirse en un manual completo de nginx, DNS, TLS, Docker o base de datos.
⚠️ Advertencia: Reiniciar ciegamente nginx, Docker, PHP-FPM o todo el VPS en los primeros minutos de un incidente puede borrar las pistas que necesitas. Recopila una ronda de evidencia primero, luego cambia solo la capa que realmente falló.
El Mapa de Triage de Un Minuto

Antes de profundizar, oriéntate. La forma del fallo a menudo te dice qué capa merece atención primero, incluso cuando aún no conoces la causa raíz.
Trata la siguiente tabla como un atajo de triage, no como un veredicto final.
| Lo que ves | Lo que generalmente significa | Lo que revisar primero | Lo que no asumir |
|---|---|---|---|
| 🧭 Could not resolve host | El nombre no se resolvió a una dirección | Registros DNS, ruta del resolver, errores tipográficos | El servidor web es necesariamente el problema |
| ⏱️ Timeout | El tráfico está bloqueado, mal enrutado o colgado más adelante en la ruta | curl externo, ruta del firewall, enrutamiento, accesibilidad del listener | Todos los timeouts significan lo mismo |
| 🚫 Connection refused | El host es accesible, pero nada útil acepta conexiones allí | ss -ltnp, estado del servicio, dirección de enlace | Todo el servidor está caído |
| 🔐 Advertencia de TLS o certificado | HTTPS llegó al puerto 443, pero la capa de identidad o handshake falló | Certificado servido, coincidencia de hostname, cadena, estado de renovación | La aplicación en sí definitivamente está muerta |
| ⚠️ 502 / 503 / 504 | Un frontend o servicio accesible está fallando más arriba en la cadena | Entrega upstream, disponibilidad del servicio, ubicación del timeout | Cada error 5xx significa la misma solución |
| 🏠 Funciona localmente pero no externamente | La pila puede estar bien en el servidor, pero la ruta externa está rota | Firewall del host, firewall del proveedor, ruta de CDN, enrutamiento | El éxito local prueba la accesibilidad pública |
Lo que importa es la primera etapa rota. Si DNS falla, las capas posteriores son ruido. Si el puerto 443 responde pero TLS falla, la aplicación no es tu primera pregunta aún. El modelo mental a continuación es lo que hace que esa secuencia sea lógica en lugar de aleatoria.
Por qué SSH no prueba que el sitio web funciona
SSH y el tráfico web son caminos diferentes con trabajos diferentes. SSH en el puerto 22 prueba que puedes llegar a la máquina a través de su puerta de gestión remota. Un sitio web depende de los puertos 80 y 443, más las capas detrás de ellos. Estas son pruebas separadas, por lo que “servidor alcanzable” y “sitio web alcanzable” no son declaraciones intercambiables.

La forma más fácil de visualizarlo es como un edificio de oficinas. DNS ayuda a un visitante a encontrar la dirección del edificio. Los puertos 80 y 443 son la recepción para visitantes públicos. El servidor web es el recepcionista que acepta la solicitud y decide a dónde va a continuación. La aplicación es la oficina que realiza el trabajo real. Una base de datos u otra dependencia puede estar más adentro del edificio. SSH es una entrada completamente diferente. Es útil para el personal, pero no prueba que la recepción esté abierta o que la entrega de la oficina funcione.
Browser
↓
DNS lookup
↓
IP address
↓
Port 80 / 443
↓
Web server
↓
App / upstream
↓
Database / dependencyCuando las personas dicen que un servicio está “escuchando”, quieren decir que realmente está aceptando conexiones en el punto final esperado. Esa es la distinción que convierte un vago momento “el servidor está activo” en una ruta de solicitud rastreable.
Eso importa porque HTTPS puede fallar antes de que la aplicación responda, y los fallos de proxy o aplicación pueden ocurrir después de que el frontend ya sea alcanzable. Por lo tanto, el siguiente paso es siempre el mismo: buscar desde afuera primero y encontrar la última etapa exitosa de la solicitud.
Paso 1: Reproducir el Fallo desde Fuera del Servidor
Comienza desde el lado del cliente, no desde dentro del VPS. Si es posible, prueba desde otra red o dispositivo primero para que no confundas una caché DNS local, una entrada antigua en /etc/hosts, o un problema de firewall/VPN local con una verdadera interrupción del servidor.
Utiliza una solicitud externa detallada para que puedas ver hasta dónde llega la solicitud antes de fallar:
curl -v --connect-timeout 5 --max-time 15 https://example.com/curl -v no es una herramienta solo para expertos aquí. Léela como un seguimiento del progreso. Si nunca resuelve el nombre, estás en la rama DNS. Si se conecta y luego dice Connection refused, el host respondió pero nada útil está aceptando tráfico allí. Si se cuelga hasta el tiempo de espera, piensa en filtrado, enrutamiento, o un cuelgue más profundo más adelante en la ruta de la solicitud. Si recibes una respuesta HTTP, incluso una página de error, ya has pasado la capa de conexión y estás en una rama superior.
💡 Consejo: Compara IPv4 e IPv6 temprano. Un registro AAAA olvidado puede hacer que la interrupción parezca inconsistente porque algunos clientes prefieren IPv6 primero y otros no.
Ejecuta la misma prueba una vez por familia de protocolos cuando hay dual stack en juego:
curl -4 -v --connect-timeout 5 --max-time 15 https://example.com/
curl -6 -v --connect-timeout 5 --max-time 15 https://example.com/Si IPv4 funciona e IPv6 falla, o viceversa, ya has estrechado el incidente más rápido de lo que un reinicio de servicio jamás lo haría. Si el fallo comienza en la resolución de nombres o en la elección del destino, DNS es la siguiente rama limpia a verificar.
Paso 2: Verificar DNS y Confirmar el Destino Correcto
Antes de depurar nginx, confirma que el dominio realmente está enviando visitantes al servidor que crees que es. Esto es especialmente importante después de migraciones, cambios de IP, ajustes de CDN o ediciones parciales de registros.
Primero verifica los registros públicos:
dig +short A example.com
dig +short AAAA example.comEstas dos líneas responden una pregunta muy práctica: ¿dónde cree Internet que vive example.com en este momento? Una forma común de fallo es que SSH por IP alcanza el nuevo VPS, pero el dominio aún apunta a la dirección antigua. Otra es que el registro A fue actualizado, pero el registro AAAA aún apunta a algo antiguo. En ese caso, solo parte de tu tráfico falla.
📝 Nota: curl --resolve es más seguro que cambiar DNS público en medio de un incidente. Te permite probar el origen que pretendes usar mientras mantienes el hostname y SNI intactos.
Usa curl --resolve para forzar una prueba contra la IP que esperas sin tocar los registros públicos:
curl --resolve example.com:443:203.0.113.10 https://example.com/Si eso funciona mientras el dominio público aún falla, el servidor puede estar bien y DNS puede seguir siendo la capa rota. Una nota sobre CDN limitado vale la pena tener en mente aquí. Si tu origen está bloqueado para aceptar tráfico solo de rangos de IP de CDN, una prueba de origen directo puede fallar simplemente porque el origen espera tráfico de edge, no solicitudes públicas arbitrarias. Una vez que el destino está confirmado, la siguiente pregunta es si algo útil está respondiendo en 80 o 443 allí.
Paso 3: Verificar Qué Está Escuchando en 80/443
Ahora cambia al servidor y haz una pregunta específica: ¿hay algo realmente aceptando conexiones web en los puertos esperados? La máquina puede estar activa, SSH puede funcionar, e incluso nginx puede estar instalado. Sin embargo, los puertos web públicos aún pueden no tener ningún listener útil.
Primero verifica los listeners:
sudo ss -ltnpUna salida vacía para :80 o :443 significa que nada útil está escuchando allí. Un listener en 127.0.0.1 significa que el servicio está aceptando conexiones solo desde la máquina local. Un listener en 0.0.0.0 significa que está vinculado en interfaces IPv4. [::] generalmente significa interfaces IPv6. No asumas que el vinculamiento IPv6 garantiza automáticamente la ruta IPv4 que necesitas.
Luego usa un pequeño bundle de salud de nginx antes de cambiar nada:
sudo systemctl status nginx --no-pager -l
sudo nginx -t
sudo journalctl -u nginx --since '-30 minutes' --no-pager- Si systemctl dice active (running), eso solo prueba que el proceso del servicio existe
- nginx -t te dice si la configuración es válida
- journalctl muestra si una recarga reciente falló, un archivo de certificado desapareció, o un vhost se rompió al iniciar.
Para lectores de Apache, la sintaxis equivalente de verificación es apachectl configtest. Una vez que sabes que algo está escuchando, la siguiente prueba es más específica: ¿responde el sitio correcto localmente cuando eliminas la red externa de la ecuación?
💡 Consejo: Prueba la configuración primero, luego prefiere reload sobre un reinicio ciego cuando sea apropiado. Un reload valida la nueva configuración y mantiene los workers antiguos si la nueva configuración es mala; un reinicio ciego es mucho más brusco en medio de un incidente.
Paso 4: Prueba el Sitio Localmente con el Host y SNI Correctos
Esta es la bifurcación más importante en toda la investigación. Un simple curl 127.0.0.1 puede ser engañoso. Muchos servidores alojan múltiples sitios y eligen la respuesta basándose en el encabezado Host o, para HTTPS, SNI. No estás preguntando si algo responde localmente. Estás preguntando si la ruta del sitio correcta responde localmente.
Usa pruebas locales que preserven la lógica del nombre de host:
curl -I http://127.0.0.1/ -H 'Host: example.com'
curl -v --resolve example.com:443:127.0.0.1 https://example.com/
# Only as a one-off diagnostic if you already know the cert is bad:
curl -vk --resolve example.com:443:127.0.0.1 https://example.com/Un éxito significativo es la página esperada, la redirección esperada, o la respuesta de aplicación esperada del sitio correcto. No es el host nginx predeterminado, el certificado incorrecto, o un “devolvió HTML” genérico. De aquí hay tres resultados limpios: éxito local, comportamiento de sitio incorrecto o certificado predeterminado local, o fallo/tiempo de espera local. Un buen resultado local apunta hacia afuera a firewall, proveedor, CDN, o comprobaciones de enrutamiento. Un mal resultado local te mantiene dentro de la pila, en las ramas de upstream o TLS.
Paso 5: Si Funciona Localmente pero No Externamente, Rastrear la Ruta de Red
Una vez que la prueba local sea correcta, deja de cuestionar nginx por un momento. La pila del sitio probablemente esté activa en el servidor, y la pieza faltante generalmente está en algún lugar entre el visitante y ese servicio local que funciona. Comienza con el firewall del host porque es el límite externo más cercano que controlas.
Inspecciona las reglas del lado del host con la herramienta que tu sistema realmente usa, y haz una verificación rápida de cordura para bloqueos autoinfligidos mientras estés allí:
sudo nft list ruleset
# Or, on systems still using iptables directly:
sudo iptables-save
sudo ip6tables-save
# Fast sanity check for self-inflicted blocking:
sudo fail2ban-client statusEse resultado solo muestra la capa del SO invitado. No muestra el filtrado del lado del proveedor, grupos de seguridad o reglas de firewall a nivel de panel que viven fuera del VPS mismo. En un VPS de AlexHost, por ejemplo, el firewall de la máquina y cualquier control de red a nivel de panel son preguntas separadas. Ambos importan cuando las pruebas locales funcionan pero los visitantes públicos aún fallan.
⚠️ Advertencia: Si Docker publica puertos en el host, no asumas que la salida de UFW cuenta toda la historia. Docker puede enrutar el tráfico de contenedores publicados a través de NAT antes de las cadenas habituales de UFW. Eso significa que “UFW se ve bien” no siempre significa que la ruta de paquetes sea correcta.
Los CDN y balanceadores de carga merecen su propia rama aquí también. El origen puede estar saludable y aún ser inalcanzable directamente porque solo se permite que los rangos de IP de borde se comuniquen con él. Cuando necesites prueba de si los paquetes llegan en absoluto, usa tcpdump como herramienta de sí-o-no:
📝 Nota: Una prueba de origen directo fallida detrás de una lista de permitidos de CDN generalmente apunta a la política de borde, no a un origen muerto. En esa configuración, el origen está diseñado para confiar en la ruta de CDN, no en cada visitante directo.
sudo tcpdump -ni any 'tcp port 80 or tcp port 443'Si no ves paquetes SYN en absoluto, el tráfico no está llegando al servidor. Si los SYN llegan y no sale ningún SYN-ACK, la ruta del servidor o firewall aún está bloqueando la entrega. Si ninguno de estos patrones parece ser el bloqueador, los fallos restantes generalmente se sientan detrás del frontend en la entrega ascendente.
Paso 6: Si el Frontend Responde pero el Sitio Sigue Roto, Sigue el Upstream
En esta rama, el servidor web es accesible, pero el siguiente salto detrás de él no está lo suficientemente saludable para completar la solicitud. Aquí, “upstream” significa el servicio al que nginx entrega la solicitud a continuación: un proceso de aplicación, un tiempo de ejecución respaldado por socket, un contenedor u otra dependencia interna.
Las páginas estáticas funcionando mientras que el inicio de sesión, búsqueda, pago o rutas API fallan es una pista fuerte de que el frontend está presente y la falla comienza en la entrega detrás de él.
📝 Nota: Trata 502 como “el siguiente salto respondió mal” y 504 como “el siguiente salto respondió demasiado lentamente.” Ambos son signos para seguir la ruta upstream en lugar de detenerse en el frontend.
Inspecciona la entrega activa, luego prueba el upstream directamente:
sudo nginx -T
# Direct HTTP upstream example
curl -i http://127.0.0.1:3000/
# Unix-socket-backed HTTP example
curl --unix-socket /run/app.sock http://localhost/En la salida de nginx, busca directivas como proxy_pass, fastcgi_pass o uwsgi_pass. Estás verificando si nginx apunta al destino correcto, sobre el protocolo correcto, en el puerto o socket correcto. Si hay contenedores involucrados, añade una verificación corta de salud del contenedor en lugar de adivinar:
docker ps
docker logs --tail 50 <container_name>
docker inspect --format '{{json .State.Health}}' <container_name>
docker port <container_name>Si la prueba directa de la aplicación falla, el problema está detrás del servidor web. Si funciona directamente pero falla a través de nginx, la configuración de entrega es la rama a inspeccionar. La accesibilidad de la base de datos importa solo como verificación de dependencia aquí, no como un análisis profundo separado. Si este patrón de falla upstream sigue repitiéndose, ese es el momento adecuado para cambiar a una guía de solución de problemas dedicada en lugar de estirar un incidente en conjeturas.
Paso 7: Aislar Fallos de TLS y Certificados
Esta rama es más estrecha: algo está respondiendo en el puerto 443, pero el navegador aún no puede completar una sesión HTTPS limpia y confiable. Una conexión TCP exitosa al puerto 443 no prueba que el certificado, la coincidencia del nombre de host o la ruta del protocolo de enlace sean saludables.
Inspecciona qué certificado se está sirviendo realmente:
openssl s_client -connect example.com:443 -servername example.com -verify_hostname example.com -briefAquí es donde atrapas las formas de fallo comunes: el nombre de host incorrecto, un certificado expirado, una cadena incompleta o una renovación que nunca se completó limpiamente. En lenguaje simple, SNI le dice al servidor qué nombre de host quisiste decir. -verify_hostname verifica si el certificado que sirvió coincide con ese nombre de host. Después de la recuperación, valida la ruta de renovación para que esto no se convierta en el próximo apagón:
⚠️ Advertencia: Si confías en la validación HTTP-01 para la renovación de certificados, el puerto de entrada 80 debe ser accesible. Una regla de firewall o proveedor que bloquee 80 puede romper silenciosamente las renovaciones mucho antes de que los usuarios reporten que HTTPS se ve muerto.
sudo certbot renew --dry-runPaso 8: Verifica la Presión de Recursos Antes de Llamarlo Aleatorio
Algunos incidentes no son fallos de accesibilidad en absoluto. La ruta es técnicamente intacta, pero el servidor está demasiado hambriento, bloqueado u sobrecargado para responder a tiempo. Es cuando un sitio puede verse “parcialmente vivo” desde un ángulo y aún así sentirse muerto para los usuarios.
Ejecuta un pequeño paquete de primer paso de recursos:
df -h
df -i
free -h
uptime
vmstat 1 5
sudo journalctl -k -g 'oom|out of memory|killed process'Lee los resultados en patrones, no en aislamiento.
- df -h muestra agotamiento ordinario de disco.
- df -i detecta agotamiento de inodos, donde el espacio parece existir pero el sistema de archivos no puede crear más entradas.
- free -h importa más cuando la memoria disponible colapsa y la actividad de intercambio aumenta.
- uptime puede mostrar carga alta incluso cuando la CPU no está al máximo, lo que a menudo significa que las tareas están esperando presión de disco o memoria en lugar de cómputo activo.
- Las líneas del registro del kernel sobre eventos OOM te dicen si el sistema comenzó a matar procesos para sobrevivir.
Los gráficos del proveedor pueden confirmar la línea de tiempo. En un VPS de AlexHost, pueden ser útiles para verificar si los picos en RAM, disco o I/O se alinean con la interrupción. Pero la evidencia de terminal aún debe liderar el diagnóstico. Esta sección no es una guía de ajuste; es la rama que te dice que el sitio puede estar fallando bajo presión en lugar de fallar al enrutar.
Piensa en Capas, No en Pánico

Cuando SSH funciona pero el sitio web no se abre, mantén la cadena corta y repetible:
- reproduce el fallo externamente
- identifica la última etapa exitosa
- confirma DNS y destino
- verifica un listener real en 80/443
- prueba el sitio correcto localmente
- ramifica en ruta de red, upstream, TLS o recursos
💡 Consejo: No cierres tu última sesión SSH funcionando hasta que hayas confirmado que un inicio de sesión nuevo aún funciona y que aún tienes una ruta de acceso de respaldo, como acceso a la consola del proveedor. Durante un incidente en vivo, preservar el control importa tanto como solucionar el primer síntoma.
Mantén los hábitos ligeros: monitorea externamente, guarda registros y prueba certificados con certbot renew –dry-run. Asegura el acceso con copias de seguridad y una ruta de consola. Las herramientas del proveedor — firewall, gráficos, consola (incluyendo AlexHost) — deben apoyar la solución de problemas, no reemplazarla. Enfócate en solucionar la primera capa rota para que cada incidente se maneje con evidencia más clara y menos pánico.
en todos los servicios de hosting