Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Capítulo 15: NGINX en RHEL

Alto Rendimiento: NGINX es un servidor web y proxy inverso de alto rendimiento popular. Aprende cómo configurar NGINX con certificados TLS en RHEL.


15.1 Resumen de NGINX en RHEL

Nombre del Paquete: nginx Ubicación de Config: /etc/nginx/nginx.conf Ruta de Certificados: /etc/pki/tls/certs/ o /etc/nginx/certs/ Ruta de Claves: /etc/pki/tls/private/ o /etc/nginx/certs/

Fuentes de Instalación por Versión de RHEL

Versión RHELFuente NGINXCómo Instalar
RHEL 7EPEL (comunidad)Habilitar EPEL, luego yum install nginx
RHEL 8AppStream (oficial)dnf module install nginx:1.20
RHEL 9AppStream (oficial)dnf install nginx
RHEL 10AppStream (oficial)dnf install nginx

Nota: RHEL 7 requiere EPEL para NGINX. RHEL 8+ incluye NGINX en repos oficiales.


15.2 Instalación

RHEL 7

#============================================#
# INSTALAR NGINX (RHEL 7 - REQUIERE EPEL)
#============================================#

# Paso 1: Habilitar EPEL
sudo yum install epel-release -y

# Paso 2: Instalar NGINX
sudo yum install nginx -y

# Paso 3: Habilitar e iniciar
sudo systemctl enable nginx
sudo systemctl start nginx

# Paso 4: Abrir firewall
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

# Verificar
systemctl status nginx
curl http://localhost/

RHEL 8

#============================================#
# INSTALAR NGINX (RHEL 8 - DE APPSTREAM)
#============================================#

# Listar módulos NGINX disponibles
dnf module list nginx

# Instalar versión específica
sudo dnf module install nginx:1.20 -y

# O instalar predeterminado
sudo dnf install nginx -y

# Habilitar e iniciar
sudo systemctl enable nginx
sudo systemctl start nginx

# Abrir firewall
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

RHEL 9/10

#============================================#
# INSTALAR NGINX (RHEL 9/10)
#============================================#

sudo dnf install nginx -y

sudo systemctl enable nginx
sudo systemctl start nginx

# Abrir firewall
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

# Verificar
systemctl status nginx
ss -tlnp | grep :443

15.3 Configuración Básica HTTPS

Configuración TLS Mínima

#============================================#
# /etc/nginx/nginx.conf o /etc/nginx/conf.d/default.conf
#============================================#

