Todas las guías de despliegue Despliegue

Cómo instalar un certificado SSL en Nginx

Esta guía te lleva paso a paso por la instalación de un certificado SSL en Nginx: desde la subida de archivos hasta la optimización de la configuración TLS y la solución de errores comunes. Funciona con certificados de GetHTTPS, Certbot o cualquier otra fuente.

Si aún no tienes un certificado, obtén uno gratis en 5 minutos.

Requisitos previos

  • Nginx instalado y sirviendo tu sitio en HTTP (puerto 80)
  • Acceso root/sudo al servidor
  • Archivos de certificado — necesitas dos:
    • fullchain.pem — tu certificado + cadena intermedia (combinados)
    • privkey.pem — tu clave privada

¿Qué archivo es cuál? GetHTTPS te da cuatro archivos. Nginx necesita fullchain.pem (no cert.pem) y privkey.pem. Usar solo cert.pem causa errores de «cadena incompleta» porque los navegadores no pueden verificar la ruta de confianza. Formatos de certificados explicados →

Paso 1: Subir los archivos de certificado al servidor

Copia los archivos a un directorio seguro:

# Create directory
sudo mkdir -p /etc/ssl/gethttps

# Copy files (from your local machine to the server)
sudo cp fullchain.pem /etc/ssl/gethttps/
sudo cp privkey.pem /etc/ssl/gethttps/

