--- title: "Cómo obtener una A+ en SSL Labs con Nginx y Apache" description: "Consigue la A+ de SSL Labs en Ubuntu 24.04 con un certificado ECDSA, TLS 1.2 y 1.3 con cifrados modernos, redirección a HTTPS y cabecera HSTS en Nginx o Apache." category: "SSL/TLS y Certificados" language: es source: https://cubepath.com/es/docs/ssl-tls-y-certificados/guia-de-configuracion-de-clasificacion-ssl-labs-a updated: 2026-09-25 --- # Cómo obtener una A+ en SSL Labs con Nginx y Apache SSL Labs (de Qualys) es el test público más usado para evaluar la configuración TLS de un servidor web. Asigna una nota de A+ a F según los protocolos, cifrados, certificado y cabeceras que ofrece tu sitio. En esta guía configurarás Nginx o Apache en Ubuntu 24.04 con un certificado de Let's Encrypt, TLS 1.2 y 1.3 con cifrados modernos y la cabecera HSTS, que es lo que separa una A de una A+, y comprobarás el resultado en SSL Labs. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con un usuario no root con privilegios `sudo`. - Nginx o Apache instalado y sirviendo tu sitio por HTTP. - Un dominio (`your_domain` en los ejemplos) con registros A (y AAAA si usas IPv6) apuntando al servidor. Si tienes `www`, también debe apuntar al servidor. - Puertos 80 y 443 abiertos. Con UFW: ```bash sudo ufw allow 'Nginx Full' ``` Si usas Apache, el perfil es `'Apache Full'`. ## Qué necesita una A+ SSL Labs parte de una puntuación numérica y después aplica límites que bajan la nota ante problemas concretos. Para llegar a A+ necesitas: | Requisito | Qué pasa si falta | |---|---| | Certificado válido, cadena completa y nombre correcto | Nota T o F | | Sin SSL 3, TLS 1.0 ni TLS 1.1 | Limitado a B (C o F si hay SSL 3) | | Secreto hacia adelante (ECDHE) en todas las suites | Limitado a B | | Sin cifrados inseguros (RC4, 3DES, NULL, EXPORT) | Limitado a B, C o F | | Soporte de TLS 1.3 | Recomendado; los servidores modernos lo tienen por defecto | | Cabecera HSTS con `max-age` de al menos 6 meses | Se queda en A | El OCSP stapling, las cabeceras como CSP o X-Frame-Options y el preload de HSTS no forman parte de la nota. Son buenas prácticas, pero no hace falta nada de eso para la A+. ## Paso 1: Obtener un certificado ECDSA con Certbot Instala Certbot con el plugin de tu servidor web: ```bash sudo apt update sudo apt install certbot python3-certbot-nginx ``` Para Apache, instala `python3-certbot-apache` en lugar de `python3-certbot-nginx`. Desde la versión 2.0, Certbot genera por defecto claves ECDSA P-256, más pequeñas y rápidas que RSA 2048 con una seguridad equivalente o mayor. Ubuntu 24.04 trae Certbot 2.9, así que no necesitas opciones extra. Solicita el certificado solo (`certonly`) para que Certbot no modifique la configuración TLS del sitio; la escribirás tú en el paso 2: ```bash sudo certbot certonly --nginx -d your_domain -d www.your_domain ``` Con Apache, usa `--apache` en lugar de `--nginx`. Comprueba el tipo de clave: ```bash sudo openssl x509 -in /etc/letsencrypt/live/your_domain/cert.pem -noout -text | grep 'Public Key Algorithm' ``` ```output Public Key Algorithm: id-ecPublicKey ``` El paquete de Certbot instala un temporizador de systemd que renueva los certificados automáticamente. Verifica que está activo: ```bash systemctl list-timers certbot.timer ``` ## Paso 2: Configurar TLS y HSTS en Nginx En Ubuntu, `/etc/nginx/nginx.conf` ya activa TLS 1.0 y 1.1 en su sección `SSL Settings`, y eso limitaría la nota a B. Edítalo: ```bash sudo nano /etc/nginx/nginx.conf ``` Deja la sección `SSL Settings` del bloque `http` así: ```nginx ## # SSL Settings ## ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305; ssl_ecdh_curve X25519:prime256v1:secp384r1; ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; ssl_session_tickets off; ``` Estos cifrados solo usan ECDHE (secreto hacia adelante) con AES-GCM o ChaCha20, y ninguno aparece como débil en SSL Labs. `ssl_ciphers` no afecta a TLS 1.3, que usa las suites seguras de OpenSSL por defecto. Ahora crea o sustituye la configuración del sitio: ```bash sudo nano /etc/nginx/sites-available/your_domain ``` ```nginx server { listen 80; listen [::]:80; server_name your_domain www.your_domain; return 301 https://your_domain$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name your_domain www.your_domain; ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; root /var/www/your_domain; index index.html; location / { try_files $uri $uri/ =404; } } ``` Puntos importantes: - `fullchain.pem` incluye el certificado intermedio. Si usas `cert.pem`, la cadena queda incompleta y SSL Labs lo penaliza. - `max-age=31536000` es un año, por encima de los 6 meses que exige la A+. `always` hace que la cabecera se envíe también en respuestas de error. - `includeSubDomains` obliga a usar HTTPS en todos los subdominios. Quítalo si alguno sigue sirviendo solo HTTP. - En Nginx, un `add_header` dentro de un bloque `location` anula todos los `add_header` del bloque `server`. Si añades cabeceras en un `location`, repite ahí la de HSTS. Activa el sitio si es nuevo, comprueba la sintaxis y recarga: ```bash sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx ``` ## Paso 3 (alternativa): Configurar TLS y HSTS en Apache Si usas Apache, activa los módulos necesarios: ```bash sudo a2enmod ssl headers ``` Crea un archivo global con la política TLS. Se carga después de `mods-available/ssl.conf` y sustituye sus valores: ```bash sudo nano /etc/apache2/conf-available/tls-modern.conf ``` ```apache SSLProtocol -all +TLSv1.2 +TLSv1.3 SSLHonorCipherOrder off SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305 SSLOpenSSLConfCmd Curves X25519:prime256v1:secp384r1 SSLSessionTickets off ``` ```bash sudo a2enconf tls-modern ``` Crea el sitio con la redirección y el `VirtualHost` HTTPS: ```bash sudo nano /etc/apache2/sites-available/your_domain.conf ``` ```apache ServerName your_domain ServerAlias www.your_domain Redirect permanent / https://your_domain/ ServerName your_domain ServerAlias www.your_domain DocumentRoot /var/www/your_domain SSLEngine on SSLCertificateFile /etc/letsencrypt/live/your_domain/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/your_domain/privkey.pem Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" ErrorLog ${APACHE_LOG_DIR}/your_domain_error.log CustomLog ${APACHE_LOG_DIR}/your_domain_access.log combined ``` Actívalo, comprueba y recarga: ```bash sudo a2ensite your_domain sudo apache2ctl configtest sudo systemctl reload apache2 ``` ```output Syntax OK ``` ## Paso 4: Comprobar la configuración antes del test SSL Labs tarda un par de minutos, así que conviene verificar lo básico antes desde el servidor. La redirección de HTTP a HTTPS: ```bash curl -sI http://your_domain | grep -iE '^(HTTP|location)' ``` ```output HTTP/1.1 301 Moved Permanently Location: https://your_domain/ ``` La cabecera HSTS en HTTPS: ```bash curl -sI https://your_domain | grep -i strict-transport-security ``` ```output strict-transport-security: max-age=31536000; includeSubDomains ``` El protocolo y la cadena de certificados: ```bash openssl s_client -connect your_domain:443 -servername your_domain < /dev/null 2>/dev/null | grep -E 'Verify return code|^New' ``` ```output New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 Verify return code: 0 (ok) ``` Un código distinto de `0 (ok)` indica un problema de cadena o de nombre que SSL Labs también detectará. ## Paso 5: Ejecutar el test de SSL Labs Abre `https://www.ssllabs.com/ssltest/`, escribe tu dominio y marca **Do not show the results on the boards** si no quieres que aparezca en el listado público. El análisis tarda entre uno y tres minutos y prueba cada dirección IP del dominio por separado (IPv4 e IPv6), así que ambas deben tener la misma configuración. El resumen debe mostrar **Overall Rating: A+**. En la sección de detalles verás: - **Protocols**: TLS 1.3 y TLS 1.2 en `Yes`; TLS 1.1, TLS 1.0, SSL 3 y SSL 2 en `No`. - **Cipher Suites**: ninguna marcada como `WEAK`. - **HTTP Strict Transport Security (HSTS)**: `Yes` con el `max-age` que configuraste. Si repites el test tras un cambio, pulsa **Clear cache** en la página de resultados; si no, SSL Labs muestra el análisis anterior. ## Sobre el preload de HSTS El preload de HSTS (añadir `preload` a la cabecera y registrar el dominio en `hstspreload.org`) hace que los navegadores usen HTTPS desde la primera visita. No sube la nota y es difícil de deshacer: salir de la lista tarda meses y, mientras tanto, cualquier subdominio sin HTTPS deja de ser accesible. Actívalo solo cuando estés seguro de que todo el dominio, incluidos los subdominios, funciona por HTTPS y exige `max-age` de al menos un año. ## Solución de problemas **Nota B con el aviso "This server supports TLS 1.0 and TLS 1.1".** Otra configuración vuelve a activar esos protocolos. En Nginx suele ser `include /etc/letsencrypt/options-ssl-nginx.conf;` en el bloque `server` o un sitio `default` que escucha en el mismo puerto. Búscalos: ```bash sudo grep -rnE 'ssl_protocols|SSLProtocol|options-ssl' /etc/nginx /etc/apache2 ``` **Se queda en A y SSL Labs no detecta HSTS.** Comprueba con `curl -sI https://your_domain` que la cabecera sale en la respuesta de la raíz. En Nginx, revisa si algún `location` tiene su propio `add_header`. En Apache, confirma que el módulo `headers` está activo con `apache2ctl -M | grep headers`. **"Chain issues: Incomplete".** El servidor no envía el intermedio. Usa `fullchain.pem` en `ssl_certificate` o en `SSLCertificateFile`. **Nota distinta en IPv4 e IPv6.** El registro AAAA apunta a otra máquina o Nginx no tiene `listen [::]:443`. Corrige el DNS o la directiva `listen`. ## Conclusión Has configurado un certificado ECDSA de Let's Encrypt con renovación automática, limitado el servidor a TLS 1.2 y 1.3 con cifrados que ofrecen secreto hacia adelante, forzado HTTPS y añadido la cabecera HSTS, que es el último requisito para la A+. Como siguientes pasos, puedes añadir cabeceras de seguridad (Content-Security-Policy, X-Content-Type-Options) y revisarlas en securityheaders.com, y repetir el test de SSL Labs tras cada cambio de configuración o de certificado.