server {
    listen 80;
    server_name www.example.com;

    # Redirigir HTTP a HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name www.example.com;

    # Archivos de certificado
    ssl_certificate     /etc/pki/tls/certs/www.example.com.crt;
    ssl_certificate_key /etc/pki/tls/private/www.example.com.key;

    # Protocolos TLS
    ssl_protocols TLSv1.2 TLSv1.3;

    # Cifrados
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # Directorio raíz
    root /usr/share/nginx/html;
    index index.html;

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

Configuración de Producción Fortalecida

#============================================#
# CONFIGURACIÓN HTTPS NGINX GRADO PRODUCCIÓN
#============================================#

server {
    listen 443 ssl http2;
    server_name api.example.com;

    # Certificados
    ssl_certificate     /etc/pki/tls/certs/api.example.com.crt;
    ssl_certificate_key /etc/pki/tls/private/api.example.com.key;

    # Versiones TLS
    ssl_protocols TLSv1.2 TLSv1.3;

    # Cifrados fuertes
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
    ssl_prefer_server_ciphers on;

    # Parámetros DH (opcional, para perfect forward secrecy)
    ssl_dhparam /etc/nginx/dhparam.pem;

    # Optimización de sesión SSL
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_session_tickets off;

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/pki/tls/certs/chain.crt;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    # HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    # Encabezados de seguridad
    add_header X-Frame-Options DENY always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Logging
    access_log /var/log/nginx/api_access.log;
    error_log /var/log/nginx/api_error.log;

    location / {
        proxy_pass http://backend_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

15.4 Configuración de Certificados

Generar Certificados para NGINX

#============================================#
# GENERACIÓN DE CERTIFICADOS PARA NGINX
#============================================#

# Paso 1: Crear directorio de certs (opcional)
sudo mkdir -p /etc/nginx/certs
sudo chmod 755 /etc/nginx/certs

# Paso 2: Generar clave privada
sudo openssl genpkey -algorithm RSA \
  -out /etc/pki/tls/private/api.example.com.key \
  -pkeyopt rsa_keygen_bits:2048

# Paso 3: Establecer permisos
sudo chmod 600 /etc/pki/tls/private/api.example.com.key
sudo chown root:nginx /etc/pki/tls/private/api.example.com.key

# Paso 4: Generar CSR
sudo openssl req -new \
  -key /etc/pki/tls/private/api.example.com.key \
  -out /tmp/api.example.com.csr \
  -subj "/CN=api.example.com" \
  -addext "subjectAltName=DNS:api.example.com,DNS:www.api.example.com"

# Paso 5: Enviar a CA, recibir certificado

# Paso 6: Instalar certificado
sudo cp api.example.com.crt /etc/pki/tls/certs/
sudo chmod 644 /etc/pki/tls/certs/api.example.com.crt

15.5 Integración con certmonger

Renovación Automatizada con certmonger

#============================================#
# CERTMONGER + NGINX
#============================================#

# Instalar certmonger
sudo dnf install certmonger
sudo systemctl enable --now certmonger

# Solicitar certificado de FreeIPA
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/nginx.example.com.crt \
  -k /etc/pki/tls/private/nginx.example.com.key \
  -D nginx.example.com \
  -K host/nginx.example.com@REALM \
  -C "systemctl reload nginx"  # ¡Auto-recargar al renovar!

# O de Let's Encrypt (RHEL 9+)
sudo getcert request \
  -c lets-encrypt \
  -f /etc/pki/tls/certs/nginx.example.com.crt \
  -k /etc/pki/tls/private/nginx.example.com.key \
  -D nginx.example.com \
  -C "systemctl reload nginx"

# Monitorear estado
sudo getcert list

15.6 Let’s Encrypt con certbot

⚠️ IMPORTANTE: EPEL Requerido

certbot NO está disponible en repositorios oficiales de RHEL. Requiere EPEL, un repositorio mantenido por la comunidad.

Instalación: Todas las versiones RHEL requieren EPEL, pero el comando de habilitación varía según la versión. Consulte el Capítulo 24 para el flujo completo de certbot.

RHEL 7

# Paso 1: Habilitar EPEL
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm -y

# Paso 2: Instalar certbot con plugin NGINX
sudo yum install certbot python2-certbot-nginx -y

RHEL 8

# Paso 1: Habilitar EPEL
sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -y
# O, con suscripción activa:
# sudo dnf install epel-release -y

# Paso 2: Instalar certbot con plugin NGINX
sudo dnf install certbot python3-certbot-nginx -y

RHEL 9/10

# Paso 1: Habilitar EPEL
sudo dnf install epel-release -y

# Paso 2: Instalar certbot con plugin NGINX
sudo dnf install certbot python3-certbot-nginx -y

Obtener y configurar el certificado (todas las versiones)

# Paso 3: Obtener e instalar certificado (¡automatizado!)
sudo certbot --nginx -d www.example.com -d example.com

# Certbot hará:
#  ✅ Generar certificado de Let's Encrypt
#  ✅ Actualizar configuración NGINX automáticamente
#  ✅ Configurar redirección HTTP a HTTPS
#  ✅ Configurar renovación automática

# Paso 4: Verificar temporizador de renovación automática
systemctl list-timers | grep certbot

# Paso 5: Probar renovación (simulación)
sudo certbot renew --dry-run

# ¡El certificado se renueva automáticamente cada 60 días!

Recuerda: EPEL tiene soporte comunitario, no de Red Hat. Para producción empresarial, considera FreeIPA + certmonger.


15.7 Proxy Inverso con TLS

NGINX como Proxy de Terminación TLS

#============================================#
# PROXY INVERSO NGINX CON TLS
#============================================#

upstream backend_servers {
    server 10.0.1.10:8080;
    server 10.0.1.11:8080;
    server 10.0.1.12:8080;
}

server {
    listen 443 ssl http2;
    server_name proxy.example.com;

    # Terminación TLS aquí
    ssl_certificate     /etc/pki/tls/certs/proxy.crt;
    ssl_certificate_key /etc/pki/tls/private/proxy.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # Proxy a backends (HTTP)
    location / {
        proxy_pass http://backend_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }
}

15.8 Solución de Problemas NGINX HTTPS

Comandos de Diagnóstico

#============================================#
# SOLUCIÓN DE PROBLEMAS NGINX HTTPS
#============================================#

# Probar sintaxis de configuración
sudo nginx -t

# Mostrar configuración completa (con includes)
sudo nginx -T

# Verificar rutas de certificado SSL
sudo nginx -T | grep ssl_certificate

# Verificar archivo de certificado
sudo openssl x509 -in /etc/pki/tls/certs/nginx.crt -noout -text

# Verificar archivo de clave
sudo openssl rsa -in /etc/pki/tls/private/nginx.key -check

# Verificar coincidencia par cert/clave
CERT=$(openssl x509 -noout -modulus -in /etc/pki/tls/certs/nginx.crt | openssl md5)
KEY=$(openssl rsa -noout -modulus -in /etc/pki/tls/private/nginx.key | openssl md5)
[ "$CERT" = "$KEY" ] && echo "✅ Coincide" || echo "❌ ¡Desajuste!"

# Verificar si NGINX está escuchando en 443
ss -tlnp | grep :443

# Verificar contexto SELinux
ls -Z /etc/pki/tls/certs/nginx.crt
ls -Z /etc/pki/tls/private/nginx.key

# Probar HTTPS localmente
curl -vk https://localhost/

# Verificar logs
sudo tail -f /var/log/nginx/error.log

Errores HTTPS Comunes de NGINX

ErrorCausaSolución
“SSL: error:0200100D…”Permission denied en clavechmod 600 en archivo de clave
“no ssl configured for the server”Falta ssl en listenAgregar listen 443 ssl;
“cannot load certificate”Archivo no encontrado o inválidoVerificar ruta y formato cert
“PEM_read_bio:no start line”Formato incorrectoAsegurar que cert esté en formato PEM
“key values mismatch”Cert/clave no coincidenRegenerar con clave correcta
“nginx: [emerg] bind() failed”Puerto ya en usoVerificar ss -tlnp | grep :443

15.9 Configuración Específica por Versión

RHEL 7: Configuración TLS Manual

#============================================#
# NGINX RHEL 7 - CONFIGURACIÓN SSL MANUAL
#============================================#

server {
    listen 443 ssl;
    server_name www.example.com;

    ssl_certificate     /etc/pki/tls/certs/www.crt;
    ssl_certificate_key /etc/pki/tls/private/www.key;

    # REQUERIDO: Deshabilitar manualmente TLS débil
    ssl_protocols TLSv1.2;  # ¡No TLS 1.0/1.1!

    # REQUERIDO: Establecer manualmente cifrados fuertes
    ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5';
    ssl_prefer_server_ciphers on;

    # Encabezados de seguridad
    add_header Strict-Transport-Security "max-age=31536000" always;

    root /usr/share/nginx/html;
}

RHEL 8/9/10: Con Crypto-Policies

#============================================#
# NGINX RHEL 8/9/10 - CON CRYPTO-POLICIES
#============================================#

server {
    listen 443 ssl http2;
    server_name www.example.com;

    ssl_certificate     /etc/pki/tls/certs/www.crt;
    ssl_certificate_key /etc/pki/tls/private/www.key;

    # Configuración TLS mínima - ¡crypto-policies manejan el resto!
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # O confiar completamente en crypto-policies:
    # (eliminar ssl_protocols y ssl_ciphers)
    # NGINX usará crypto-policy del sistema

    # Optimización de sesión
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/pki/tls/certs/chain.crt;

    # HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    root /usr/share/nginx/html;
}

15.10 Optimización de Rendimiento

Ajuste de Rendimiento SSL/TLS

#============================================#
# OPTIMIZACIÓN DE RENDIMIENTO SSL NGINX
#============================================#

http {
    # Caché de sesión SSL (reduce overhead de handshake)
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # Tamaños de buffer
    ssl_buffer_size 4k;  # Más pequeño = menor latencia, más grande = mejor throughput

    server {
        listen 443 ssl http2;
        server_name fast.example.com;

        ssl_certificate     /etc/pki/tls/certs/fast.crt;
        ssl_certificate_key /etc/pki/tls/private/fast.key;

        # Usar HTTP/2 para multiplexación
        # (ya habilitado en directiva listen)

        # Habilitar OCSP Stapling (reduce tiempo de búsqueda del cliente)
        ssl_stapling on;
        ssl_stapling_verify on;

        # Keep-alive
        keepalive_timeout 70;
        keepalive_requests 100;

        location / {
            proxy_pass http://backend;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
        }
    }
}

15.11 Múltiples Certificados (SNI)

Indicación de Nombre de Servidor (SNI)

#============================================#
# MÚLTIPLES DOMINIOS CON CERTIFICADOS DIFERENTES
#============================================#

# Sitio 1
server {
    listen 443 ssl http2;
    server_name site1.example.com;

    ssl_certificate     /etc/pki/tls/certs/site1.crt;
    ssl_certificate_key /etc/pki/tls/private/site1.key;

    root /var/www/site1;
}

# Sitio 2
server {
    listen 443 ssl http2;
    server_name site2.example.com;

    ssl_certificate     /etc/pki/tls/certs/site2.crt;
    ssl_certificate_key /etc/pki/tls/private/site2.key;

    root /var/www/site2;
}

# Sitio 3 (comodín)
server {
    listen 443 ssl http2;
    server_name *.apps.example.com;

    ssl_certificate     /etc/pki/tls/certs/wildcard.apps.crt;
    ssl_certificate_key /etc/pki/tls/private/wildcard.apps.key;

    root /var/www/apps;
}

15.12 Autenticación de Certificado de Cliente

TLS Mutuo (mTLS) con NGINX

#============================================#
# NGINX CON AUTENTICACIÓN DE CERTIFICADO DE CLIENTE
#============================================#

server {
    listen 443 ssl http2;
    server_name secure.example.com;

    # Certificados del servidor
    ssl_certificate     /etc/pki/tls/certs/secure.crt;
    ssl_certificate_key /etc/pki/tls/private/secure.key;

    # Verificación de certificado de cliente
    ssl_client_certificate /etc/pki/tls/certs/client-ca.crt;
    ssl_verify_client on;  # o 'optional'
    ssl_verify_depth 3;

    # Pasar info de cert de cliente a backend
    location / {
        proxy_pass http://backend;
        proxy_set_header X-SSL-Client-Cert $ssl_client_cert;
        proxy_set_header X-SSL-Client-DN $ssl_client_s_dn;
        proxy_set_header X-SSL-Client-Verify $ssl_client_verify;
    }
}

15.13 Probar NGINX HTTPS

Suite de Pruebas Comprehensiva

#============================================#
# PRUEBAS NGINX HTTPS
#============================================#

# Prueba 1: Sintaxis de configuración
sudo nginx -t
# nginx: configuration file /etc/nginx/nginx.conf test is successful

# Prueba 2: Mostrar configuración efectiva
sudo nginx -T | grep -A10 "server_name www.example.com"

# Prueba 3: Puerto escuchando
ss -tlnp | grep nginx

# Prueba 4: HTTPS local
curl -vk https://localhost/

# Prueba 5: Basado en hostname
curl -v https://www.example.com/

# Prueba 6: Verificar certificado desde servidor
echo | openssl s_client -connect www.example.com:443 -servername www.example.com 2>&1 | \
  openssl x509 -noout -subject -dates

# Prueba 7: TLS 1.2
openssl s_client -connect www.example.com:443 -tls1_2

# Prueba 8: TLS 1.3 (RHEL 8+)
openssl s_client -connect www.example.com:443 -tls1_3

# Prueba 9: Soporte HTTP/2
curl -I --http2 https://www.example.com/

# Prueba 10: Encabezados de seguridad
curl -I https://www.example.com/ | grep -i "strict-transport"

15.14 Problemas Comunes y Soluciones

Problema 1: “Permission denied” en Clave Privada

# Síntoma
sudo nginx -t
# nginx: [emerg] SSL_CTX_use_PrivateKey_file() failed (SSL: error:0200100D:system library:fopen:Permission denied)

# Verificar permisos
ls -l /etc/pki/tls/private/nginx.key

# Solución
sudo chmod 600 /etc/pki/tls/private/nginx.key
sudo chown root:nginx /etc/pki/tls/private/nginx.key

# Si problema SELinux:
sudo restorecon -v /etc/pki/tls/private/nginx.key

Problema 2: Cadena de Certificado No Enviada

# Probar desde cliente
openssl s_client -connect www.example.com:443 -showcerts

# Si muestra solo cert del servidor (no intermedios):
# Crear paquete de certificado
cat server.crt intermediate.crt > /etc/pki/tls/certs/bundle.crt

# Actualizar configuración NGINX
ssl_certificate /etc/pki/tls/certs/bundle.crt;

# Recargar
sudo systemctl reload nginx

Problema 3: OCSP Stapling No Funciona

# Probar OCSP stapling
openssl s_client -connect www.example.com:443 -status -tlsextdebug 2>&1 | grep -A17 "OCSP"

# Causas comunes:
# 1. No hay resolver configurado
# Solución: Agregar a nginx.conf:
resolver 8.8.8.8 8.8.4.4 valid=300s;

# 2. Falta cadena de certificados confiables
# Solución:
ssl_trusted_certificate /etc/pki/tls/certs/chain.crt;

# 3. Firewall bloquea solicitudes OCSP
# Solución: Permitir HTTPS saliente

15.15 Mejores Prácticas de Seguridad

Lista de Verificación

✅ Usar solo TLS 1.2+ (deshabilitar 1.0/1.1)
✅ Cifrados fuertes con forward secrecy (ECDHE)
✅ Habilitar HSTS con max-age largo
✅ Habilitar OCSP Stapling
✅ Usar HTTP/2
✅ Permisos de archivo apropiados (600 para claves)
✅ Contextos SELinux correctos
✅ Validez de certificado ≤ 90 días con renovación automática
✅ Incluir SANs comprehensivos
✅ Encabezados de seguridad habilitados

15.16 Conclusiones Clave

  1. NGINX disponible en AppStream (RHEL 8+) o EPEL (RHEL 7)
  2. Crypto-policies simplifican config en RHEL 8/9/10
  3. certmonger se integra bien con recarga automática
  4. certbot requiere EPEL en todas las versiones RHEL
  5. SNI habilita múltiples certs en la misma IP
  6. mTLS posible para autenticación de cliente
  7. Probar exhaustivamente - sintaxis, conectividad, seguridad

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA NGINX HTTPS                                │
├──────────────────────────────────────────────────────────────┤
│ Instalar:     dnf install nginx (RHEL 8/9/10)                │
│               yum install epel-release nginx (RHEL 7)        │
│                                                              │
│ Config:       /etc/nginx/nginx.conf                          │
│               /etc/nginx/conf.d/*.conf                       │
│                                                              │
│ SSL básico:   listen 443 ssl http2;                          │
│               ssl_certificate /path/to/cert.crt;             │
│               ssl_certificate_key /path/to/key.key;          │
│                                                              │
│ Probar:       nginx -t                                       │
│ Recargar:     systemctl reload nginx                         │
│ Logs:         /var/log/nginx/error.log                       │
│                                                              │
│ certbot:      certbot --nginx (¡requiere EPEL!)              │
│ certmonger:   ipa-getcert ... -C "systemctl reload nginx"    │
└──────────────────────────────────────────────────────────────┘

⚠️ certbot requiere EPEL en todas las versiones RHEL
✅ Usar certmonger para entornos empresariales

🧪 Laboratorio Práctico

Lab 07: Configuración HTTPS de NGINX

Configura NGINX con SSL/TLS y mejores prácticas de seguridad

  • 📁 Ubicación: labs/es_ES/07-nginx-https/
  • ⏱️ Tiempo: 30-35 minutos
  • 🎯 Nivel: Intermedio

Navegación del Capítulo