# Restrict private key permissions — only root should read it
sudo chmod 600 /etc/ssl/gethttps/privkey.pem
sudo chmod 644 /etc/ssl/gethttps/fullchain.pem
sudo chown root:root /etc/ssl/gethttps/*

Si transfieres vía SCP:

scp fullchain.pem privkey.pem user@your-server:/tmp/
# Then on the server:
sudo mv /tmp/fullchain.pem /tmp/privkey.pem /etc/ssl/gethttps/

Paso 2: Configurar el bloque server HTTPS

Edita la configuración de Nginx de tu sitio. El archivo normalmente se encuentra en:

  • /etc/nginx/sites-available/yourdomain.conf (Debian/Ubuntu)
  • /etc/nginx/conf.d/yourdomain.conf (CentOS/RHEL)

Configuración completa recomendada:

# HTTPS server block
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;

    # ─── Certificate files ───────────────────────
    ssl_certificate     /etc/ssl/gethttps/fullchain.pem;
    ssl_certificate_key /etc/ssl/gethttps/privkey.pem;

    # ─── TLS protocol and ciphers ────────────────
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;

    # ─── Session caching (performance) ───────────
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # ─── OCSP stapling (faster verification) ─────
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    # ─── Security headers ────────────────────────
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;

    # ─── Your site ───────────────────────────────
    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

# HTTP redirect block
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

Qué hace cada sección:

DirectivaPropósito
listen 443 ssl http2HTTPS en el puerto 443 con HTTP/2 habilitado
ssl_certificateRuta a tu certificado + cadena
ssl_certificate_keyRuta a tu clave privada
ssl_protocolsSolo TLS 1.2 y 1.3 (1.0/1.1 obsoletos desde 2020)
ssl_prefer_server_ciphers offPermite al cliente elegir el mejor cifrado (práctica recomendada moderna)
ssl_session_cacheAlmacena sesiones TLS en caché — evita re-negociación para visitantes recurrentes
ssl_session_tickets offLos tickets pueden debilitar el secreto perfecto hacia adelante
ssl_staplingEl servidor obtiene la respuesta OCSP — más rápido para los clientes
Strict-Transport-SecurityHSTS — los navegadores recuerdan usar siempre HTTPS
return 301Redirección permanente de HTTP a HTTPS

Paso 3: Probar la configuración

Siempre prueba antes de recargar:

sudo nginx -t

Resultado esperado:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Si la prueba falla, Nginx te indica el número de línea exacto con el error. Errores comunes:

  • Error tipográfico en la ruta del archivo (ssl_certifcate en lugar de ssl_certificate)
  • El archivo no existe en la ruta especificada
  • Puntos y comas faltantes

Paso 4: Recargar Nginx

sudo systemctl reload nginx

Usa reload, no restart. Reload aplica la nueva configuración a las nuevas conexiones sin cortar las existentes: cero tiempo de inactividad.

Paso 5: Verificar el certificado

Verificación en el navegador

Visita https://yourdomain.com. Haz clic en el icono de candado para confirmar:

  • Emitido por: «Let’s Encrypt» (o tu CA)
  • Válido: fechas de inicio y fin
  • Dominio: coincide con tu URL

Verificación por línea de comandos

# Full certificate details
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates -ext subjectAltName

# Check the full chain is present
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null \
  | grep -E 'Verify return code|depth='

Esperado: Verify return code: 0 (ok) y múltiples niveles de profundidad (tu certificado + intermedio).

Verificación en línea

Usa SSL Labs Server Test para un informe completo. Verifica:

  • Validez de la cadena de certificados
  • Soporte de protocolos (debe mostrar solo TLS 1.2 + 1.3)
  • Fortaleza de las suites de cifrado
  • Vulnerabilidades conocidas (BEAST, POODLE, Heartbleed)
  • Configuración HSTS

Objetivo: Grado A o A+.

Cómo renovar

Cuando tu certificado se acerque al vencimiento (día 60 de 90 para Let’s Encrypt):

  1. Obtén un nuevo certificado desde GetHTTPS (o tu herramienta de renovación)
  2. Reemplaza los archivos:
    sudo cp new-fullchain.pem /etc/ssl/gethttps/fullchain.pem
    sudo cp new-privkey.pem /etc/ssl/gethttps/privkey.pem
  3. Recarga Nginx:
    sudo systemctl reload nginx

No se necesita reinicio. Nginx lee los nuevos archivos al recargar. Guía completa de renovación →

¿Quieres renovación automática? Instala Certbot para renovación sin intervención: sudo certbot --nginx -d example.com. Se encarga de todo, incluyendo la configuración de Nginx.

Solución de problemas

«SSL: error:0B080074:x509 certificate routines»

Causa: Estás usando cert.pem en lugar de fullchain.pem.

Solución: Cambia ssl_certificate para que apunte a fullchain.pem, que incluye tanto tu certificado como la cadena de confianza intermedia:

ssl_certificate /etc/ssl/gethttps/fullchain.pem;  # NOT cert.pem

«cannot load certificate key»

Causa: Los permisos del archivo de clave privada son incorrectos, el archivo está corrupto o la clave no coincide con el certificado.

Solución:

# Check permissions (should be 600)
ls -la /etc/ssl/gethttps/privkey.pem

# Verify the key is valid
sudo openssl ec -in /etc/ssl/gethttps/privkey.pem -check  # For ECDSA
sudo openssl rsa -in /etc/ssl/gethttps/privkey.pem -check  # For RSA

# Verify key matches certificate
sudo openssl x509 -noout -modulus -in /etc/ssl/gethttps/fullchain.pem | md5sum
sudo openssl rsa -noout -modulus -in /etc/ssl/gethttps/privkey.pem | md5sum
# Both hashes MUST match

«nginx: [emerg] bind() to 0.0.0.0:443 failed»

Causa: El puerto 443 ya está en uso por otro proceso.

Solución:

# Find what's using port 443
sudo ss -tlnp | grep 443

# Usually: another Nginx instance or Apache
sudo systemctl stop apache2  # If Apache is running
sudo systemctl reload nginx

HTTPS funciona pero el navegador muestra «Not Secure»

Causa: Contenido mixto — tu página carga imágenes, scripts o CSS a través de http://.

Solución: Abre DevTools (F12) → Consola → busca advertencias de «Mixed Content». Actualiza todas las URLs de recursos para usar https:// o rutas relativas.

«ERR_SSL_VERSION_OR_CIPHER_MISMATCH»

Causa: El cliente no soporta las versiones TLS o los cifrados que ofrece tu servidor.

Solución: Asegúrate de que tu configuración incluya TLS 1.2 (no solo 1.3):

ssl_protocols TLSv1.2 TLSv1.3;  # NOT just TLSv1.3

El certificado aparece como «Untrusted» a pesar de los archivos correctos

Causa: La cadena de certificados está incompleta — fullchain.pem no tiene el certificado intermedio, o el archivo está en el orden equivocado.

Solución: Reconstruye fullchain.pem concatenando tu certificado + el intermedio:

cat cert.pem chain.pem > fullchain.pem

El orden importa: tu certificado primero, luego el intermedio.

Preguntas frecuentes

¿Necesito archivos de configuración separados para HTTP y HTTPS?

No. Pon ambos bloques server (puerto 80 y 443) en el mismo archivo. El bloque HTTP solo existe para redirigir a HTTPS.

¿Debo usar ssl on;?

No. ssl on; está obsoleto. Usa listen 443 ssl; en su lugar: el parámetro ssl en la directiva listen es el enfoque moderno.

¿Cuál es la diferencia entre reload y restart?

reload aplica la nueva configuración a las nuevas conexiones sin cortar las existentes. restart detiene e inicia el proceso, cortando brevemente todas las conexiones. Siempre usa reload para cambios de certificados.

¿Puedo servir múltiples dominios con diferentes certificados?

Sí. Usa bloques server separados con diferentes directivas server_name, ssl_certificate y ssl_certificate_key. Nginx usa SNI (Server Name Indication) para servir el certificado correcto según el nombre de host solicitado.

¿Nginx soporta certificados ECDSA/ECC?

Sí. Nginx maneja los certificados ECDSA exactamente igual que RSA: mismas directivas, mismo formato de archivo. GetHTTPS genera ECDSA P-256 por defecto (claves más pequeñas, negociaciones más rápidas).

¿Cómo habilito HTTP/2?

Añade http2 a la directiva listen: listen 443 ssl http2;. Esto ya está en la configuración recomendada de arriba. HTTP/2 requiere HTTPS: no puedes usarlo sobre HTTP plano.

Artículos relacionados

Primeros pasos 2026-05-08
Cómo obtener un certificado SSL gratuito (guía paso a paso)
Obtén un certificado SSL gratuito de Let's Encrypt en 5 minutos — sin software que instalar, sin cuenta que crear. Guía completa con 4 métodos, ambos tipos de desafío, instalación en 6 plataformas y solución de problemas.
Despliegue 2026-05-07
Cómo redirigir HTTP a HTTPS
Fuerza todo el tráfico a HTTPS con redirecciones del lado del servidor. Ejemplos de configuración para Nginx, Apache y .htaccess con redirecciones 301 permanentes.
Despliegue 2026-05-08
Cómo instalar un certificado SSL en Apache
Guía paso a paso para instalar un certificado SSL en Apache con mod_ssl. Cubre la subida de archivos, configuración de VirtualHost, mejores prácticas TLS, HSTS, redirección HTTP y solución de 5 errores comunes.
Despliegue 2026-05-07
Cómo solucionar advertencias de contenido mixto
El contenido mixto ocurre cuando una página HTTPS carga recursos por HTTP. Aprende cómo encontrar y solucionar errores de contenido mixto para obtener un icono de candado limpio.
Obtén un certificado SSL gratuito en tu navegador
Sin instalación, sin cuenta. Tu clave privada nunca sale de tu dispositivo.
Obtener certificado