Skip to content

“Connection Refused” a HTTPS estable

¿Alguna vez te ha tocado enfrentarte a un misterioso «Connection Refused» al intentar acceder a una app por HTTPS y te has quedado con cara de no entender nada? A mí me pasó con subdominio.midominio.com. Lo que empezó como un simple error de conexión, se convirtió en una aventura para optimizar y dejar el proyecto en un estado mucho mejor. Aquí te cuento cómo lo solucioné, desde el diagnóstico inicial hasta la automatización de procesos y la internacionalización.

—

Diagnóstico: Descifrando el misterio del «Connection Refused»

Para resolver el problema, me puse mi sombrero de detective y seguí una serie de pasos para encontrar la raíz del fallo.

  1. ¿Quién sirve las DNS? Lo primero fue preguntar: ¿hacia dónde apunta esta URL? Utilicé dig subdominio.midominio.com y nslookup, y descubrí que la dirección apuntaba a la IP del servidor de backend. El problema estaba claro: este servidor no tenía un listener SSL.
  2. Siguiendo el rastro de la petición: El camino ideal de la petición debía ser Cliente → DNS interno → nginx-proxy (donde está el SSL), pero en realidad, la petición estaba yendo directamente a backend-server por el puerto 80. Aquí, el error DNS era evidente.
  3. Revisando el servidor SSL: Como buen dev, la siguiente parada fue comprobar la configuración del proxy. En nginx-proxy revisé la sección listen 443 ssl; y la validez de los certificados. Para mi sorpresa, todo parecía estar en orden.
  4. Firewall y servicios: El siguiente paso lógico era el firewall. Verifiqué que el puerto 443 no estuviese bloqueado. También confirmé que mi backend-server solo escuchaba tráfico HTTP (puertos 80 y 8080).
  5. ¡Bingo! El error era la DNS: Una vez que tenía todas las piezas, corregí el registro interno para que subdominio.midominio.com apuntase a la IP de nginx-proxy.
  6. Verificación final: Con la DNS corregida, hice una última prueba con curl -I https://subdominio.midominio.com. El resultado fue HTTP/2 200 y 302. ¡El error había desaparecido!

El desvío de DNS estaba causando todo el problema. Pero en vez de dejarlo ahí, decidí que era una excelente oportunidad para mejorar el proyecto.

—

Transformando el proyecto: Del caos a la estructura

Con el error inicial resuelto, aproveché para darle al proyecto la estructura que merecía. Aquí te cuento los cambios que implementé:

1. Control de versiones con GitLab

  • Creé un repositorio privado en GitLab para el proyecto.
  • Le di acceso a mis compañeros, lo que facilita el trabajo en equipo y el control de versiones.

2. Saneando Composer y las dependencias

  • Limpié los conflictos en composer.json para Symfony 2.8.
  • Me aseguré de que las versiones de las dependencias fueran compatibles en todos los entornos (DEV, TEST y PROD).

3. Ajustes en Doctrine ORM

  • Encontré y corregí un error de continue que causaba problemas en PHP moderno.
  • Ahora la caché se limpia sin fallos.

4. Gestión de caché y permisos

  • Eliminé los directorios de caché antiguos en app/cache.
  • Revisé y ajusté los permisos (apache:apache).

5. Creación de un script de limpieza automática

Para evitar problemas futuros, creé un script para limpiar la caché de forma automática. Es un pequeño detalle que ahorra mucho tiempo y dolores de cabeza.

#!/bin/bash
# scripts/clear_cache.sh
rm -rf app/cache/{dev,prod}
mkdir -p app/cache/{dev,prod}
chown -R apache:apache app/cache
php bin/console cache:clear --env=prod
php bin/console cache:clear --env=dev
systemctl reload httpd

6. Internacionalización (i18n): La app habla idiomas

Para que la aplicación pueda crecer sin límites, la hice multilingüe:

  • Generé archivos messages.es.yml y messages.fr.yml.
  • Reemplacé los textos fijos por la sintaxis de traducción {{ 'clave'|trans }}.
  • Traduje las partes principales de la aplicación: login, panel de admin, gestión de usuarios, etc.

—

El resultado final: Un proyecto a prueba de balas

Lo que empezó con un error, terminó con un proyecto mucho más robusto:

  • El **HTTPS** funciona perfectamente.
  • El proyecto está **versionado y listo** para colaborar.
  • La **caché** está estable y los procesos automatizados.
  • La app es **multilenguaje** y está preparada para crecer.

¿Te ha pasado algo parecido? A veces, los errores más tontos son los que nos enseñan las lecciones más valiosas. ¡Cuéntame tu historia en los comentarios!

Volver arriba