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 1: Criptografía, Estructura PKI y Fundamentos

Antes de Empezar: Este capítulo construye la base conceptual que necesitas antes de tocar un solo certificado. Al finalizar, entenderás por qué existe la criptografía, cómo funciona a nivel práctico, y qué ocurre detrás de escena cuando dos máquinas establecen una conexión segura.


1.1 ¿Por Qué Usar Criptografía?

Imagina enviar una postal. Cualquier persona que la manipule—carteros, vecinos, desconocidos—puede leerla. Ahora imagina que la postal contiene tu contraseña bancaria. Así es como se ve el tráfico de red sin cifrar.

Cada paquete que viaja por una red puede ser interceptado, leído, modificado o falsificado. Sin criptografía:

AmenazaQué ocurreEjemplo real
EspionajeEl atacante lee tus datosCaptura de contraseñas en Wi-Fi público
AlteraciónEl atacante modifica datos en tránsitoInyección de malware en descarga de software
SuplantaciónEl atacante finge ser otra personaSitio bancario falso recopilando credenciales
RepudioEl remitente niega haber enviado un mensajeNegar una transacción financiera

La criptografía resuelve los cuatro problemas. No es opcional en sistemas modernos—es la base de toda comunicación segura.


1.2 Los Cuatro Pilares de la Seguridad de la Información

La criptografía proporciona cuatro garantías fundamentales. Todo sistema seguro depende de una combinación de estas:

Confidencialidad — “Solo tú puedes leer esto”

La confidencialidad asegura que los datos son legibles únicamente por el destinatario previsto. Incluso si un atacante intercepta los datos, solo ve ruido sin sentido.

Cómo se implementa:

  • Cifrado simétrico (AES-256): La misma clave cifra y descifra. Rápido, usado para datos masivos.
  • Cifrado asimétrico (RSA, ECC): La clave pública cifra, la clave privada descifra. Usado para intercambio de claves.

Contra qué protege: Espionaje.

Integridad — “Esto no ha sido alterado”

La integridad garantiza que los datos no han sido alterados entre remitente y destinatario. Si un solo bit cambia, la modificación se detecta.

Cómo se implementa:

  • Funciones hash (SHA-256): Producen una huella digital de tamaño fijo de los datos.
  • HMAC: Hash combinado con una clave secreta para integridad autenticada.
  • Firmas digitales: Hash firmado con una clave privada.
 Original:  "Transferir $100 a Bob"  → SHA-256 → a1b2c3d4...
 Alterado:  "Transferir $900 a Bob"  → SHA-256 → f7e8d9c0...  ← ¡DIFERENTE!

Contra qué protege: Alteración.

Autenticidad — “Eres quien dices ser”

La autenticidad prueba la identidad de la parte comunicante. Cuando te conectas al sitio de tu banco, necesitas la seguridad de que realmente es tu banco, no un impostor.

Cómo se implementa:

  • Certificados digitales (X.509): Vinculan una clave pública a una identidad.
  • Autoridades Certificadoras (CAs): Terceros de confianza que verifican identidades.
  • Firmas digitales: Prueban que un mensaje fue creado por el remitente declarado.

Contra qué protege: Suplantación.

No Repudio — “No puedes negar esto”

El no repudio asegura que el remitente no puede negar haber enviado un mensaje o realizado una acción. Es el equivalente digital de una firma manuscrita en un contrato.

Cómo se implementa:

  • Firmas digitales con claves privadas: Solo el poseedor de la clave puede producir la firma.
  • Sellado de tiempo: Prueba cuándo ocurrió una acción.
  • Registros de auditoría con integridad criptográfica: Registros a prueba de manipulación.

Contra qué protege: Repudio (negar responsabilidad).

Resumen: Los Cuatro Pilares

PilarPregunta que respondeImplementado porProtege contra
Confidencialidad¿Alguien más puede leerlo?Cifrado (AES, RSA)Espionaje
Integridad¿Ha sido modificado?Hashes (SHA-256), HMACAlteración
Autenticidad¿Quién lo envió?Certificados, firmasSuplantación
No repudio¿Puede el remitente negarlo?Firmas digitalesRepudio

1.3 Funciones Hash: Huellas Digitales de Datos

Una función hash toma una entrada de cualquier tamaño y produce una salida de tamaño fijo. Piensa en ella como una huella dactilar para datos.

Propiedades y Ejemplos

1. Determinista — La misma entrada siempre produce la misma salida.

SHA-256("Hello") → 185f8db32271...  (siempre)
SHA-256("Hello") → 185f8db32271...  (siempre)

2. Unidireccional (Resistencia a Preimagen) — No es posible descubrir la entrada a partir de la salida.

185f8db32271... → ???  (computacionalmente inviable encontrar la entrada)

3. Resistente a Colisiones — Es prácticamente imposible encontrar dos entradas diferentes que produzcan la misma salida.

SHA-256("entrada A") → hash1
SHA-256("entrada B") → hash2
hash1 ≠ hash2  (con probabilidad abrumadora)

4. Efecto Avalancha — Un cambio mínimo en la entrada produce una salida completamente diferente.

SHA-256("Hello World")  → a591a6d40bf420404a011733cfb7b190...
SHA-256("Hello World!") → 7f83b1657ff1fc53b92dc18148a1d65d...
                                     ↑ ¡completamente diferente!

¿Son Seguros los Hashes?

No todos los algoritmos hash son iguales. Algunos han sido rotos:

AlgoritmoTamaño de SalidaEstadoPor qué
MD5128 bitsROTOColisiones encontradas en segundos. Nunca usar para seguridad.
SHA-1160 bitsROTOGoogle demostró colisión práctica en 2017 (SHAttered).
SHA-256256 bitsSEGUROSin ataques prácticos conocidos. Estándar actual.
SHA-384384 bitsSEGUROMayor margen de seguridad.
SHA-512512 bitsSEGUROSeguridad máxima de la familia SHA-2.
SHA-3256+ bitsSEGURODiseño diferente (Keccak). Alternativa a prueba de futuro.
BLAKE2256+ bitsSEGUROMuy rápido, usado en aplicaciones modernas.

“Roto” significa: Un atacante puede encontrar dos entradas diferentes que producen el mismo hash (colisión). Esto permite falsificar documentos, certificados o firmas.

# Verifícalo tú mismo — calcula hashes en cualquier sistema RHEL:
echo -n "Hello World" | sha256sum
# a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e

echo -n "Hello World" | md5sum
# b10a8db164e0754105b7a99be72e3fe5  ← ¡NO confíes en esto para seguridad!

Usos Reales de los Hashes

Caso de usoCómoEjemplo
Almacenamiento de contraseñasAlmacena el hash, no la contraseña/etc/shadow en Linux
Integridad de archivosCompara hash antes/despuéssha256sum paquete.rpm
Firmas digitalesFirma el hash, no los datosFirma de certificados
DeduplicaciónIdentifica archivos idénticosSistemas de respaldo
BlockchainCadena de hashesPrueba de trabajo de Bitcoin

1.4 Criptografía Simétrica vs Asimétrica

Simétrica: Una Clave para Todo

Remitente y destinatario comparten la misma clave secreta. Como un candado donde ambas partes tienen una copia de la misma llave.

PropiedadValor
VelocidadMuy rápida (AES acelerado por hardware)
Tamaño de clave128 o 256 bits
Problema¿Cómo compartir la clave de forma segura?
EjemplosAES-128, AES-256, ChaCha20

Asimétrica: Dos Claves, Dos Roles

Cada parte tiene un par de claves: una clave pública (comparte libremente) y una clave privada (nunca la compartas).

PropiedadValor
VelocidadLenta (1000x más lenta que la simétrica)
Tamaño de clave2048–4096 bits (RSA) o 256 bits (ECC)
VentajaNo necesita compartir clave secreta previamente
EjemplosRSA, ECDSA, Ed25519

Por Qué Necesitamos Ambas: Cifrado Híbrido

La criptografía asimétrica resuelve el problema de distribución de claves, pero es demasiado lenta para datos masivos. La solución: usar asimétrica para intercambiar una clave simétrica, luego usar simétrica para los datos.

Esto es exactamente lo que ocurre en cada conexión HTTPS.


1.5 Entendiendo el Intercambio de Claves: La Analogía de Mezcla de Colores

Antes de sumergirnos en el handshake TLS/RSA real, construyamos una intuición con una analogía visual. Esto explica el intercambio de claves Diffie-Hellman, el mecanismo usado en TLS moderno para establecer un secreto compartido.

El Problema

Alice y Bob quieren acordar un color secreto compartido que Eve (la espía) no pueda descifrar, aunque Eve pueda ver todo lo que se envían entre sí.

Por Qué Eve No Puede Hacer Trampa

Mezclar pintura es fácil de hacer pero imposible de revertir. No se puede separar pintura mezclada en sus componentes originales. En matemáticas, esto es análogo a:

  • Fácil: Multiplicar dos primos grandes → obtener un producto (mezclar)
  • Difícil: Factorizar un producto grande → encontrar los primos (separar)

Esta es la función unidireccional que hace funcionar la criptografía.

De Colores a Números

Analogía de ColoresEquivalente Criptográfico
Color público (Amarillo)Parámetros públicos (primo grande, generador)
Secreto de Alice (Rojo)Clave privada de Alice
Secreto de Bob (Azul)Clave privada de Bob
Color mezclado enviado (Naranja/Verde)Clave pública (calculada desde la privada)
Secreto final compartido (Marrón)Clave de sesión compartida
“No se puede separar la pintura”El problema del logaritmo discreto es computacionalmente difícil

1.6 El Handshake TLS: Cómo Funciona Realmente una Conexión Segura

Ahora veamos qué ocurre realmente cuando tu navegador se conecta a https://banco.com. Esto combina todo lo que hemos aprendido: hashes, criptografía asimétrica, criptografía simétrica, certificados e intercambio de claves.

Recorrido Paso a Paso

Pasos 1-2 (Hello): Cliente y servidor intercambian capacidades y números aleatorios. Estos números aleatorios añaden frescura — garantizan que cada sesión es única, incluso entre las mismas partes.

Paso 3 (Certificate): El servidor prueba su identidad enviando su certificado X.509 que contiene su clave pública.

Paso 4 (Verificación): Este es el paso crítico de confianza. El cliente recorre la cadena de confianza:

Cada firma se verifica usando la clave pública del emisor. Si cualquier eslabón se rompe, el handshake falla.

Paso 5 (Intercambio de Claves): El cliente genera 48 bytes aleatorios (PreMasterSecret), los cifra con la clave pública RSA del servidor y los envía. Solo la clave privada del servidor puede descifrar — esta es la magia asimétrica.

Paso 6 (Derivación de Claves): Ambos lados calculan independientemente las mismas claves de sesión usando una Función Pseudo-Aleatoria (PRF). Aquí es donde transitamos de asimétrica lenta a simétrica rápida.

Pasos 7-9 (Comunicación Cifrada): A partir de aquí, todo se cifra con AES-256 — miles de veces más rápido que RSA.

TLS 1.3 Moderno: Más Simple y Rápido

TLS 1.3 simplificó el handshake eliminando el intercambio de claves RSA (el secreto perfecto hacia adelante ahora es obligatorio) y reduciendo viajes de ida y vuelta:


1.7 Estructura PKI: La Arquitectura de Confianza

Infraestructura de Clave Pública (PKI) es el sistema que gestiona certificados digitales y claves públicas. Responde a la pregunta: “¿Cómo sé que esta clave pública realmente pertenece a banco.com?”

¿Por Qué una Cadena?

Las CAs Raíz son extremadamente valiosas — si se comprometen, cada certificado que hayan firmado se vuelve no confiable. Por eso las CAs Raíz son:

  • Almacenadas en módulos de seguridad de hardware (HSMs) fuera de línea, aislados de la red
  • Usadas solo para firmar certificados de CAs Intermedias
  • Válidas por 20-30 años

Las CAs Intermedias hacen el trabajo diario de emitir certificados. Si se comprometen:

  • Solo los certificados de esa Intermedia se ven afectados
  • La Raíz puede revocar la Intermedia y crear una nueva
  • El daño queda contenido

Revocación: Qué Ocurre Cuando la Confianza se Rompe

Cuando una clave privada se compromete o un certificado ya no debe ser confiable:

MétodoCómo funcionaCompensación
LCR (Lista de Certificados Revocados)La CA publica lista de números de serie revocadosPuede estar desactualizada (se actualiza periódicamente)
OCSP (Protocolo de Estado de Certificado en Línea)El cliente pregunta a la CA “¿este cert aún es válido?” en tiempo realRequiere red, preocupación de privacidad
OCSP StaplingEl servidor obtiene su propia respuesta OCSP y la adjunta al handshakeLo mejor de ambos mundos

1.8 Uniendo Todo: Un Ejemplo Completo

Rastreemos una conexión HTTPS completa de principio a fin, viendo cada concepto en acción:


1.9 Conclusiones Principales

Antes de avanzar a la gestión de certificados específica de RHEL, asegúrate de entender:

ConceptoResumen en una frase
HashesHuellas digitales unidireccionales que detectan cualquier cambio (usa SHA-256+).
Cifrado simétricoLa misma clave cifra y descifra — rápido, pero distribución de clave es difícil.
Cifrado asimétricoPares de claves pública/privada — resuelve distribución, pero es lento.
Cifrado híbridoUsa asimétrico para intercambiar claves, luego simétrico para datos (TLS hace esto).
Firmas digitalesHash + clave privada = prueba de identidad e integridad.
CertificadosVinculan una clave pública a una identidad, firmados por una CA de confianza.
PKILa arquitectura de confianza: CA Raíz → CA Intermedia → Certificado entidad final.
Handshake TLSAutentica servidor, intercambia claves, luego cifra todo.
Secreto hacia adelanteUsa claves efímeras (ECDHE) para que sesiones pasadas permanezcan seguras.

Navegación del Capítulo

Capítulo 2: Introducción a los Certificados en RHEL

¡Bienvenido! Este tutorial te llevará desde no saber nada sobre certificados digitales hasta resolver problemas de certificados con confianza en sistemas Red Hat Enterprise Linux.


2.1 ¿Por Qué Este Tutorial?

Eres un administrador de RHEL. Un día, algo se rompe:

  • Apache se niega a iniciar: SSL_CTX_use_certificate:ca md too weak
  • Las conexiones LDAP fallan: TLS: hostname does not match CN
  • certmonger muestra: CA_UNREACHABLE
  • curl retorna: SSL certificate problem: unable to get local issuer certificate

¿Te suena familiar? Estos son problemas de certificados, y están en todas partes en los sistemas Linux modernos.

Este tutorial te enseña a:

  • ✅ Entender qué son los certificados (perspectiva RHEL)
  • ✅ Configurar certificados para servicios comunes de RHEL
  • Resolver problemas de certificados (¡objetivo principal!)
  • ✅ Automatizar el ciclo de vida de certificados con herramientas RHEL
  • ✅ Manejar diferencias de versiones de RHEL (7, 8, 9, 10)
  • ✅ Pasar auditorías (FIPS, STIG, cumplimiento)

2.2 ¿Para Quién es Este Tutorial?

Audiencia Principal:

  • Administradores e ingenieros RHEL
  • Ingenieros de soporte que resuelven problemas de certificados
  • Cualquiera que gestione sistemas RHEL con HTTPS, LDAPS o TLS

Prerrequisitos:

  • Conocimientos básicos de línea de comandos Linux
  • Acceso a sistemas RHEL (7, 8, 9 o 10)
  • ¡No se necesita conocimiento previo de certificados!

2.3 ¿Qué Son los Certificados? (En 60 Segundos)

Imagina que visitas https://example.com. ¿Cómo sabe tu navegador que realmente está hablando con example.com y no con un impostor?

Respuesta: Certificados digitales.

Un certificado es como una tarjeta de identificación digital que:

  1. Prueba identidad (“Soy example.com”)
  2. Habilita cifrado (comunicación segura)
  3. Está firmado por una autoridad confiable (como una CA)

En Sistemas RHEL

Los certificados se usan en todas partes:

  • Servidores web (Apache, NGINX) → HTTPS
  • Servicios de directorio (OpenLDAP, FreeIPA) → LDAPS
  • Servidores de correo (Postfix, Dovecot) → SMTPS/IMAPS
  • Bases de datos (PostgreSQL, MySQL) → Conexiones TLS
  • APIs y servicios (REST, microservicios) → mTLS
  • Túneles VPN → Conexiones seguras
  • Registros de contenedores → Imágenes seguras

Conclusión: Si está en red y es seguro en RHEL, probablemente usa certificados.


2.4 Tu Primera Inspección de Certificado

Vamos a hacerlo práctico inmediatamente. Conéctate por SSH a cualquier sistema RHEL y ejecuta:

# Ver el certificado del servidor SSH de tu sistema
sudo openssl s_client -connect localhost:22 -starttls smtp 2>/dev/null | openssl x509 -noout -text

# Mejor ejemplo: Verificar un certificado web
echo | openssl s_client -connect access.redhat.com:443 2>/dev/null | openssl x509 -noout -text | head -20

Verás una salida como:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            0a:5d:d2:48:fc:4e:2f:e2:99:81:09:74:2d:4c:d5:69
        Signature Algorithm: ecdsa-with-SHA384
        Issuer: C=US, O=DigiCert Inc, CN=DigiCert Global G3 TLS ECC SHA384 2020 CA1
        Validity
            Not Before: Oct 30 00:00:00 2025 GMT
            Not After : Oct 27 23:59:59 2026 GMT
        Subject: C=US, ST=North Carolina, L=Raleigh, O=Red Hat, Inc., CN=access.redhat.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:fc:08:bf:d2:d8:63:0c:84:a4:c8:dd:04:9c:8c:
                    99:4f:cb:93:31:7f:9e:64:27:ea:3d:a7:18:fd:3e:
                    4c:c2:58:8b:cb:f2:5c:6e:95:bf:f3:97:ba:b8:2b:
                    49:c6:51:30:f4:71:88:e3:fa:d4:f1:73:74:1d:e3:
                    2b:49:bc:9e:6e

Lo que estás viendo:

  • Issuer: Quién firmó este certificado
  • Subject: A quién pertenece este certificado
  • Validity: Cuándo es válido (expira el 15 de marzo de 2025)
  • Signature Algorithm: Cómo está asegurado (SHA-256 con RSA)

🎉 ¡Felicitaciones! Acabas de inspeccionar tu primer certificado.


2.5 Cómo Funcionan los Certificados (Contexto RHEL)

Los Tres Componentes Clave

  1. Certificado (.crt, .pem)

    • Información pública: “Soy server.example.com”
    • Contiene la clave pública
    • Almacenado en /etc/pki/tls/certs/ en RHEL
  2. Clave Privada (.key, .pem)

    • ¡Secreto! Nunca compartas esto
    • Se usa para probar que posees el certificado
    • Almacenado en /etc/pki/tls/private/ en RHEL (¡modo 600!)
  3. Autoridad Certificadora (CA)

    • Emite y firma certificados
    • Puede ser pública (Let’s Encrypt, DigiCert)
    • O interna (FreeIPA, CA corporativa)
    • CAs confiables almacenadas en /etc/pki/ca-trust/ en RHEL

La Cadena de Confianza

CA Raíz (confiable para el sistema RHEL)
  └─ CA Intermedia
      └─ Certificado del Servidor (tu servidor web)

Cuando alguien se conecta a tu servidor RHEL:

  1. El servidor envía su certificado
  2. El cliente verifica la cadena de firmas hasta una CA raíz confiable
  3. Si la cadena es válida → la conexión procede
  4. Si la cadena se rompe → error (¡y tú recibes la llamada de soporte!)

2.6 Arquitectura de Certificados de RHEL

Directorios Clave

/etc/pki/
├── ca-trust/
│   ├── source/anchors/      ← Pon aquí los certificados CA personalizados
│   └── extracted/           ← Almacén de confianza del sistema
│       ├── pem/             ← CAs en formato PEM
│       ├── openssl/         ← Confianza OpenSSL
│       └── java/            ← Confianza Java (cacerts)
├── tls/
│   ├── certs/               ← Certificados de servidor
│   ├── private/             ← Claves privadas (¡modo 700!)
│   └── cert.pem             ← Enlace simbólico de certificado predeterminado
└── nssdb/                   ← Base de datos NSS (Firefox, etc.)

Herramientas Clave

# OpenSSL - Navaja suiza de certificados
openssl version  # Verifica tu versión

# Herramientas NSS - Para bases de datos NSS
certutil -L -d /etc/pki/nssdb

# Gestión de Confianza - Agregar/eliminar CAs
update-ca-trust  # Actualizador del almacén de confianza de RHEL

# Gestor de Certificados - Renovación automática (RHEL 7+)
getcert list  # Mostrar certificados rastreados

# Crypto-Policies - Seguridad en todo el sistema (RHEL 8+)
update-crypto-policies --show  # Verificar política actual

2.7 Un Día en la Vida: Escenarios de Certificados

Escenario 1: Agregar una CA Personalizada

# Tienes una CA corporativa que firmó tus servidores internos
sudo cp corporate-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust extract

# ¡Ahora RHEL confía en certificados firmados por tu CA corporativa!

Escenario 2: Configurar Apache HTTPS

# Instalar Apache con SSL/TLS
sudo dnf install httpd mod_ssl

# Generar una clave privada
sudo openssl genpkey -algorithm RSA -out /etc/pki/tls/private/server.key \
  -pkeyopt rsa_keygen_bits:2048

# Generar una solicitud de firma de certificado (CSR)
sudo openssl req -new -key /etc/pki/tls/private/server.key \
  -out /tmp/server.csr \
  -subj "/CN=web.example.com"

# Enviar CSR a CA, obtener certificado de vuelta, instalarlo
sudo cp server.crt /etc/pki/tls/certs/

# Configurar Apache, reiniciar
sudo systemctl restart httpd

Escenario 3: Resolver un Certificado Expirado

# El servicio falla con: "certificate has expired"
# Verificar expiración del certificado
sudo openssl x509 -in /etc/pki/tls/certs/server.crt -noout -dates

# La salida muestra:
# notAfter=Jan 15 23:59:59 2024 GMT  ← ¡Ups, expirado!

# Renovar certificado, reemplazar archivo, reiniciar servicio

2.8 Diferencias de Versiones RHEL (Vista Previa)

La gestión de certificados ha evolucionado significativamente a través de las versiones de RHEL:

Versión RHELCaracterística ClaveEnfoque de Solución de Problemas
RHEL 7Enfoque tradicionalConfiguración manual, problemas TLS heredados
RHEL 8Crypto-policiesConflictos de políticas, integración certmonger
RHEL 9OpenSSL 3.xProblemas de proveedores, validación más estricta
RHEL 10Valores predeterminados fortalecidosSolo moderno, herramientas mejoradas

¡No te preocupes! El Capítulo 8 cubre estas diferencias de versión en detalle.


2.9 Problemas Comunes de Certificados (Vista Previa)

Aprenderás a resolver:

Problemas de Configuración:

  • Desajuste certificado/clave
  • Permisos de archivo incorrectos
  • Rutas incorrectas en archivos de configuración

Problemas de Confianza:

  • Certificados autofirmados rechazados
  • Errores de CA desconocida
  • Fallos de validación de cadena

Problemas de Expiración:

  • Certificados expirados
  • Problemas de desfase de reloj
  • Fallos de renovación

Problemas de Versión:

  • Desajustes de versión TLS
  • Problemas de conjunto de cifrado
  • Conflictos de crypto-policy (RHEL 8+)
  • Compatibilidad OpenSSL 3.x (RHEL 9+)

Específicos de Servicio:

  • Apache: Errores de SSLCertificateFile
  • NGINX: Problemas de ssl_certificate
  • Postfix: Fallos de handshake TLS
  • LDAP: TLS: hostname does not match

2.10 Resumen del Camino de Aprendizaje

Este tutorial está organizado para administradores RHEL:

Parte 1: Fundamentos (Capítulos 1-7)

Comienza aquí. Aprende los conceptos básicos de certificados en contexto RHEL.

Parte 2: Específico por Versión (Capítulos 8-13)

Inmersión Profunda en diferencias de RHEL 7, 8, 9, 10.

Parte 3: Servicios (Capítulos 14-21)

Configura certificados para Apache, NGINX, Postfix, LDAP, etc.

Parte 4: Automatización (Capítulos 22-26)

Domina certmonger, crypto-policies, Let’s Encrypt, Ansible.

Parte 5: Solución de Problemas (Capítulos 27-33) ⭐

¡Aquí es donde te conviertes en un experto! Resolución sistemática de problemas, errores comunes, procedimientos de emergencia.

Parte 6: Migración (Capítulos 34-37)

Actualizaciones de versiones RHEL y migración de certificados.

Parte 7: Seguridad (Capítulos 38-41)

Modo FIPS, cumplimiento, fortalecimiento, auditoría.

Apéndices

Temas avanzados opcionales (Kubernetes, Vault, Zero Trust, etc.)


2.11 Cómo Usar Este Tutorial

Para Usuarios Nuevos

📖 Lee los capítulos en orden. Cada uno se basa en el conocimiento previo.

Para Usuarios Experimentados

🎯 Salta a solución de problemas (Parte 5) o servicios específicos (Parte 3).

Para Ingenieros de Soporte

🚨 Comienza con el Capítulo 27 (Metodología de Solución de Problemas de Certificados RHEL), luego profundiza en detalles.

Laboratorios Prácticos

Cada capítulo incluye ejemplos prácticos. Necesitarás:

  • Un sistema RHEL (una VM o contenedor está bien)
  • Acceso root o sudo
  • Conectividad a Internet (para instalaciones de paquetes)

2.12 Conceptos Clave a Dominar

Al final de este tutorial, entenderás:

  • Qué son los certificados y por qué RHEL los usa
  • Cómo funciona la confianza en sistemas RHEL
  • Dónde viven los certificados (/etc/pki/)
  • Qué herramientas usar (openssl, certutil, certmonger)
  • Diferencias de versión (RHEL 7 vs 8 vs 9 vs 10)
  • Cómo resolver problemas de cualquier certificado
  • Cómo automatizar el ciclo de vida de certificados
  • Cómo asegurar sistemas (FIPS, cumplimiento)

2.13 Impacto en el Mundo Real

Los problemas de certificados causan:

  • ❌ Interrupciones de servicio (certificados expirados)
  • ❌ Vulnerabilidades de seguridad (cifrados débiles)
  • ❌ Migraciones fallidas (actualizaciones de RHEL)
  • ❌ Fallos de cumplimiento (rechazos de auditoría)
  • ❌ Pérdida de productividad (tiempo de solución de problemas)

Después de este tutorial:

  • ✅ Prevenir problemas antes de que sucedan
  • ✅ Resolver problemas en minutos, no horas
  • ✅ Automatizar la gestión de certificados
  • ✅ Pasar auditorías de seguridad
  • ✅ Migrar versiones de RHEL con confianza

2.14 Tu Primer Ejercicio

Vamos a verificar que tu sistema RHEL está listo:

# Verificar versión de RHEL
cat /etc/redhat-release

# Verificar OpenSSL
openssl version

# Verificar si certmonger está instalado
rpm -q certmonger

# Verificar si puedes usar sudo
sudo whoami

# Verificar conectividad a Internet (para instalaciones de paquetes)
ping -c 3 access.redhat.com

# Listar CAs confiables actuales (muestra)
trust list | head -20

✅ ¡Si todos los comandos funcionan, estás listo para continuar!


2.15 ¡Comencemos!

Ahora entiendes:

  • Qué son los certificados
  • Por qué importan en RHEL
  • Dónde viven en el sistema de archivos
  • Qué herramientas usarás
  • Qué aprenderás en este tutorial

¿Listo para profundizar más?


Referencia Rápida

┌─────────────────────────────────────────────────────────────────┐
│ INICIO RÁPIDO DE CERTIFICADOS (RHEL)                            │
├─────────────────────────────────────────────────────────────────┤
│ Ver cert:           openssl x509 -in cert.crt -noout -text      │
│ Ver expiración:     openssl x509 -in cert.crt -noout -dates     │
│ Agregar CA:         cp ca.crt /etc/pki/ca-trust/source/anchors/ │
│                     sudo update-ca-trust                        │
│ Listar rastreados:  getcert list                                │
│ Ver política:       update-crypto-policies --show  (RHEL 8+)    │
└─────────────────────────────────────────────────────────────────┘

Ubicación cert:  /etc/pki/tls/certs/
Ubicación key:   /etc/pki/tls/private/  (¡modo 600!)
Confianza CA:    /etc/pki/ca-trust/

🧪 Laboratorio Práctico

Lab 01: Configuración del Entorno

Valida tu entorno RHEL e instala herramientas esenciales de gestión de certificados

  • 📁 Ubicación: labs/es_ES/01-environment-setup/
  • ⏱️ Tiempo: 15-20 minutos
  • 🎯 Nivel: Principiante

Navegación del Capítulo

Capítulo 3: Resumen de Herramientas de Certificados en RHEL

Objetivo de Aprendizaje: Familiarízate con las herramientas esenciales para gestionar certificados en RHEL para que sepas qué herramienta usar para cada tarea.


3.1 Tu Caja de Herramientas de Certificados

Al trabajar con certificados en RHEL, usarás estas herramientas principales:

HerramientaUso PrincipalVersiones RHELCuándo Usar
opensslOperaciones de certificados, pruebasTodasGenerar claves/CSRs, inspeccionar certs, probar conexiones
certutilGestión de base de datos NSSTodasBDs de cert estilo Firefox/Mozilla
update-ca-trustGestión de almacén de confianzaTodasAgregar/eliminar CAs confiables
certmongerRenovación automáticaTodasRastrear y renovar certificados automáticamente
crypto-policiesSeguridad en todo el sistemaRHEL 8+Controlar versiones TLS y cifrados
getcertCLI de certmongerTodasSolicitar y gestionar certs rastreados
trustGestión de confianza P11-kitTodas (mejorado RHEL 8+)Operaciones avanzadas de confianza

3.2 OpenSSL - La Navaja Suiza

Disponible: Todas las versiones de RHEL Paquete: openssl

Diferencias de Versión

# Verificar tu versión
openssl version

# RHEL 7: OpenSSL 1.0.2k-26
# RHEL 8: OpenSSL 1.1.1k-14
# RHEL 9: OpenSSL 3.5.5-2
# RHEL 10: OpenSSL 3.5.5-2

Usos Comunes

#============================================#
# INSPECCIONAR CERTIFICADOS
#============================================#

# Ver detalles del certificado
openssl x509 -in cert.crt -noout -text

# Verificar expiración
openssl x509 -in cert.crt -noout -dates
openssl x509 -in cert.crt -noout -checkend 86400  # Verificar si expira en 24h

# Ver asunto del certificado
openssl x509 -in cert.crt -noout -subject -issuer


#============================================#
# GENERAR CLAVES
#============================================#

# Estilo RHEL 7 (aún funciona en todas las versiones)
openssl genrsa -out server.key 2048

# Estilo moderno RHEL 8+ (recomendado)
openssl genpkey -algorithm RSA -out server.key -pkeyopt rsa_keygen_bits:2048

# Clave EC RHEL 9+ (curva elíptica)
openssl genpkey -algorithm EC -out ec.key -pkeyopt ec_paramgen_curve:P-256


#============================================#
# CREAR CSR (Solicitud de Firma de Certificado)
#============================================#

# CSR básico
openssl req -new -key server.key -out server.csr \
  -subj "/C=US/ST=State/L=City/O=Organization/CN=server.example.com"

# CSR con SANs (¡requerido para navegadores modernos!)
openssl req -new -key server.key -out server.csr \
  -subj "/CN=server.example.com" \
  -addext "subjectAltName=DNS:server.example.com,DNS:www.example.com"


#============================================#
# PROBAR CONEXIONES
#============================================#

# Probar HTTPS
openssl s_client -connect server.example.com:443 -servername server.example.com

# Probar versión TLS específica
openssl s_client -connect server.example.com:443 -tls1_2
openssl s_client -connect server.example.com:443 -tls1_3

# Probar LDAPS
openssl s_client -connect ldap.example.com:636

# Probar SMTP con STARTTLS
openssl s_client -connect mail.example.com:25 -starttls smtp

Diferencias Específicas por Versión

RHEL 7 (OpenSSL 1.0.2k):

  • ✅ Estable y bien probado
  • ❌ Sin soporte TLS 1.3
  • ❌ Sintaxis de comando antigua

RHEL 8 (OpenSSL 1.1.1k):

  • ✅ Soporte TLS 1.3
  • ✅ Sintaxis de comando moderna
  • ✅ Mejores valores predeterminados

RHEL 9/10 (OpenSSL 3.5.5):

  • ✅ Arquitectura de proveedores
  • ✅ Soporte FIPS mejorado
  • ⚠️ Cambios en API (afecta apps personalizadas)
  • ⚠️ Algoritmos heredados requieren -provider legacy

3.3 certutil - Herramienta de Base de Datos NSS

Disponible: Todas las versiones de RHEL Paquete: nss-tools

Usado para bases de datos de certificados estilo Mozilla/Firefox.

Usos Comunes

#============================================#
# GESTIONAR BASE DE DATOS NSS
#============================================#

# Crear nueva base de datos
certutil -N -d /etc/pki/nssdb

# Listar certificados
certutil -L -d /etc/pki/nssdb

# Agregar certificado CA
certutil -A -n "My CA" -t "CT,C,C" -d /etc/pki/nssdb -i ca.crt

# Eliminar certificado
certutil -D -n "Certificate Name" -d /etc/pki/nssdb

# Exportar certificado
certutil -L -n "Certificate Name" -d /etc/pki/nssdb -a > exported.crt

Cuándo Usar certutil

  • Gestionar certificados de Firefox/Thunderbird
  • Trabajar con aplicaciones que usan NSS (muchos servicios Red Hat)
  • Cuando veas archivos .db en /etc/pki/nssdb/

3.4 update-ca-trust - Gestión del Almacén de Confianza

Disponible: Todas las versiones de RHEL Paquete: ca-certificates (instalado por defecto)

Gestiona qué Autoridades Certificadoras (CAs) confía tu sistema.

Cómo Funciona

Tus CAs Personalizadas
  ↓
/etc/pki/ca-trust/source/anchors/
  ↓
update-ca-trust extract
  ↓
/etc/pki/ca-trust/extracted/
  ├── pem/tls-ca-bundle.pem       (OpenSSL/Python/Ruby)
  ├── openssl/ca-bundle.trust.crt (Específico de OpenSSL)
  └── java/cacerts                (Aplicaciones Java)

Usos Comunes

#============================================#
# AGREGAR CA PERSONALIZADA
#============================================#

# Paso 1: Copiar certificado CA
sudo cp corporate-ca.crt /etc/pki/ca-trust/source/anchors/

# Paso 2: Actualizar almacén de confianza
sudo update-ca-trust extract

# ¡Eso es todo! Ahora todas las aplicaciones confían en esta CA


#============================================#
# ELIMINAR/PONER EN LISTA NEGRA CA (RHEL 8+)
#============================================#

# Poner en lista negra una CA comprometida
sudo cp compromised-ca.crt /etc/pki/ca-trust/source/blacklist/
sudo update-ca-trust extract


#============================================#
# VERIFICAR CONFIANZA
#============================================#

# Verificar si el certificado es confiable
openssl verify /path/to/cert.crt

# Listar todas las CAs confiables
trust list | grep "certificate-authority"

# Buscar CA específica
trust list | grep -i "Let's Encrypt"

Directorios Clave

/etc/pki/ca-trust/
├── source/
│   ├── anchors/          ← Agrega tus CAs confiables aquí
│   └── blacklist/        ← Lista negra de CAs (RHEL 8+)
└── extracted/
    ├── pem/              ← Usado por la mayoría de apps
    ├── openssl/          ← Específico de OpenSSL
    └── java/             ← Aplicaciones Java

3.5 certmonger - Renovación Automática de Certificados

Disponible: Todas las versiones de RHEL Paquete: certmonger

La herramienta “configúralo y olvídate” para certificados.

Qué Hace

certmonger:

  • Rastrea fechas de expiración de certificados
  • Renueva automáticamente antes de expirar
  • Funciona con múltiples CAs (IPA, Let’s Encrypt, externa)
  • Ejecuta comandos post-renovación (ej: reiniciar servicios)

Flujo de Trabajo Básico

#============================================#
# INSTALACIÓN
#============================================#

sudo dnf install certmonger
sudo systemctl enable --now certmonger


#============================================#
# SOLICITAR CERTIFICADO
#============================================#

# Desde FreeIPA
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/web.crt \
  -k /etc/pki/tls/private/web.key \
  -D web.example.com \
  -K host/web.example.com@REALM

# Autofirmado (para pruebas)
sudo getcert request \
  -f /etc/pki/tls/certs/test.crt \
  -k /etc/pki/tls/private/test.key


#============================================#
# MONITOREAR CERTIFICADOS
#============================================#

# Listar todos los certificados rastreados
sudo getcert list

# Verificar certificado específico
sudo getcert list -f /etc/pki/tls/certs/web.crt

# Observar renovación
sudo journalctl -u certmonger -f

Características Clave por Versión

RHEL 7:

  • Rastreo y renovación básicos
  • Integración con IPA
  • Configuración manual

RHEL 8:

  • Integración mejorada con IPA
  • Mejor reporte de errores
  • Comandos post-guardado

RHEL 9:

  • Soporte ACME (¡Let’s Encrypt!)
  • Monitoreo mejorado
  • Mejor reporte de estado
# RHEL 9 - Integración con Let's Encrypt
sudo getcert request \
  -f /etc/pki/tls/certs/acme.crt \
  -k /etc/pki/tls/private/acme.key \
  -D example.com \
  -c acme-letsencrypt \
  -C "systemctl reload httpd"

3.6 crypto-policies - Seguridad en Todo el Sistema (RHEL 8+)

Disponible: Solo RHEL 8, 9, 10 Paquete: crypto-policies (instalado por defecto)

CAMBIO DE JUEGO: ¡Controla versiones TLS, cifrados y tamaños de clave en todo el sistema!

La Gran Idea

En lugar de configurar cada aplicación individualmente:

❌ FORMA ANTIGUA (RHEL 7):
- Configurar cifrados SSL de Apache
- Configurar cifrados SSL de NGINX
- Configurar ajustes TLS de Postfix
- Configurar ajustes TLS de OpenLDAP
- Configurar cada aplicación...

✅ FORMA NUEVA (RHEL 8+):
- Establecer UNA política del sistema
- ¡Todas las aplicaciones la siguen automáticamente!

Políticas Disponibles

# Verificar política actual
update-crypto-policies --show

# Políticas:
# DEFAULT  - Seguridad equilibrada (TLS 1.2+, RSA 2048+)
# LEGACY   - Modo de compatibilidad (permite TLS 1.0/1.1)
# FUTURE   - Seguridad más estricta (TLS 1.2+, RSA 3072+)
# FIPS     - Modo de cumplimiento federal

Comparación de Políticas

CaracterísticaLEGACYDEFAULTFUTUREFIPS
TLS 1.0/1.1✅ Permitido❌ Bloqueado❌ Bloqueado❌ Bloqueado
TLS 1.2✅ Sí✅ Sí✅ Sí✅ Sí
TLS 1.3✅ Sí✅ Sí✅ Sí✅ Sí
RSA Mín1024 bits2048 bits3072 bits2048 bits
Firmas SHA-1⚠️ Permitido❌ Bloqueado❌ Bloqueado❌ Bloqueado
Cifrado 3DES⚠️ Permitido❌ Bloqueado❌ Bloqueado❌ Bloqueado

Usos Comunes

#============================================#
# CAMBIAR POLÍTICA
#============================================#

# Establecer política FUTURE (más estricta)
sudo update-crypto-policies --set FUTURE
# Reiniciar o reiniciar servicios

# Usar temporalmente LEGACY (para sistemas antiguos)
sudo update-crypto-policies --set LEGACY
# Nota: ¡LEGACY debe ser temporal!


#============================================#
# POLÍTICAS PERSONALIZADAS (RHEL 9+)
#============================================#

# Subpolíticas - modificar política existente
sudo update-crypto-policies --set DEFAULT:NO-SHA1
sudo update-crypto-policies --set FUTURE:AD-SUPPORT


#============================================#
# RESOLVER PROBLEMAS DE POLÍTICA
#============================================#

# Si el servicio falla después del cambio de política:
# 1. Verificar política actual
update-crypto-policies --show

# 2. Verificar configuración de aplicación
cat /etc/crypto-policies/back-ends/opensslcnf.config

# 3. Probar con LEGACY temporalmente
sudo update-crypto-policies --set LEGACY
sudo systemctl restart <service>

Qué Controla crypto-policies

Configura automáticamente:

  • OpenSSL
  • GnuTLS
  • NSS
  • OpenJDK/Java
  • BIND
  • Kerberos
  • OpenSSH
  • ¡Y más!

Conclusión: Cambia un ajuste, actualiza la seguridad de todo el sistema. ¡Brillante!


3.7 Guía de Selección de Herramientas

“¿Qué herramienta debo usar?”

┌─────────────────────────────────────────────────────────────┐
│ ÁRBOL DE DECISIÓN DE HERRAMIENTAS DE CERTIFICADOS           │
└─────────────────────────────────────────────────────────────┘

Necesito...
│
├─ Inspeccionar un certificado
│  └─ Usar: openssl x509 -in cert.crt -noout -text
│
├─ Generar una clave/CSR
│  └─ Usar: openssl genpkey / openssl req
│
├─ Probar una conexión TLS
│  └─ Usar: openssl s_client -connect host:port
│
├─ Agregar una CA confiable en todo el sistema
│  └─ Usar: copiar a /etc/pki/ca-trust/source/anchors/
│          luego: update-ca-trust
│
├─ Renovar certificados automáticamente
│  └─ Usar: certmonger (getcert/ipa-getcert)
│
├─ Cambiar política TLS del sistema (RHEL 8+)
│  └─ Usar: update-crypto-policies --set <POLICY>
│
├─ Trabajar con bases de datos Firefox/NSS
│  └─ Usar: certutil
│
└─ Resolver problemas de certificados
   └─ Usar: ¡Metodología del Capítulo 27!

3.8 Matriz de Disponibilidad de Herramientas

HerramientaRHEL 7RHEL 8RHEL 9RHEL 10Notas
openssl1.0.2k1.1.1k3.5.53.5.5Herramienta principal
certutilHerramienta NSS
update-ca-trust✅ Mejorado✅ Mejorado✅ MejoradoGestión confianza
certmonger✅ Mejorado✅ ACME✅ ACMERenovación auto
crypto-policies✅ Subpolíticas✅ MejoradoPolítica sistema
getcertCLI certmonger
trust✅ BásicoHerramienta p11-kit

3.9 Verificación de Instalación

Verifica que tienes las herramientas esenciales:

#============================================#
# VERIFICAR HERRAMIENTAS INSTALADAS
#============================================#

# OpenSSL (debe estar instalado por defecto)
openssl version

# Herramientas NSS
rpm -q nss-tools || echo "Instalar con: sudo dnf install nss-tools"

# certmonger
rpm -q certmonger || echo "Instalar con: sudo dnf install certmonger"

# Verificar crypto-policies (solo RHEL 8+)
which update-crypto-policies &>/dev/null && \
  echo "Crypto-policies disponible: $(update-crypto-policies --show)" || \
  echo "Crypto-policies no disponible (RHEL 7 o anterior)"

3.10 Comandos de Referencia Rápida

# === OpenSSL ===
openssl version                          # Verificar versión
openssl x509 -in cert.crt -noout -text   # Inspeccionar certificado
openssl s_client -connect host:443       # Probar HTTPS

# === Almacén de Confianza ===
sudo cp ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust                     # Agregar CA confiable

# === certmonger ===
sudo getcert list                        # Listar certs rastreados
sudo getcert list -f /path/to/cert.crt   # Verificar cert específico
sudo journalctl -u certmonger -f         # Ver logs

# === Crypto-Policies (RHEL 8+) ===
update-crypto-policies --show            # Política actual
sudo update-crypto-policies --set <POL>  # Cambiar política

# === NSS ===
certutil -L -d /etc/pki/nssdb            # Listar certs NSS

3.11 ¿Qué Sigue?

Ahora que conoces las herramientas, aprenderás:

  • Capítulo 4: Conceptos básicos de criptografía
  • Capítulo 5: Entender certificados X.509
  • Capítulo 6: Inmersión Profunda en almacén de confianza RHEL
  • Capítulo 22: Dominio de certmonger (detallado)
  • Capítulo 23: Inmersión Profunda en Crypto-policies (detallado)

Tarjeta de Referencia Rápida

┌────────────────────────────────────────────────────────────┐
│ HOJA DE TRUCOS DE HERRAMIENTAS DE CERTIFICADOS RHEL        │
├────────────────────────────────────────────────────────────┤
│ Inspeccionar:  openssl x509 -in cert.crt -noout -text      │
│ Probar:        openssl s_client -connect host:443          │
│ Agregar CA:    cp ca.crt /etc/pki/ca-trust/source/anchors/ │
│                sudo update-ca-trust                        │
│ Renovar auto:  sudo getcert list                           │
│ Política:      update-crypto-policies --show  (RHEL 8+)    │
│ NSS:           certutil -L -d /etc/pki/nssdb               │
└────────────────────────────────────────────────────────────┘

Navegación del Capítulo

Capítulo 4: Criptografía Básica para Administradores RHEL

Enfoque Práctico: Aprende los conceptos de criptografía que necesitas para gestionar certificados en RHEL - ¡no se requiere un doctorado!

4.1 Simétrica vs Asimétrica

La criptografía simétrica (ej. AES) se basa en un único secreto compartido. En contraste, la criptografía asimétrica proporciona dos claves complementarias:

  • Clave pública — compártela libremente, usada para cifrado o verificación de firma.
  • Clave privada — mantenla secreta, usada para descifrado o firma.

4.2 RSA en Pocas Palabras

  1. Selecciona dos números primos grandes p y q.
  2. Calcula el módulo n = p × q.
  3. Deriva el exponente público e y el exponente privado d tal que e × d ≡ 1 (mod φ(n)).
  4. El par (n, e) es público; (n, d) es privado.

La fortaleza deriva de la dificultad de factorizar n.

4.3 Criptografía de Curva Elíptica (ECC)

ECC ofrece seguridad comparable con tamaños de clave mucho más pequeños al operar sobre puntos en curvas elípticas. Las curvas populares incluyen secp256r1 (P-256) y Curve25519.

AlgoritmoTamaño de clave para seguridad de 128 bits
RSA3072 bits
ECC256 bits

4.4 Laboratorio de Generación de Claves (OpenSSL)

# Generar clave privada RSA de 3072 bits
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out rsa.key.pem

# Extraer clave pública
openssl pkey -in rsa.key.pem -pubout -out rsa.pub.pem

# Generar par de claves EC P-256
openssl ecparam -genkey -name prime256v1 -out ec.key.pem
openssl pkey -in ec.key.pem -pubout -out ec.pub.pem

Reutilizaremos estas claves en capítulos posteriores para crear certificados.

4.5 Cifrado Híbrido

En TLS, una clave de sesión simétrica se intercambia usando criptografía asimétrica (RSA o ECDHE). Esto proporciona lo mejor de ambos mundos: eficiencia e intercambio seguro de claves.


4.6 Consideraciones Específicas de RHEL

Generación de Claves en RHEL por Versión

RHEL 7 (OpenSSL 1.0.2k):

# Estilo antiguo (aún funciona en todas las versiones)
openssl genrsa -out server.key 2048

# Extraer clave pública
openssl rsa -in server.key -pubout -out server.pub

RHEL 8+ (OpenSSL 1.1.1k / 3.5.5):

# Estilo moderno (recomendado)
openssl genpkey -algorithm RSA -out server.key -pkeyopt rsa_keygen_bits:2048

# Extraer clave pública
openssl pkey -in server.key -pubout -out server.pub

Tamaños Mínimos de Clave por Versión de RHEL

Versión RHELRSA MínimoECC MínimoAplicado Por
RHEL 7Ninguno (débil permitido)NingunoConfiguración manual
RHEL 82048 bitsP-256crypto-policy DEFAULT
RHEL 92048 bitsP-256crypto-policy DEFAULT
RHEL 102048 bitsP-256crypto-policy DEFAULT

Recomendación: ¡Siempre usa RSA 2048+ o ECC P-256+ para compatibilidad!

Pruebas en RHEL

# Generar par de claves de prueba (RHEL 8+)
openssl genpkey -algorithm RSA -out test.key -pkeyopt rsa_keygen_bits:2048

# Verificar clave
openssl pkey -in test.key -text -noout

# Crear datos de prueba
echo "Hola RHEL" > message.txt

# Firmar con clave privada
openssl dgst -sha256 -sign test.key -out message.sig message.txt

# Verificar con clave pública
openssl dgst -sha256 -verify test.pub -signature message.sig message.txt
# Verified OK

Referencia Rápida

┌─────────────────────────────────────────────────────────────┐
│ CRIPTOGRAFÍA PARA ADMINISTRADORES RHEL                      │
├─────────────────────────────────────────────────────────────┤
│ Asimétrica:   Clave pública (compartir) + Privada (secreta) │
│ Algoritmos:   RSA, ECC (Curva Elíptica)                     │
│                                                             │
│ Tamaños RSA:  2048 bits (mínimo en RHEL 8+)                 │
│               4096 bits (recomendado)                       │
│                                                             │
│ Curvas ECC:   P-256 (secp256r1) - mínimo                    │
│               P-384 (secp384r1) - recomendado               │
│                                                             │
│ RHEL 7:       openssl genrsa -out key 2048                  │
│ RHEL 8/9/10:  openssl genpkey -algorithm RSA -out key       │
│                                                             │
│ Caso de uso:  Certificados TLS/SSL                          │
│ Seguridad:    Clave privada DEBE protegerse (chmod 600)     │
└─────────────────────────────────────────────────────────────┘

🧪 Laboratorio Práctico

Lab 02: Generación de Claves

Practica la generación de pares de claves criptográficas en este ejercicio práctico

  • 📁 Ubicación: labs/es_ES/02-key-generation/
  • ⏱️ Tiempo: 20-25 minutos
  • 🎯 Nivel: Principiante

Navegación del Capítulo

Capítulo 5: Certificados X.509 en RHEL

Formato Estándar: X.509 es el estándar de certificados usado en todas partes en RHEL. Aprende su estructura y cómo trabajar con él en sistemas Red Hat.

5.1 Orígenes del Estándar

X.509 surgió del proyecto de directorio X.500 (ITU-T, 1988) para definir un certificado de identidad estándar—un documento que vincula una clave pública a un nombre de sujeto, firmado por una autoridad confiable.

5.2 Anatomía del Certificado

CampoPropósito
VersionUsualmente v3 (agrega extensiones)
Serial NumberÚnico por CA
Signature Algorithmej. sha256WithRSAEncryption
IssuerNombre Distinguido (DN) de CA
ValidityFechas Not Before y Not After
SubjectDN de la entidad (CN, O, C…)
Subject Public Key InfoAlgoritmo + Clave
ExtensionsKey Usage, SAN, CRL DP, etc.
SignatureFirma digital de la CA

5.3 Extensiones Comunes

  • Subject Alternative Name (SAN) — Hosts/IPs vinculados al cert.
  • Key Usage / Extended Key Usage — Operaciones permitidas (servidor TLS, firma de código…).
  • Basic Constraints — Indica si el cert puede firmar otros (CA:TRUE).

5.4 Ver un Certificado

openssl x509 -in server.crt -noout -text

Observa que cada sección coincide con la tabla anterior.

5.5 Codificaciones PEM vs DER

  • PEM — Base64 + encabezados -----BEGIN CERTIFICATE----- (más común en RHEL).
  • DER — ASN.1 binario, útil para dispositivos embebidos.

5.6 X.509 en Sistemas RHEL

Ubicaciones de Certificados en RHEL

# Ubicaciones estándar de certificados en RHEL
/etc/pki/tls/certs/          # Certificados de servidor (públicos)
/etc/pki/tls/private/        # Claves privadas (¡modo 600!)
/etc/pki/ca-trust/           # Certificados CA confiables
/etc/pki/nssdb/              # Base de datos NSS (Firefox, etc.)

# Ubicaciones específicas de servicios
/etc/httpd/conf/ssl.crt/     # Apache (alternativa)
/etc/nginx/certs/            # NGINX (personalizado)
/var/lib/pgsql/data/         # PostgreSQL
/etc/openldap/certs/         # OpenLDAP

Ver Certificados en RHEL

# Ver detalles completos del certificado
openssl x509 -in /etc/pki/tls/certs/server.crt -noout -text

# Verificaciones rápidas (enfoque sysadmin RHEL)
openssl x509 -in server.crt -noout -subject             # ¿Para quién es?
openssl x509 -in server.crt -noout -issuer              # ¿Quién lo firmó?
openssl x509 -in server.crt -noout -dates               # ¿Cuándo es válido?
openssl x509 -in server.crt -noout -ext subjectAltName  # SANs (¡crítico!)

# Verificar si expiró
openssl x509 -in server.crt -noout -checkend 0
# Exit 0 = válido, Exit 1 = expirado

Diferencias de Versión RHEL para X.509

Versión RHELOpenSSLRigurosidad de ValidaciónCambios Clave
RHEL 71.0.2kEstándarSANs recomendados
RHEL 81.1.1kMás estrictoSANs fuertemente recomendados
RHEL 93.5.5Muy estrictoSANs requeridos, SHA-1 bloqueado
RHEL 103.5.5Muy estrictoIgual que RHEL 9

Punto Clave: Los navegadores modernos y RHEL 9+ requieren SANs (Subject Alternative Names)!

Crear Certificados X.509 en RHEL

# Flujo de trabajo completo en RHEL

# Paso 1: Generar clave privada
openssl genpkey -algorithm RSA -out server.key -pkeyopt rsa_keygen_bits:2048

# Paso 2: Crear CSR (Solicitud de Firma de Certificado)
openssl req -new -key server.key -out server.csr \
  -subj "/C=US/ST=State/O=Company/CN=server.example.com" \
  -addext "subjectAltName=DNS:server.example.com,DNS:www.example.com"

# Paso 3: Autofirmado (¡solo para pruebas!)
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

# Paso 4: Ver tu certificado X.509
openssl x509 -in server.crt -noout -text

# Paso 5: Instalar en RHEL
sudo cp server.crt /etc/pki/tls/certs/
sudo cp server.key /etc/pki/tls/private/
sudo chmod 600 /etc/pki/tls/private/server.key

Referencia Rápida

┌─────────────────────────────────────────────────────────────────────┐
│ CERTIFICADOS X.509 EN RHEL                                          │
├─────────────────────────────────────────────────────────────────────┤
│ Estándar:      X.509 v3 (con extensiones)                           │
│ Codificación:  PEM (Base64, legible por humanos)                    │
│                                                                     │
│ Ver:           openssl x509 -in cert.crt -noout -text               │
│ Sujeto:        openssl x509 -in cert.crt -noout -subject            │
│ Expiración:    openssl x509 -in cert.crt -noout -dates              │
│ SANs:          openssl x509 -in cert.crt -noout -ext subjectAltName │
│                                                                     │
│ Ubicación:     /etc/pki/tls/certs/ (certificados)                   │
│                /etc/pki/tls/private/ (claves, ¡modo 600!)           │
│                                                                     │
│ Crítico:       SANs son REQUERIDOS en RHEL 9+                       │
│                Firma SHA-256+ requerida en RHEL 8+                  │
└─────────────────────────────────────────────────────────────────────┘

🧪 Laboratorio Práctico

Lab 04: Certificados X.509

Crea certificados autofirmados, genera CSRs, inspecciona certificados y convierte formatos

  • 📁 Ubicación: labs/es_ES/04-x509-certificates/
  • ⏱️ Tiempo: 25-30 minutos
  • 🎯 Nivel: Principiante

Navegación del Capítulo

Capítulo 6: Inmersión Profunda en el Almacén de Confianza de RHEL

Arquitectura de Confianza: Entender cómo RHEL valida certificados y gestiona CAs confiables es esencial para resolver problemas de certificados. Este capítulo va más allá de lo básico: cubre la mecánica interna de update-ca-trust, cómo p11-kit procesa las fuentes de confianza, qué sucede con los certificados duplicados y cómo depurar problemas de confianza con trust list.

6.1 Arquitectura del Almacén de Confianza de RHEL

Cómo RHEL Valida Certificados

Cuando cualquier aplicación en RHEL valida un certificado:

  1. Verificar firma del certificado usando la clave pública del emisor
  2. Encontrar certificado del emisor en el almacén de confianza
  3. Repetir hasta alcanzar la CA raíz confiable
  4. Verificar que la CA raíz es confiable por el sistema RHEL

Ubicación del almacén de confianza: /etc/pki/ca-trust/

El Rol de p11-kit

El almacén de confianza de RHEL no es un archivo plano que las aplicaciones leen directamente. Es un sistema gestionado construido sobre p11-kit, que proporciona un módulo de confianza PKCS#11. Los componentes clave son:

ComponenteRol
p11-kitMiddleware que carga módulos de confianza y los expone vía PKCS#11
p11-kit-trustEl módulo de confianza (/usr/lib64/pkcs11/p11-kit-trust.so) que lee los certificados fuente
update-ca-trustScript de shell que invoca p11-kit extract para regenerar los paquetes extraídos
trustInterfaz CLI para inspeccionar y modificar objetos de confianza gestionados por p11-kit

Aplicaciones como curl, wget, OpenSSL, GnuTLS y NSS consumen los paquetes extraídos. Nunca leen los directorios fuente directamente.


6.2 Estructura de Directorios del Almacén de Confianza

RHEL 7/8:

/etc/pki/ca-trust/
├── source/
│   ├── anchors/                   ← Certificados CA confiables agregados por el administrador
│   ├── blacklist/                 ← Certificados desconfiados agregados por el administrador
│   └── ca-bundle.legacy.crt       ← Paquete heredado (solo compatibilidad)
├── extracted/
│   ├── pem/
│   │   ├── tls-ca-bundle.pem      ← Para clientes TLS (curl, wget, Python...)
│   │   ├── email-ca-bundle.pem    ← Para validación de correo S/MIME
│   │   └── objsign-ca-bundle.pem  ← Para verificación de firma de código
│   ├── openssl/
│   │   └── ca-bundle.trust.crt    ← Formato "certificado confiable" de OpenSSL
│   ├── java/
│   │   └── cacerts                ← Keystore JKS de Java
│   └── edk2/
│       └── cacerts.bin            ← Formato de firmware UEFI
└── README

/usr/share/pki/ca-trust-source/
├── anchors/                       ← Anclas de confianza provistas por paquetes (desde RPMs)
├── blacklist/                     ← Certificados desconfiados provistos por paquetes
└── ca-bundle.trust.p11-kit        ← Paquete de CAs de Mozilla incluido por el RPM ca-certificates

RHEL 9/10+: El directorio blacklist/ fue renombrado a blocklist/:

/etc/pki/ca-trust/
├── source/
│   ├── anchors/                   ← Certificados CA confiables agregados por el administrador
│   ├── blocklist/                 ← Certificados desconfiados agregados por el administrador
│   └── ca-bundle.legacy.crt       ← Paquete heredado (solo compatibilidad)
├── extracted/
│   └── (misma estructura que arriba)
└── README

/usr/share/pki/ca-trust-source/
├── anchors/                       ← Anclas de confianza provistas por paquetes (desde RPMs)
├── blocklist/                     ← Certificados desconfiados provistos por paquetes
└── ca-bundle.trust.p11-kit        ← Paquete de CAs de Mozilla incluido por el RPM ca-certificates

Convención de nombres: A lo largo de este capítulo, blacklist/ se refiere al nombre de directorio en RHEL 7/8 y blocklist/ se refiere al nombre de directorio en RHEL 9/10+. Ambos cumplen el mismo propósito. Cuando veas una ruta como source/blacklist/, sustitúyela por source/blocklist/ en RHEL 9+.

Prioridad de Directorios Fuente

La cadena de procesamiento de update-ca-trust lee certificados de múltiples directorios fuente, procesados en un orden definido:

PrioridadDirectorioGestionado por
1 (más baja)/usr/share/pki/ca-trust-source/Paquetes RPM (ca-certificates)
2 (más alta)/etc/pki/ca-trust/source/Administrador del sistema

Dentro de cada ubicación:

  • anchors/ — Los certificados colocados aquí se tratan como CAs confiables
  • blacklist/ (RHEL 7/8) o blocklist/ (RHEL 9+) — Los certificados colocados aquí se tratan como explícitamente desconfiados

Las rutas en /etc/pki/ siempre anulan las rutas en /usr/share/pki/. Esto sigue la convención estándar de RHEL: /usr/share/ contiene los valores predeterminados de paquetes, /etc/ contiene las personalizaciones del administrador.


6.3 Qué Sucede Cuando Ejecutas update-ca-trust

La Cadena de Ejecución

update-ca-trust es un script de shell (inspecciónalo tú mismo: cat /usr/bin/update-ca-trust). Cuando ejecutas sudo update-ca-trust, ocurre la siguiente secuencia:

Paso 1: Recopilar todas las fuentes de confianza

p11-kit lee cada archivo de certificado de estos directorios:

/usr/share/pki/ca-trust-source/anchors/
/usr/share/pki/ca-trust-source/blacklist/    ← RHEL 7/8
/usr/share/pki/ca-trust-source/blocklist/    ← RHEL 9+
/usr/share/pki/ca-trust-source/ca-bundle.trust.p11-kit
/etc/pki/ca-trust/source/anchors/
/etc/pki/ca-trust/source/blacklist/          ← RHEL 7/8
/etc/pki/ca-trust/source/blocklist/          ← RHEL 9+

Acepta formatos PEM (.pem, .crt), DER (.der) y objetos de confianza p11-kit (.p11-kit).

Paso 2: Analizar atributos de confianza

Para cada certificado, p11-kit determina su disposición de confianza. El formato PEM del archivo de certificado es relevante:

  • -----BEGIN TRUSTED CERTIFICATE----- (formato “confiable” de OpenSSL) — Contiene el certificado más datos auxiliares de confianza: listas explícitas de OIDs de uso de clave confiados y rechazados. p11-kit lee estos atributos embebidos de confianza/rechazo directamente.
  • -----BEGIN CERTIFICATE----- (PEM simple) o DER — Contiene solo el certificado sin metadatos de confianza. p11-kit asigna la confianza basándose únicamente en el directorio donde se coloca el archivo (anchors/ = confiable, blacklist//blocklist/ = desconfiado).
  • Archivos en formato .p11-kit — Contienen objetos de confianza PKCS#11 con atributos de grano fino (trusted, x-distrusted, OIDs de propósito). Utilizados por el archivo ca-bundle.trust.p11-kit incluido con el paquete ca-certificates.

Crítico: Los formatos BEGIN TRUSTED CERTIFICATE y BEGIN CERTIFICATE no son intercambiables. Un archivo BEGIN TRUSTED CERTIFICATE lleva datos auxiliares de confianza — listas explícitas de OIDs de uso confiable y/o rechazado. Cuando no se listan usos (atributos de confianza vacíos), p11-kit lo interpreta como “confiable para nada” — efectivamente desconfiado. Si el mismo certificado también existe como BEGIN CERTIFICATE simple (que implica confianza para todos los propósitos), p11-kit detecta aserciones de confianza contradictorias y marca el certificado como desconfiado. Este conflicto ocurre en dos casos: (1) el BEGIN TRUSTED CERTIFICATE tiene usos rechazados explícitos, o (2) tiene atributos de confianza vacíos (ningún uso confiable, ningún uso rechazado). Ver Sección 6.6 para detalles.

Paso 3: Fusionar y resolver conflictos

Cuando el mismo certificado (identificado por su contenido codificado en DER) aparece en múltiples ubicaciones fuente, p11-kit aplica reglas de fusión:

  1. La desconfianza prevalece sobre la confianza. Si un certificado aparece tanto en anchors/ como en blacklist//blocklist/, se desconfía de él.

  2. El administrador anula los paquetes. Los atributos de confianza establecidos en /etc/pki/ca-trust/source/ anulan los de /usr/share/pki/ca-trust-source/.

  3. Los atributos explícitos anulan los predeterminados. Un archivo .p11-kit con restricciones de propósito específicas anula la confianza general otorgada a un PEM simple en anchors/.

  4. Los formatos de confianza en conflicto causan desconfianza. Si el mismo certificado (huella digital idéntica) aparece como BEGIN TRUSTED CERTIFICATE (o .p11-kit) y como BEGIN CERTIFICATE, la desconfianza ocurre en dos casos:

    • El BEGIN TRUSTED CERTIFICATE tiene usos rechazados explícitos — el rechazo contradice la confianza implícita total del PEM simple.
    • El BEGIN TRUSTED CERTIFICATE tiene atributos de confianza vacíos (ningún uso confiable, ningún uso rechazado) — p11-kit interpreta “ningún uso listado” como “confiable para nada”, lo que contradice el implícito “confiable para todos los propósitos” del PEM simple.

    En ambos casos, p11-kit marca el certificado como desconfiado.

Esta es la causa más común de desconfianza inesperada. Un administrador copia un archivo PEM simple en source/anchors/ sin darse cuenta de que el mismo certificado ya existe en ca-bundle.trust.p11-kit con atributos de uso rechazado o confianza vacía. El resultado: la CA queda desconfiada después de update-ca-trust, y los servicios que dependen de ella fallan silenciosamente.

Paso 4: Extraer a paquetes específicos por formato

p11-kit ejecuta comandos de extracción para cada formato de salida:

# Paquete PEM para TLS (el más comúnmente consumido)
p11-kit extract --format=pem-bundle \
    --filter=ca-anchors \
    --overwrite \
    --purpose=server-auth \
    /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem

# Paquete PEM para correo (S/MIME)
p11-kit extract --format=pem-bundle \
    --filter=ca-anchors \
    --overwrite \
    --purpose=email-protection \
    /etc/pki/ca-trust/extracted/pem/email-ca-bundle.pem

# Paquete PEM para firma de código
p11-kit extract --format=pem-bundle \
    --filter=ca-anchors \
    --overwrite \
    --purpose=code-signing \
    /etc/pki/ca-trust/extracted/pem/objsign-ca-bundle.pem

# Formato "certificado confiable" de OpenSSL (incluye atributos de confianza/rechazo)
p11-kit extract --format=openssl-bundle \
    --filter=certificates \
    --overwrite \
    /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt

# Keystore de Java
p11-kit extract --format=java-cacerts \
    --filter=ca-anchors \
    --overwrite \
    --purpose=server-auth \
    /etc/pki/ca-trust/extracted/java/cacerts

# Formato UEFI EDK2
p11-kit extract --format=edk2-cacerts \
    --filter=ca-anchors \
    --overwrite \
    --purpose=server-auth \
    /etc/pki/ca-trust/extracted/edk2/cacerts.bin

Paso 5: Actualizar enlaces simbólicos de compatibilidad

El sistema mantiene enlaces simbólicos para que las rutas heredadas apunten a los paquetes extraídos:

/etc/pki/tls/certs/ca-bundle.crt → /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
/etc/pki/tls/certs/ca-bundle.trust.crt → /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
/etc/pki/java/cacerts → /etc/pki/ca-trust/extracted/java/cacerts

update-ca-trust vs update-ca-trust extract

Son funcionalmente idénticos. El script update-ca-trust acepta extract como subcomando, pero ejecutar update-ca-trust sin argumentos utiliza por defecto la acción extract. No hay diferencia en el comportamiento.

# Estos dos comandos producen resultados idénticos:
sudo update-ca-trust
sudo update-ca-trust extract

El subcomando extract existe para mayor explicitud en scripts y documentación. Históricamente, update-ca-trust también soportaba los subcomandos enable y disable (para alternar entre el nuevo almacén de confianza gestionado por p11-kit y el enfoque heredado de archivo plano), pero ya no son relevantes en sistemas RHEL modernos donde la gestión por p11-kit está siempre activa.

# Verificar estado actual (solo informativo en RHEL moderno)
update-ca-trust check

Verificar Qué Cambió

Después de ejecutar update-ca-trust, puedes verificar el resultado:

# Contar CAs confiables en el paquete PEM
grep -c '^-----BEGIN CERTIFICATE-----' /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem

# Listar todas las CAs confiables vía p11-kit
trust list --filter=ca-anchors | grep "label:" | wc -l

# Verificar si una CA específica está presente
trust list | grep -A 4 "My Company CA"

6.4 Agregar Certificados CA Personalizados

Paso a Paso

# Paso 1: Copiar certificado CA (formato PEM o DER)
sudo cp company-ca.crt /etc/pki/ca-trust/source/anchors/

# Paso 2: Actualizar almacén de confianza
sudo update-ca-trust

# Paso 3: Verificar adición
trust list | grep -i "company"

# Paso 4: Probar
curl https://internal-server.example.com

Funciona idénticamente en RHEL 7, 8, 9, 10.

Agregar con Restricciones de Propósito

Si una CA solo debe ser confiable para autenticación de servidor TLS (no para firma de correo ni firma de código), usa el comando trust en lugar del enfoque simple de copia de archivos:

# Confiar solo para autenticación de servidor TLS
sudo trust anchor --store /path/to/company-ca.crt

# O con restricción de propósito explícita vía formato p11-kit
# Crear un archivo .p11-kit con confianza restringida:
cat > /tmp/company-ca.p11-kit <<'EOF'
[p11-kit-object-v1]
class: x-certificate-extension
label: "My Company CA"
x-public-key-info: <extracted-from-cert>

[p11-kit-object-v1]
class: certificate
label: "My Company CA"
certificate-type: x-509
java-midp-security-domain: 0
trusted: true
x-distrusted: false

[p11-kit-object-v1]
class: x-certificate-extension
label: "My Company CA"
object-id: 2.5.29.37
value: "%06%08%2b%06%01%05%05%07%03%01"
EOF

El comando trust anchor --store maneja esto automáticamente y es el enfoque recomendado en RHEL 8+.


6.5 Características del Almacén de Confianza por Versión de RHEL

Evolución de la Gestión de Confianza

Versión RHELComando trustDesconfianzaDirectorio de DesconfianzaNotas
RHEL 7BásicoLimitadablacklist/Gestión manual
RHEL 8MejoradoSoporte completoblacklist/Integración p11-kit
RHEL 9MejoradoSoporte completoblocklist/Renombrado de blacklist/
RHEL 10MejoradoSoporte completoblocklist/Igual que RHEL 9

Mejora RHEL 8+:

# Gestión avanzada de confianza (RHEL 8+)
trust anchor /path/to/ca.crt --purpose server-auth
trust anchor --remove "pkcs11:id=%CERT_ID%"
trust list --filter=ca-anchors

# Desconfiar de una CA comprometida
# RHEL 7/8:
sudo cp compromised.crt /etc/pki/ca-trust/source/blacklist/
# RHEL 9+:
sudo cp compromised.crt /etc/pki/ca-trust/source/blocklist/

sudo update-ca-trust

6.6 Certificados Duplicados: Qué Sucede y Cómo Manejarlos

Variantes de Formato PEM e Implicaciones de Confianza

Antes de discutir duplicados, es esencial entender los tres formatos de encabezado PEM que RHEL utiliza, porque el formato en sí lleva semántica de confianza:

Encabezado PEMDatos de ConfianzaDónde Aparece
-----BEGIN CERTIFICATE-----Ninguno — solo certificado X.509 sin procesarArchivos descargados, respuestas CSR, exportaciones manuales
-----BEGIN TRUSTED CERTIFICATE-----Embebidos — incluye listas auxiliares de OIDs de confianza/rechazoPaquete extraído de OpenSSL (ca-bundle.trust.crt), algunos archivos de proveedores
Formato .p11-kit (no es PEM)Estructurados — objetos de confianza PKCS#11 con atributos de grano finoca-bundle.trust.p11-kit incluido por el RPM ca-certificates

Puedes inspeccionar los atributos de confianza embebidos en un archivo BEGIN TRUSTED CERTIFICATE:

# Mostrar los datos auxiliares de confianza
openssl x509 -in cert.crt -noout -text -trustout 2>/dev/null | grep -A 5 "Trusted Uses\|Rejected Uses"

Un archivo BEGIN TRUSTED CERTIFICATE con “Rejected Uses: TLS Web Server Authentication” y un archivo BEGIN CERTIFICATE para el mismo cert (que no lleva información de rechazo) son contradictorios desde la perspectiva de p11-kit.

Entender los Certificados “Duplicados”

Dos certificados pueden ser duplicados en diferentes niveles:

Nivel de CoincidenciaQué SignificaCómo lo Trata p11-kit
Codificación DER idéntica, mismo formatoCertificado idéntico byte por byte, misma envoltura de confianzaDeduplicado — aparece una vez en la salida
Codificación DER idéntica, diferente formato de confianzaMismo certificado pero uno tiene atributos BEGIN TRUSTED CERTIFICATE / .p11-kit y el otro tiene BEGIN CERTIFICATEDESCONFIADO si el formato confiable tiene usos rechazados O atributos de confianza vacíos (ningún uso listado = “confiable para nada”)
Mismo Subject + Serial + Issuer, diferente DERMismo certificado lógico pero recodificadoSe tratan como objetos separados — ambos se cargan
Mismo Subject DN, diferente SerialCertificados diferentes para la misma entidad (ej. CA reemitida)Ambos válidos, ambos cargados independientemente

La distinción crítica: p11-kit identifica duplicados por contenido de certificado codificado en DER, no por campos de metadatos. Sin embargo, “coincidir” el contenido DER es solo la mitad de la historia — lo que sucede después depende enteramente de si los formatos de envoltura de confianza coinciden:

  • Si los bytes DER crudos del certificado son idénticos y todas las fuentes coinciden en la disposición de confianza → deduplicado, confiable
  • Si los bytes DER crudos del certificado son idénticos pero una fuente tiene OIDs de uso rechazado embebidos y la otra no → aserciones de confianza contradictorias → DESCONFIADO
  • Si los bytes DER crudos del certificado son idénticos pero una fuente tiene BEGIN TRUSTED CERTIFICATE con atributos de confianza vacíos (ningún uso confiable, ningún uso rechazado) → p11-kit interpreta como “confiable para nada” → contradice confianza implícita total → DESCONFIADO
  • Si los bytes DER crudos del certificado son idénticos y una fuente tiene BEGIN TRUSTED CERTIFICATE con solo usos confiables explícitos (sin usos rechazados) → certificado es aceptado con los propósitos de confianza especificados
  • Si los bytes DER crudos del certificado difieren (incluso por un solo byte) → p11-kit los trata como certificados separados y ambos se incluyen

Escenario: Formatos de Confianza en Conflicto (Más Peligroso)

Este es el problema de “duplicados” más común y más dañino. Ocurre silenciosamente cuando un administrador copia un certificado en source/anchors/ sin darse cuenta de que el mismo certificado ya existe en el paquete del sistema con OIDs de uso rechazado o atributos de confianza vacíos en sus datos de confianza.

Ejemplo:

/usr/share/pki/ca-trust-source/ca-bundle.trust.p11-kit
  → Contiene "My Corp CA" como objeto de confianza p11-kit con atributos de confianza específicos
    INCLUYENDO usos rechazados (ej.: "Rejected Uses: TLS Web Server Authentication")
    O con atributos de confianza vacíos (ningún uso confiable, ningún uso rechazado listado)

/etc/pki/ca-trust/source/anchors/my-corp-ca.crt
  → Mismo "My Corp CA" como PEM simple (-----BEGIN CERTIFICATE-----)
    (sin atributos de confianza — depende de la ubicación del directorio para confianza implícita)

Resultado: El mismo contenido DER del certificado ahora tiene descripciones de confianza contradictorias. El objeto de confianza p11-kit o rechaza explícitamente ciertos usos, o no lista ningún uso (lo que p11-kit interpreta como “confiable para nada”). El PEM simple no lleva metadatos de confianza, implicando confianza para todos los propósitos. p11-kit no puede reconciliar estas contradicciones, y marca el certificado como desconfiado. Después de ejecutar update-ca-trust:

  • El certificado desaparece de tls-ca-bundle.pem
  • trust list lo muestra con trust: distrusted
  • Todos los servicios que dependen de esta CA comienzan a fallar con certificate verify failed

Este mismo problema ocurre con el formato BEGIN TRUSTED CERTIFICATE de OpenSSL cuando contiene usos rechazados O confianza vacía:

/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
  → Contiene el certificado como -----BEGIN TRUSTED CERTIFICATE-----
    (con OIDs de "Rejected Uses" embebidos, O sin ningún uso confiable/rechazado listado)

/etc/pki/ca-trust/source/anchors/certificate.crt
  → Mismo certificado como -----BEGIN CERTIFICATE-----
    (sin datos embebidos de confianza — sin información de rechazo)

Resultado: Mismo desenlace — el rechazo o la confianza vacía en una fuente contradice la confianza implícita en la otra, certificado marcado como desconfiado.

Información clave: En un BEGIN TRUSTED CERTIFICATE, “ningún uso confiable/rechazado listado” NO significa “confiable para todos los propósitos.” Significa “confiable para nada.” Esta es la distinción crítica respecto a un BEGIN CERTIFICATE simple en anchors/, donde la ubicación en el directorio otorga confianza implícita total. Para depurar, busque certificados duplicados en /etc/pki/ca-trust/source/ y /usr/share/pki/ca-trust-source/ y verifique si existe algún BEGIN TRUSTED CERTIFICATE sin Reject o con confianza vacía que pueda conflictuar con una copia PEM simple.

Cómo solucionarlo:

# Opción 1: Eliminar el duplicado PEM simple de anchors/
sudo rm /etc/pki/ca-trust/source/anchors/my-corp-ca.crt
sudo update-ca-trust

# Opción 2: Si NECESITAS el cert en anchors/, conviértelo al
# formato confiable que coincida con los atributos de confianza existentes:
openssl x509 -in my-corp-ca.crt -addtrust serverAuth \
    -addtrust emailProtection -out my-corp-ca-trusted.crt
sudo cp my-corp-ca-trusted.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

# Verificar la corrección
trust list --filter=ca-anchors | grep -A 3 "My Corp CA"

Escenario: Desconfianza Explícita

/usr/share/pki/ca-trust-source/ca-bundle.trust.p11-kit
  → Contiene "Legacy Corp CA" con confianza completa

/etc/pki/ca-trust/source/blacklist/legacy-corp-ca.crt    ← RHEL 7/8
/etc/pki/ca-trust/source/blocklist/legacy-corp-ca.crt    ← RHEL 9+
  → Mismo "Legacy Corp CA" como PEM simple, colocado en directorio de desconfianza

Resultado: La desconfianza prevalece por diseño. El certificado se excluye de tls-ca-bundle.pem y se marca como desconfiado en el paquete OpenSSL. Este es el comportamiento esperado cuando un administrador desconfía intencionalmente de una CA.

Escenario: Certificados Casi Idénticos (Diferente DER)

Un problema más sutil ocurre cuando dos certificados parecen iguales pero no son idénticos byte por byte:

  • Un certificado CA fue descargado de dos fuentes diferentes con un ajuste de línea PEM ligeramente diferente
  • Un certificado CA fue recodificado (PEM → DER → PEM) y obtuvo metadatos de encabezado diferentes
  • Una CA fue reemitida con el mismo Subject DN pero un nuevo par de claves y número de serie

En estos casos, p11-kit los trata como certificados distintos, y ambos terminan en los paquetes extraídos. Esto puede causar:

  • Salida confusa de trust list con aparentes duplicados
  • Tamaño de paquete incrementado (problema cosmético)
  • Confusión en la construcción de cadenas si una copia es desconfiada y la otra es confiable pero tienen diferente contenido DER

Cómo Detectar Certificados Duplicados

Método 1: Comparación de huella digital + formato

Extraer huellas digitales de todos los certificados fuente y buscar duplicados, incluyendo qué formato usa cada archivo:

# Escanear todos los directorios fuente por huellas SHA-256 duplicadas
# Y reportar el formato PEM de cada archivo
for dir in /usr/share/pki/ca-trust-source/anchors \
           /etc/pki/ca-trust/source/anchors; do
    for cert in "$dir"/*.crt "$dir"/*.pem 2>/dev/null; do
        [ -f "$cert" ] || continue
        fp=$(openssl x509 -in "$cert" -noout -fingerprint -sha256 2>/dev/null)
        fmt=$(head -1 "$cert" 2>/dev/null)
        [ -n "$fp" ] && echo "$fp  [$fmt]  $cert"
    done
done | sort

# Buscar la misma huella digital apareciendo con formatos diferentes:
# Si ves la misma huella digital tanto con "BEGIN CERTIFICATE" como con
# "BEGIN TRUSTED CERTIFICATE", esa es la fuente de un conflicto de confianza.

Si la misma huella digital aparece con encabezados PEM diferentes, has encontrado un conflicto de formato de confianza que causará desconfianza.

Método 2: Usar trust list para detectar duplicados

# Extraer todas las etiquetas y buscar duplicados
trust list --filter=ca-anchors | grep "^    label:" | sort | uniq -c | sort -rn | head -20

Si alguna etiqueta aparece más de una vez, investiga más:

# Mostrar detalles completos para un duplicado sospechoso
trust list | grep -B 2 -A 10 "label: DigiCert Global Root G2"

Método 3: Comparar el paquete extraído contra archivos fuente

# Contar certificados en el paquete PEM
grep -c 'BEGIN CERTIFICATE' /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem

# Contar certificados únicos por huella digital
awk '/BEGIN CERT/,/END CERT/' /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem | \
    csplit -z -f /tmp/cert- - '/BEGIN CERTIFICATE/' '{*}' 2>/dev/null
for f in /tmp/cert-*; do
    openssl x509 -in "$f" -noout -fingerprint -sha256 2>/dev/null
done | sort -u | wc -l
rm -f /tmp/cert-*

Si el conteo de certificados excede el conteo de huellas únicas, existen duplicados en el paquete extraído.

Cómo Identificar Diferencias Entre Duplicados Sospechosos

Cuando tienes dos archivos de certificado que parecen ser la misma CA, compáralos en cuatro niveles:

Nivel 1: Verificar el formato PEM (causa más común de conflictos)

# Verificar qué encabezado PEM usa cada archivo
head -1 cert1.crt
head -1 cert2.crt

# "-----BEGIN CERTIFICATE-----"         → PEM simple, sin datos de confianza
# "-----BEGIN TRUSTED CERTIFICATE-----" → formato confiable de OpenSSL, TIENE datos de confianza

Si uno dice BEGIN CERTIFICATE y el otro dice BEGIN TRUSTED CERTIFICATE, has encontrado el problema. Causarán un conflicto de confianza incluso si el certificado subyacente es idéntico.

Nivel 2: Comparar contenido de certificado codificado en DER

# Comparar contenido codificado en DER (elimina encabezados PEM, diferencias de espaciado)
openssl x509 -in cert1.crt -outform DER -out /tmp/cert1.der
openssl x509 -in cert2.crt -outform DER -out /tmp/cert2.der
diff /tmp/cert1.der /tmp/cert2.der && echo "DER IDÉNTICO" || echo "DER DIFERENTE"

Nivel 3: Comparar campos del certificado

# Comparar subject, issuer, serial, validez y clave
for field in subject issuer serial dates fingerprint pubkey; do
    echo "=== $field ==="
    echo "cert1: $(openssl x509 -in cert1.crt -noout -$field 2>/dev/null)"
    echo "cert2: $(openssl x509 -in cert2.crt -noout -$field 2>/dev/null)"
done

Nivel 4: Comparar atributos de confianza embebidos (si es formato TRUSTED CERTIFICATE)

# Mostrar atributos de confianza para cada archivo
echo "=== atributos de confianza cert1 ==="
openssl x509 -in cert1.crt -noout -text -trustout 2>/dev/null | grep -A 5 "Trusted Uses\|Rejected Uses"
echo "=== atributos de confianza cert2 ==="
openssl x509 -in cert2.crt -noout -text -trustout 2>/dev/null | grep -A 5 "Trusted Uses\|Rejected Uses"

Hallazgos comunes:

ObservaciónExplicación ProbableImpacto
Misma huella digital, mismo formato PEMDuplicado inofensivo — p11-kit deduplicaNinguno
Misma huella digital, diferente formato PEM (formato confiable con usos rechazados O confianza vacía)Contradicción de confianza — usos rechazados o “confiable para nada” vs confianza implícita totalCertificado marcado como DESCONFIADO
Mismo subject + serial, diferente huella digitalCertificado recodificado o manipuladoAmbos cargados como objetos separados
Mismo subject, diferente serialCertificado CA reemitido (nuevo par de claves o renovado)Ambos cargados independientemente
Mismo subject + serial + huella digital, diferente salida de trust listMismo certificado con diferentes atributos de confianza aplicadosPosible desconfianza

Limpiar Duplicados

Si el certificado ya está en el paquete del sistema (caso más común):

Un certificado en anchors/ que ya existe en ca-bundle.trust.p11-kit no siempre es inofensivo — si la copia en el paquete del sistema tiene OIDs de uso rechazado o atributos de confianza vacíos, el duplicado PEM simple causa desconfianza. Siempre verifica los atributos de confianza antes de asumir que un duplicado es benigno.

# 1. Verificar el formato del archivo en anchors/
head -1 /etc/pki/ca-trust/source/anchors/suspect.crt

# 2. Encontrar la huella digital
openssl x509 -in /etc/pki/ca-trust/source/anchors/suspect.crt -noout -fingerprint -sha256

# 3. Verificar si ese certificado existe en el paquete del sistema
trust list | grep -B5 -A5 "<subject del cert>"

# 4. Si el certificado ya existe en el paquete del sistema con atributos
#    de confianza apropiados, eliminar el duplicado de anchors/:
sudo rm /etc/pki/ca-trust/source/anchors/suspect.crt
sudo update-ca-trust

# 5. Verificar que el certificado ahora es confiable (no desconfiado)
trust list --filter=ca-anchors | grep -A 3 "<subject del cert>"

Si necesitas mantener el certificado en anchors/ (CA personalizada no en el paquete del sistema):

# Asegurar que el formato del archivo coincide con lo que p11-kit espera.
# Para CAs personalizadas no en el paquete del sistema, PEM simple está bien:
openssl x509 -in suspect.crt -out /etc/pki/ca-trust/source/anchors/suspect.crt
sudo update-ca-trust

6.7 Usar trust list para Identificar Certificados Desconfiados

El comando trust list es la herramienta principal para inspeccionar el estado del almacén de confianza después de ejecutar update-ca-trust.

Uso Básico

# Listar todos los objetos de confianza (confiables + desconfiados)
trust list

# Listar solo anclas de CA confiables
trust list --filter=ca-anchors

# Listar solo certificados desconfiados
trust list --filter=blacklist     # RHEL 7/8
trust list --filter=blocklist     # RHEL 9+

# Listar todos los certificados (sin filtrar por disposición de confianza)
trust list --filter=certificates

Anatomía de la Salida de trust list

Cada entrada en la salida de trust list se ve así:

pkcs11:id=%DE%28%F4%A4%FF%E5%B9%2F%A3%C5%03%D1%A3%49%A7%F9%96%2A%82%12;type=cert
    type: certificate
    label: DigiCert Global Root G2
    trust: anchor
    category: authority

pkcs11:id=%01%02%03...;type=cert
    type: certificate
    label: Legacy Compromised CA
    trust: distrusted
    category: authority
CampoSignificado
pkcs11:id=...URI PKCS#11 que identifica únicamente este objeto
typeSiempre certificate para certificados CA
labelNombre legible (CN del subject del certificado)
trust: anchorEl certificado es confiable como CA
trust: distrustedEl certificado está explícitamente desconfiado
category: authorityEl certificado es una CA (tiene Basic Constraints CA:TRUE)
category: other-entryEl certificado es de entidad final o no clasificado

Encontrar Certificados Desconfiados

# Listar todos los certificados desconfiados con sus etiquetas
trust list --filter=blacklist     # RHEL 7/8
trust list --filter=blocklist     # RHEL 9+

# Contar certificados desconfiados
trust list --filter=blocklist | grep "^pkcs11:" | wc -l    # RHEL 9+

# Buscar un certificado desconfiado específico
trust list --filter=blocklist | grep -B 1 -A 4 "Symantec"  # RHEL 9+

Rastrear un Certificado Desconfiado Hasta su Origen

Cuando trust list --filter=blacklist (RHEL 7/8) o trust list --filter=blocklist (RHEL 9+) muestra un certificado que no esperabas que estuviera desconfiado, necesitas encontrar dónde se origina la desconfianza:

# Paso 1: Obtener la etiqueta del certificado desconfiado
trust list --filter=blacklist     # RHEL 7/8
trust list --filter=blocklist     # RHEL 9+
# Ejemplo de salida:
# pkcs11:id=%AB%CD...;type=cert
#     type: certificate
#     label: Suspicious CA
#     trust: distrusted
#     category: authority

# Paso 2: Verificar directorio de desconfianza del administrador
# RHEL 7/8: blacklist/  |  RHEL 9+: blocklist/
for distrust_dir in /etc/pki/ca-trust/source/blacklist \
                    /etc/pki/ca-trust/source/blocklist; do
    [ -d "$distrust_dir" ] || continue
    echo "=== $distrust_dir ==="
    ls -la "$distrust_dir"/
    for f in "$distrust_dir"/*; do
        [ -f "$f" ] || continue
        subj=$(openssl x509 -in "$f" -noout -subject 2>/dev/null)
        echo "$f: $subj"
    done
done

# Paso 3: Verificar directorio de desconfianza provisto por paquetes
for distrust_dir in /usr/share/pki/ca-trust-source/blacklist \
                    /usr/share/pki/ca-trust-source/blocklist; do
    [ -d "$distrust_dir" ] || continue
    echo "=== $distrust_dir ==="
    ls -la "$distrust_dir"/
    for f in "$distrust_dir"/*; do
        [ -f "$f" ] || continue
        subj=$(openssl x509 -in "$f" -noout -subject 2>/dev/null)
        echo "$f: $subj"
    done
done

# Paso 4: Verificar atributos de desconfianza en el paquete principal p11-kit
grep -A 5 "Suspicious CA" /usr/share/pki/ca-trust-source/ca-bundle.trust.p11-kit
# Buscar "x-distrusted: true" o "nss-mozilla-ca-policy: false"

Interpretación de resultados:

Encontrado enSignificadoAcción
/etc/pki/ca-trust/source/blacklist/ (RHEL 7/8) o blocklist/ (RHEL 9+)El administrador lo desconfió explícitamenteIntencional — verificar con el equipo si es inesperado
/usr/share/pki/ca-trust-source/blacklist/ (RHEL 7/8) o blocklist/ (RHEL 9+)El paquete RPM lo desconfióMozilla/Red Hat revocó la confianza — consultar avisos de seguridad
ca-bundle.trust.p11-kit con atributos de desconfianzaMozilla eliminó la confianza aguas arribaNormal — la CA fue desconfiada por el programa de raíz de Mozilla NSS
No en ningún directorio de desconfianzaProbablemente un conflicto de formato de confianza — el mismo cert existe como BEGIN CERTIFICATE y como BEGIN TRUSTED CERTIFICATE / .p11-kitVerificar source/anchors/ por un duplicado PEM simple de un cert que ya está en el paquete del sistema (Sección 6.6)

Ejemplo Práctico: Depurar una CA Desconfiada

Un servicio falla con certificate verify failed y sospechas que la CA fue desconfiada:

# 1. Identificar la CA desde el certificado fallido
openssl x509 -in /etc/pki/tls/certs/server.crt -noout -issuer
# issuer=CN = Internal Corp CA, O = CorpCo

# 2. Verificar si el emisor es confiable
trust list --filter=ca-anchors | grep -A 3 "Internal Corp CA"
# Sin salida significa que NO está en las anclas confiables

# 3. Verificar si está activamente desconfiado
trust list --filter=blacklist | grep -A 3 "Internal Corp CA"   # RHEL 7/8
trust list --filter=blocklist | grep -A 3 "Internal Corp CA"   # RHEL 9+
# Si se encuentra aquí, la CA está explícitamente desconfiada

# 4. Verificar si está presente de alguna forma
trust list | grep -A 3 "Internal Corp CA"
# Si no se encuentra en ningún lado, nunca fue agregada al almacén de confianza

# 5. Si está desconfiada, encontrar el archivo fuente (verifica rutas de RHEL 7/8 y 9+)
find /etc/pki/ca-trust/source/blacklist/ \
     /etc/pki/ca-trust/source/blocklist/ \
     /usr/share/pki/ca-trust-source/blacklist/ \
     /usr/share/pki/ca-trust-source/blocklist/ \
     -type f 2>/dev/null | while read f; do
    if openssl x509 -in "$f" -noout -subject 2>/dev/null | grep -qi "Internal Corp CA"; then
        echo "ENCONTRADO: $f"
    fi
done

# 6. Si NO se encuentra en ningún directorio de desconfianza, verificar conflictos de formato de confianza:
#    buscar un PEM simple en anchors/ que duplique un cert en el paquete del sistema
for f in /etc/pki/ca-trust/source/anchors/*; do
    [ -f "$f" ] || continue
    if openssl x509 -in "$f" -noout -subject 2>/dev/null | grep -qi "Internal Corp CA"; then
        echo "DUPLICADO EN ANCHORS: $f"
        echo "  Formato: $(head -1 "$f")"
        echo "  Verificar si el mismo cert existe en ca-bundle.trust.p11-kit con formato de confianza diferente"
    fi
done

# 7. También verificar el paquete principal p11-kit
grep -B 2 -A 10 "Internal Corp CA" \
    /usr/share/pki/ca-trust-source/ca-bundle.trust.p11-kit

Restaurar Confianza de un Certificado Desconfiado

Si determinas que un certificado fue incorrectamente desconfiado:

# Si la entrada de desconfianza está en /etc/pki/ (gestionada por el administrador)
# RHEL 7/8:
sudo rm /etc/pki/ca-trust/source/blacklist/the-cert.crt
# RHEL 9+:
sudo rm /etc/pki/ca-trust/source/blocklist/the-cert.crt

sudo update-ca-trust

# Si la desconfianza proviene del paquete ca-certificates, necesitas
# anularla agregando el certificado como ancla confiable:
sudo cp the-cert.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
# Nota: esto funciona porque las anclas del administrador anulan la desconfianza
# a nivel de paquete para certificados que coinciden por contenido DER.

# Verificar que el certificado ahora es confiable
trust list --filter=ca-anchors | grep -A 3 "The Cert Label"

Advertencia: Anular una decisión de desconfianza de Mozilla/Red Hat solo debe hacerse si tienes una razón de negocio específica y comprendes las implicaciones de seguridad. Las CAs son desconfiadas por causa (compromiso, emisión incorrecta, violaciones de políticas).


6.8 Depuración Avanzada con trust y p11-kit

Inspeccionar Objetos de Confianza Individuales

# Volcar los atributos PKCS#11 completos para un certificado específico
trust dump --filter="pkcs11:id=%DE%28%F4%A4..." 

# Listar todos los atributos de todos los objetos de confianza (verboso, salida extensa)
trust dump

Verificar la Cadena de Extracción

Si sospechas que update-ca-trust no está produciendo la salida esperada:

# Ejecutar la extracción manualmente con salida detallada
p11-kit extract --format=pem-bundle \
    --filter=ca-anchors \
    --purpose=server-auth \
    /tmp/test-tls-bundle.pem

# Comparar con el paquete del sistema
diff <(sort /tmp/test-tls-bundle.pem) \
     <(sort /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem)

# Ejecutar con registro de depuración de p11-kit
P11_KIT_DEBUG=all update-ca-trust 2>&1 | head -100

Verificar Completitud de la Cadena de Certificados

# Verificar un certificado de servidor contra el almacén de confianza del sistema
openssl verify -CAfile /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem server.crt

# Si la cadena tiene intermedios, inclúyelos:
openssl verify -CAfile /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem \
    -untrusted intermediate.crt server.crt

# Mostrar la cadena completa que OpenSSL construiría:
openssl verify -show_chain -CAfile /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem server.crt

Verificación Cruzada del Paquete OpenSSL

El formato “certificado confiable” de OpenSSL (ca-bundle.trust.crt) incluye atributos embebidos de confianza/rechazo que son distintos del paquete PEM simple. Puedes inspeccionarlos:

# Mostrar atributos de confianza para certificados en el paquete OpenSSL
openssl x509 -in /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt \
    -noout -text -trustout 2>/dev/null | grep -A 2 "Trusted Uses\|Rejected Uses"

Verificar el Keystore de Java

# Listar todas las entradas en el almacén de confianza de Java
keytool -list -cacerts -storepass changeit 2>/dev/null | grep "trustedCertEntry" | wc -l

# Buscar una CA específica
keytool -list -cacerts -storepass changeit 2>/dev/null | grep -i "company"

6.9 Resolver Problemas de Confianza

Enfoque Sistemático

Síntoma: Falló la verificación del certificado

Paso 1: Identificar qué certificado está fallando y quién lo emitió

# Obtener la cadena del emisor desde un servidor remoto
openssl s_client -connect server.example.com:443 -showcerts </dev/null 2>/dev/null | \
    openssl x509 -noout -issuer -subject

# O desde un archivo de certificado local
openssl x509 -in server.crt -noout -issuer -subject -serial

Paso 2: Verificar si la CA emisora está en el almacén de confianza

trust list --filter=ca-anchors | grep -i "ISSUER_CN_HERE"

Paso 3: Verificar si la CA emisora está desconfiada

trust list --filter=blacklist | grep -i "ISSUER_CN_HERE"    # RHEL 7/8
trust list --filter=blocklist | grep -i "ISSUER_CN_HERE"    # RHEL 9+

Paso 4: Si falta, agregarla

sudo cp issuer-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

Paso 5: Si está desconfiada, encontrar el origen y decidir la acción

# Rastrear el origen de la desconfianza (ver Sección 6.7)
# Verifica rutas de RHEL 7/8 (blacklist) y RHEL 9+ (blocklist)
find /etc/pki/ca-trust/source/blacklist/ \
     /etc/pki/ca-trust/source/blocklist/ \
     /usr/share/pki/ca-trust-source/blacklist/ \
     /usr/share/pki/ca-trust-source/blocklist/ \
     -name '*.crt' -o -name '*.pem' 2>/dev/null | while read f; do
    openssl x509 -in "$f" -noout -subject 2>/dev/null
done

Problemas Comunes del Almacén de Confianza

ProblemaCausaSolución
CA no encontrada después de agregarla a anchors/Olvidó ejecutar update-ca-trustEjecutar sudo update-ca-trust
CA desconfiada después de agregarla a anchors/PEM simple en conflicto con formato TRUSTED CERTIFICATE o .p11-kit existente que tiene usos rechazados o confianza vacíaEliminar el duplicado de anchors/ — el paquete del sistema ya lo tiene (Sección 6.6)
CA sigue desconfiada después de agregarla a anchors/El contenido DER difiere de la copia desconfiadaComparar huellas digitales; asegurar certificado idéntico
Aplicación Java no confía en la CAKeystore de Java no regeneradoEjecutar sudo update-ca-trust (reconstruye cacerts)
Confianza restaurada después de reiniciarEl administrador agregó el cert en /usr/share/ (sobrescrito por actualizaciones RPM)Usar siempre /etc/pki/ca-trust/source/anchors/
trust list muestra entradas duplicadasMisma CA de subject desde múltiples fuentes con diferente contenido DERIdentificar y eliminar el archivo fuente redundante
update-ca-trust falla silenciosamenteArchivo de certificado corrupto en las fuentesVerificar errores de sintaxis: openssl x509 -in suspect.crt -noout

Referencia Rápida

┌────────────────────────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA DEL ALMACÉN DE CONFIANZA DE RHEL                             │
├────────────────────────────────────────────────────────────────────────────────┤
│                                                                                │
│  Agregar CA:    sudo cp ca.crt /etc/pki/ca-trust/source/anchors/               │
│                 sudo update-ca-trust                                           │
│                                                                                │
│  Desconfiar:    sudo cp bad.crt /etc/pki/ca-trust/source/blacklist/            │
│                 (RHEL 7/8) o .../source/blocklist/ (RHEL 9+)                   │
│                 sudo update-ca-trust                                           │
│                                                                                │
│  Verificar:     trust list --filter=ca-anchors | grep "Nombre CA"              │
│                 openssl verify -CAfile /etc/pki/ca-trust/extracted/            │
│                     pem/tls-ca-bundle.pem cert.crt                             │
│                                                                                │
│  Desconfiados:  trust list --filter=blacklist  (RHEL 7/8)                      │
│                 trust list --filter=blocklist  (RHEL 9+)                       │
│                                                                                │
│  Duplicados:    trust list --filter=ca-anchors | grep "label:" |               │
│                     sort | uniq -c | sort -rn                                  │
│                                                                                │
│  Comparar:      openssl x509 -in a.crt -outform DER | sha256sum                │
│                 openssl x509 -in b.crt -outform DER | sha256sum                │
│                                                                                │
│  Depurar:       P11_KIT_DEBUG=all update-ca-trust 2>&1                         │
│                                                                                │
│  Dirs fuente:   /etc/pki/ca-trust/source/{anchors,blacklist|blocklist}/        │
│                 /usr/share/pki/ca-trust-source/{anchors,blacklist|blocklist}/  │
│                                                                                │
│  Extraídos:     /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem              │
│                 /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt        │
│                 /etc/pki/ca-trust/extracted/java/cacerts                       │
│                                                                                │
│  Pipeline:      update-ca-trust = update-ca-trust extract (idénticos)          │
│                                                                                │
│  Prioridad:     blacklist/blocklist > anchors                                  │
│                 /etc/pki/ > /usr/share/pki/                                    │
│                 atributos .p11-kit > PEM simple predeterminado                 │
│                                                                                │
│  PELIGRO:       Nunca agregar un PEM simple "BEGIN CERTIFICATE" a              │
│                 anchors/ si el mismo cert ya existe en el paquete del          │
│                 sistema como "BEGIN TRUSTED CERTIFICATE" o formato             │
│                 .p11-kit. Confianza vacía (sin usos) = "confiable para         │
│                 nada" = DESCONFIADO. Usos rechazados + PEM simple →            │
│                 también DESCONFIADO.                                           │
└────────────────────────────────────────────────────────────────────────────────┘

🧪 Laboratorio Práctico

Lab 05: Gestión del Almacén de Confianza

Agrega CAs personalizadas al almacén de confianza del sistema, gestiona atributos de confianza, detecta duplicados y depura certificados desconfiados.

  • 📁 Ubicación: labs/es_ES/05-trust-store/
  • ⏱️ Tiempo: 45 minutos
  • 🎯 Nivel: Intermedio

Navegación del Capítulo

Capítulo 7: Firmas Digitales y Verificación en RHEL

Cómo Funciona la Confianza: Aprende cómo las firmas digitales habilitan la validación de certificados en sistemas RHEL.

7.1 Funciones Hash Criptográficas

Propiedades:

  1. Deterministas
  2. Resistencia a preimagen
  3. Resistencia a colisiones
  4. Efecto avalancha

Algoritmos populares: SHA-256, SHA-3, BLAKE2.

7.2 Construir Firmas

  1. Calcular hash del mensaje.
  2. Cifrar hash con clave privada → firma.
  3. El receptor descifra la firma con clave pública y compara con su propio hash.

7.3 Huellas de Certificados

Una huella es simplemente el hash del certificado codificado en DER, usado para identificarlo únicamente, ej.:

openssl x509 -in server.crt -noout -fingerprint -sha256

7.4 Laboratorio: Firmar y Verificar un Archivo

# firmar
openssl dgst -sha256 -sign rsa.key.pem -out report.sig report.pdf
# verificar
openssl dgst -sha256 -verify rsa.pub.pem -signature report.sig report.pdf

7.5 Resumen

Las firmas vinculan datos a identidades; los hashes aseguran integridad. Juntos sustentan la validación de certificados y todas las operaciones PKI.


7.6 Algoritmos de Firma en RHEL

Aprobados por Versión de RHEL

AlgoritmoRHEL 7RHEL 8RHEL 9RHEL 10
SHA-256✅ Sí✅ Sí✅ Sí✅ Sí
SHA-384✅ Sí✅ Sí✅ Sí✅ Sí
SHA-512✅ Sí✅ Sí✅ Sí✅ Sí
SHA-1✅ Sí⚠️ Obsoleto❌ Bloqueado❌ Bloqueado
MD5✅ Sí⚠️ Solo legacy❌ Bloqueado❌ Bloqueado

Crítico: ¡RHEL 9+ bloquea SHA-1 y MD5 por seguridad!

Verificar Certificados en RHEL

# Verificar cadena de certificado
openssl verify /etc/pki/tls/certs/server.crt

# Verificar contra CA específica
openssl verify -CAfile /etc/pki/tls/certs/ca-bundle.crt server.crt

# Verificar algoritmo de firma
openssl x509 -in server.crt -noout -text | grep "Signature Algorithm"
# Debe ser SHA-256+ en RHEL 8+

Referencia Rápida

┌─────────────────────────────────────────────────────────────┐
│ FIRMAS DIGITALES EN RHEL                                    │
├─────────────────────────────────────────────────────────────┤
│ Propósito:       Probar autenticidad e integridad           │
│ Cómo:            Hash + Clave privada = Firma               │
│ Verificar:       Firma + Clave pública = Hash original      │
│                                                             │
│ Aprobados:       SHA-256, SHA-384, SHA-512                  │
│ Obsoleto:        SHA-1 (bloqueado en RHEL 9+)               │
│ Bloqueado:       MD5 (bloqueado en RHEL 9+)                 │
│                                                             │
│ Verificar cert:  openssl verify cert.crt                    │
│ Ver algoritmo:   openssl x509 -noout -text | grep Signature │
│ Huella:          openssl x509 -noout -fingerprint -sha256   │
└─────────────────────────────────────────────────────────────┘

🧪 Laboratorio Práctico

Lab 03: Firmas Digitales

Firma archivos, verifica firmas y detecta manipulaciones

  • 📁 Ubicación: labs/es_ES/03-digital-signatures/
  • ⏱️ Tiempo: 20 minutos
  • 🎯 Nivel: Principiante

Navegación del Capítulo

Capítulo 8: Versiones de RHEL y Evolución de Certificados

Objetivo de Aprendizaje: Entender cómo difiere la gestión de certificados entre RHEL 7, 8, 9 y 10 para que puedas identificar rápidamente comportamientos específicos de versión al resolver problemas.


8.1 Por Qué Importa la Versión de RHEL

Al resolver problemas de certificados en RHEL, la primera pregunta siempre debe ser: “¿En qué versión de RHEL estoy?”

La gestión de certificados ha evolucionado significativamente a través de las versiones de RHEL. Lo que funciona en RHEL 7 puede fallar en RHEL 9. Entender estas diferencias es crucial para:

  • ✅ Elegir el enfoque de solución de problemas correcto
  • ✅ Identificar errores específicos de versión
  • ✅ Planificar migraciones
  • ✅ Escribir scripts de automatización compatibles

8.2 Verificación Rápida de Versión

# Método 1: Verificar /etc/redhat-release
cat /etc/redhat-release
# Ejemplos de salida:
#   Red Hat Enterprise Linux Server release 7.9 (Maipo)
#   Red Hat Enterprise Linux release 8.10 (Ootpa)
#   Red Hat Enterprise Linux release 9.8 (Plow)
#   Red Hat Enterprise Linux release 10.2 (Coughlan)

# Método 2: Usar rpm
rpm -q --queryformat '%{VERSION}\n' redhat-release

# Método 3: Verificar versión de OpenSSL (indirecto pero útil)
openssl version
# RHEL 7: OpenSSL 1.0.2k
# RHEL 8: OpenSSL 1.1.1k
# RHEL 9: OpenSSL 3.5.5
# RHEL 10: OpenSSL 3.5.5

8.3 Resumen de Versiones RHEL

Versión RHELFecha GAFin de SoporteVersión OpenSSLCaracterística Clave de Certificados
RHEL 7Junio 2014Junio 20241.0.2k-26Gestión manual tradicional
RHEL 8Mayo 2019Mayo 20291.1.1k-14Introducción de crypto-policies
RHEL 9Mayo 2022Mayo 20323.5.5-2OpenSSL 3.x, valores predeterminados más estrictos
RHEL 10Mayo 2025Mayo 20353.5.5-2Fortalecimiento continuo, preparación PQC

Fuente: Ciclo de Vida de Productos Red Hat


8.4 Resumen de Diferencias Principales

RHEL 7 (Legado)

Características:

  • ✅ Estable, bien entendido
  • ✅ Máxima compatibilidad
  • ⚠️ TLS 1.0/1.1 habilitado por defecto
  • ⚠️ Cifrados débiles permitidos
  • ⚠️ Gestión de certificados manual

Paquete: openssl-1.0.2k-26.el7_9.x86_64

Cuándo lo Verás:

  • Sistemas legacy no migrados aún
  • Aplicaciones que requieren versiones TLS antiguas
  • Entornos conservadores

Comando Clave:

# Generar clave (estilo RHEL 7)
openssl genrsa -out server.key 2048

RHEL 8 (Estándar Empresarial Actual)

Características:

  • Crypto-policies en todo el sistema (¡cambio de juego!)
  • ✅ TLS 1.2+ por defecto
  • ✅ certmonger para renovación automática
  • ✅ Suites de cifrado modernas
  • ⚠️ Cambios incompatibles con RHEL 7

Paquete: openssl-1.1.1k-14.el8_6.x86_64

Innovación Clave - Crypto-Policies:

# Ver política actual
update-crypto-policies --show
# DEFAULT, LEGACY, FUTURE, o FIPS

# ¡Control de seguridad en todo el sistema!
sudo update-crypto-policies --set FUTURE

Cuándo lo Verás:

  • La mayoría de despliegues empresariales
  • Aplicaciones modernas
  • Entornos FreeIPA

Comando Clave:

# Generar clave (estilo moderno RHEL 8)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out server.key

RHEL 9 (Estándar Moderno)

Características:

  • ✅ OpenSSL 3.5.5 con arquitectura de proveedores
  • ✅ TLS 1.2+ obligatorio
  • ✅ Crypto-policies mejoradas
  • ✅ Validación de certificados más estricta
  • ⚠️ Cambios en API de OpenSSL 3.x
  • ⚠️ Algoritmos legacy deshabilitados

Paquete: openssl-3.5.5-2.el9_8.x86_64

Cambio Mayor - Arquitectura de Proveedores:

# Listar proveedores crypto
openssl list -providers
# default, fips, legacy, base

# Algoritmos legacy requieren proveedor explícito
openssl md5 -provider legacy file.txt

Cuándo lo Verás:

  • Nuevos despliegues
  • Entornos conscientes de seguridad
  • Últimas versiones de aplicaciones

Comando Clave:

# Generar clave EC (RHEL 9)
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out ec.key

RHEL 10 (Lanzamiento Actual)

Características:

  • ✅ Mismo OpenSSL 3.5.5 que RHEL 9.8
  • ✅ Fortalecimiento de seguridad continuo
  • ✅ Preparación para criptografía post-cuántica
  • ✅ Soporte mejorado de certificados para contenedores
  • ⚠️ Valores predeterminados aún más estrictos
  • ⚠️ Eliminaciones legacy adicionales

Paquete: openssl-3.5.5-2.el10_2.x86_64

Nota: RHEL 10.0 GA fue el 20 de mayo de 2025. Las características y capacidades pueden evolucionar a través de versiones menores (10.1, 10.2, etc.). Siempre consulta la documentación oficial para tu lanzamiento específico de RHEL 10.x.

Enfoque Clave:

  • Base de criptografía resistente a cuántica
  • Prácticas de seguridad modernas
  • Cargas de trabajo nativas de contenedor y nube

Cuándo lo Verás:

  • Despliegues completamente nuevos
  • Requisitos de seguridad de vanguardia
  • Iniciativas de preparación para el futuro

8.5 Diferencias Críticas de Versión

Soporte de Versiones TLS

Versión TLSRHEL 7RHEL 8RHEL 9RHEL 10
TLS 1.0✅ Sí⚠️ Solo LEGACY❌ No❌ No
TLS 1.1✅ Sí⚠️ Solo LEGACY❌ No❌ No
TLS 1.2✅ Sí✅ Sí✅ Sí✅ Sí
TLS 1.3❌ No✅ Sí✅ Sí (preferido)✅ Sí (preferido)

Disponibilidad de Herramientas de Certificados

HerramientaRHEL 7RHEL 8RHEL 9RHEL 10
openssl1.0.2k1.1.1k3.5.53.5.5
certutil (NSS)✅ Sí✅ Sí✅ Sí✅ Sí
update-ca-trust✅ Sí✅ Mejorado✅ Mejorado✅ Mejorado
certmonger✅ Sí✅ Mejorado✅ Mejorado✅ Mejorado
crypto-policies❌ No✅ Sí✅ Mejorado✅ Mejorado
authconfig✅ Sí❌ No (usar authselect)❌ No❌ No

Cambios Clave en Cifrado/Algoritmos

Algoritmo/CaracterísticaRHEL 7RHEL 8RHEL 9RHEL 10
3DES✅ Sí⚠️ LEGACY❌ No❌ No
RC4✅ Sí❌ No❌ No❌ No
Firmas MD5✅ Sí⚠️ LEGACY❌ No❌ No
Firmas SHA-1✅ Sí⚠️ Obsoleto❌ No❌ No
RSA < 2048 bits✅ Sí❌ No❌ No❌ No
Claves DSA✅ Sí⚠️ LEGACY❌ No❌ No

8.6 Problemas Comunes Específicos de Versión

Problemas RHEL 7

# Problema: Suites de cifrado antiguas aceptadas
# Impacto: Vulnerabilidades de seguridad
# Solución: Configuración manual de cifrados Apache/NGINX

Problemas RHEL 8

# Problema: La aplicación falla después de migración desde RHEL 7
# Razón: TLS 1.0/1.1 deshabilitado por defecto
# Solución Rápida: Usar temporalmente política LEGACY (no recomendado a largo plazo)
sudo update-crypto-policies --set LEGACY

# Mejor Solución: Actualizar aplicación para soportar TLS 1.2+

Problemas RHEL 9

# Problema: Comandos OpenSSL fallan con errores de proveedor
# Razón: Arquitectura de proveedores OpenSSL 3.x
# Solución: Especificar proveedor explícitamente
openssl md5 -provider legacy file.txt

# Problema: Certificados SHA-1 rechazados
# Razón: Validación más estricta
# Solución: Reemitir certificados con SHA-256+

Problemas RHEL 10

# Problema: Valores predeterminados aún más estrictos que RHEL 9
# Impacto: Certificados legacy pueden fallar validación
# Solución: Asegurar que todos los certificados usen algoritmos modernos
#           Verificar documentación específica de RHEL 10.x para tu versión menor

8.7 Impacto de Migración

RHEL 7 → RHEL 8

Impacto en Certificados: MODERADO

  • TLS 1.0/1.1 deshabilitado
  • Cifrados débiles eliminados
  • Integración certmonger requerida para automatización

Acción Requerida:

  1. Auditar versiones TLS en uso
  2. Actualizar configuraciones de cifrado
  3. Probar aplicaciones con TLS 1.2+
  4. Considerar crypto-policies

RHEL 8 → RHEL 9

Impacto en Certificados: ALTO

  • Cambios en API de OpenSSL 3.x
  • Eliminación de algoritmos legacy
  • Validación de certificados más estricta
  • Cambios en arquitectura de proveedores

Acción Requerida:

  1. Probar todas las operaciones de certificados
  2. Actualizar scripts personalizados usando OpenSSL
  3. Validar integridad de cadena de certificados
  4. Verificar uso de SHA-1

RHEL 9 → RHEL 10

Impacto en Certificados: BAJO-MODERADO

  • Misma base OpenSSL (3.5.5)
  • Fortalecimiento incremental
  • Refinamientos de política

Acción Requerida:

  1. Revisar documentación de RHEL 10.x
  2. Probar compatibilidad de crypto-policy
  3. Validar uso de algoritmos modernos

8.8 Elegir el Enfoque Correcto

Para Solución de Problemas

# Siempre comenzar con verificación de versión
cat /etc/redhat-release

# Luego verificar versión de OpenSSL
openssl version

# Para RHEL 8+: Verificar crypto-policy
update-crypto-policies --show 2>/dev/null || echo "Pre-RHEL 8"

Árbol de Decisión de Referencia Rápida

¿Es RHEL 7?
├─ SÍ → Verificar problemas de TLS/cifrado legacy
│       Probablemente se necesita configuración manual
│       Considerar planificación de migración
│
└─ NO → ¿Es RHEL 8?
    ├─ SÍ → ¡Verificar crypto-policies primero!
    │       Usar certmonger para automatización
    │       Considerar actualización a RHEL 9
    │
    └─ NO → ¿Es RHEL 9 o 10?
        └─ SÍ → Verificar problemas de proveedor OpenSSL 3.x
                Verificar algoritmos modernos en uso
                Aprovechar herramientas mejoradas

8.9 Conclusiones Clave

  1. Siempre verificar versión RHEL primero al resolver problemas
  2. RHEL 8 introdujo crypto-policies - cambio de juego para gestión de certificados
  3. RHEL 9 usa OpenSSL 3.x - cambios significativos en API y comportamiento
  4. RHEL 10 continúa la base de RHEL 9 - mejoras incrementales
  5. Algoritmos legacy eliminados progresivamente a través de versiones
  6. Las pruebas de migración son críticas - el comportamiento de certificados cambia significativamente

8.10 ¿Qué Sigue?

Ahora que entiendes las diferencias de versiones RHEL, profundizaremos en:

  • Capítulo 9: Gestión de Certificados en RHEL 7 (detallado)
  • Capítulo 10: RHEL 8 y Crypto-Policies (detallado)
  • Capítulo 11: Seguridad Moderna en RHEL 9 (detallado)
  • Capítulo 12: Características Actuales de RHEL 10 (detallado)

Tarjeta de Referencia Rápida

┌────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA DE VERSIONES RHEL                        │
├─────────────┬───────────┬──────────────┬───────────────────┤
│ RHEL 7      │ 1.0.2k    │ Manual       │ Amigable legacy   │
│ RHEL 8      │ 1.1.1k    │ Crypto-pols  │ Estándar empresa  │
│ RHEL 9      │ 3.5.5     │ OpenSSL 3.x  │ Moderno seguro    │
│ RHEL 10     │ 3.5.5     │ Fortalecido  │ Preparado futuro  │
└─────────────┴───────────┴──────────────┴───────────────────┘

Verificar versión:   cat /etc/redhat-release
Verificar OpenSSL:   openssl version
Verificar política:  update-crypto-policies --show  (RHEL 8+)

Navegación del Capítulo

Capítulo 9: Gestión de Certificados en RHEL 7

Legado pero Importante: RHEL 7 alcanzó el fin de mantenimiento en junio de 2024, pero muchas empresas aún lo ejecutan. Aprende cómo funciona la gestión de certificados en RHEL 7.


9.1 Resumen de RHEL 7

Lanzamiento: 10 de junio de 2014 Fin de Soporte de Mantenimiento: 30 de junio de 2024 Soporte de Ciclo de Vida Extendido: Disponible hasta 2028

Características Clave:

  • Versión OpenSSL: 1.0.2k-26 (paquete: openssl-1.0.2k-26.el7_9.x86_64)
  • TLS Por Defecto: TLS 1.0, 1.1, 1.2 todos habilitados
  • Almacén de Confianza: /etc/pki/ca-trust/extracted/
  • Enfoque de Gestión: Principalmente manual
  • Crypto-Policies: No disponible (característica de RHEL 8+)

Nota: Si aún estás en RHEL 7, planifica la migración a RHEL 8 o 9. Las actualizaciones de seguridad son limitadas.


9.2 Especificaciones de OpenSSL 1.0.2k

Verificación de Versión

# Verificar versión de OpenSSL en RHEL 7
openssl version
# OpenSSL 1.0.2k-fips  12 Jan 2017

# Verificar paquete
rpm -q openssl
# openssl-1.0.2k-26.el7_9.x86_64

Características y Limitaciones Clave

Características:

  • ✅ Soporte TLS 1.0, 1.1, 1.2
  • ✅ Estable y bien probado
  • ✅ Amplia compatibilidad
  • ✅ Tipos de clave RSA, ECC, DSA

Limitaciones:

  • ❌ Sin soporte TLS 1.3
  • ❌ Sintaxis de comando antigua (genrsa vs genpkey)
  • ❌ Cifrados predeterminados más débiles
  • ❌ Suites de cifrado modernas limitadas

Sintaxis de Comandos (Estilo RHEL 7)

#============================================#
# GENERAR CLAVE RSA (RHEL 7)
#============================================#

# Estilo antiguo (común en RHEL 7)
openssl genrsa -out server.key 2048

# Con protección de frase de contraseña
openssl genrsa -aes256 -out server.key 2048

# Eliminar frase de contraseña de clave
openssl rsa -in server.key -out server-nopass.key


#============================================#
# GENERAR CSR (RHEL 7)
#============================================#

# CSR básico
openssl req -new -key server.key -out server.csr

# Con sujeto especificado
openssl req -new -key server.key -out server.csr \
  -subj "/C=US/ST=State/L=City/O=Company/CN=server.example.com"

# ⚠️ Nota: Los SANs son más difíciles de agregar con OpenSSL de RHEL 7
# Se necesita archivo de configuración para SANs


#============================================#
# VER CERTIFICADO
#============================================#

# Detalles completos
openssl x509 -in server.crt -noout -text

# Solo expiración
openssl x509 -in server.crt -noout -dates

# Solo sujeto
openssl x509 -in server.crt -noout -subject

9.3 Gestión del Almacén de Confianza en RHEL 7

Agregar CAs Personalizadas

#============================================#
# AGREGAR CA PERSONALIZADA (RHEL 7)
#============================================#

# Paso 1: Copiar certificado CA al directorio de anchors
sudo cp corporate-ca.crt /etc/pki/ca-trust/source/anchors/

# Paso 2: Actualizar almacén de confianza
sudo update-ca-trust extract

# Paso 3: Verificar
trust list | grep -i "corporate"

# Verificar que las aplicaciones lo usen
openssl verify -CAfile /etc/pki/tls/certs/ca-bundle.crt test-cert.crt

Ubicaciones del Almacén de Confianza (RHEL 7)

/etc/pki/ca-trust/
├── source/
│   └── anchors/                   ← Agregar CAs personalizadas aquí
│
└── extracted/
    ├── pem/
    │   └── tls-ca-bundle.pem      ← OpenSSL, Python, Ruby
    ├── openssl/
    │   └── ca-bundle.trust.crt    ← Específico de OpenSSL
    └── java/
        └── cacerts                ← Aplicaciones Java

9.4 Configuración de Servicios (Enfoque RHEL 7)

Apache HTTPS en RHEL 7

#============================================#
# CONFIGURACIÓN SSL/TLS DE APACHE (RHEL 7)
#============================================#

# Instalar Apache con SSL
sudo yum install httpd mod_ssl -y

# Generar certificado y clave
sudo openssl genrsa -out /etc/pki/tls/private/server.key 2048
sudo openssl req -new -key /etc/pki/tls/private/server.key \
  -out /tmp/server.csr \
  -subj "/CN=$(hostname -f)"

# Obtener certificado de CA (o autofirmado para pruebas)
sudo openssl x509 -req -days 365 -in /tmp/server.csr \
  -signkey /etc/pki/tls/private/server.key \
  -out /etc/pki/tls/certs/server.crt

# Configurar Apache (/etc/httpd/conf.d/ssl.conf)
sudo vi /etc/httpd/conf.d/ssl.conf
# Establecer:
#   SSLCertificateFile /etc/pki/tls/certs/server.crt
#   SSLCertificateKeyFile /etc/pki/tls/private/server.key
#
#   # Recomendado: Deshabilitar versiones TLS débiles
#   SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
#
#   # Recomendado: Solo cifrados fuertes
#   SSLCipherSuite HIGH:!aNULL:!MD5:!3DES:!RC4

# Iniciar Apache
sudo systemctl enable httpd
sudo systemctl start httpd

# Probar
curl -vk https://localhost/

NGINX en RHEL 7

#============================================#
# CONFIGURACIÓN SSL/TLS DE NGINX (RHEL 7)
#============================================#

# Instalar NGINX (desde EPEL)
sudo yum install epel-release -y
sudo yum install nginx -y

# Generar certificado
sudo openssl genrsa -out /etc/pki/tls/private/nginx.key 2048
sudo openssl req -new -x509 -days 365 \
  -key /etc/pki/tls/private/nginx.key \
  -out /etc/pki/tls/certs/nginx.crt \
  -subj "/CN=$(hostname -f)"

# Configurar NGINX (/etc/nginx/nginx.conf)
# Agregar al bloque de servidor:
#   listen 443 ssl;
#   ssl_certificate /etc/pki/tls/certs/nginx.crt;
#   ssl_certificate_key /etc/pki/tls/private/nginx.key;
#
#   # Recomendado
#   ssl_protocols TLSv1.2;
#   ssl_ciphers HIGH:!aNULL:!MD5;

# Iniciar NGINX
sudo systemctl enable nginx
sudo systemctl start nginx

9.5 Renovación Manual de Certificados (RHEL 7)

Sin crypto-policies, sin herramientas automáticas - ¡todo es manual!

Proceso de Renovación

#============================================#
# PROCESO DE RENOVACIÓN MANUAL (RHEL 7)
#============================================#

# Paso 1: Verificar expiración (configurar recordatorio de calendario)
openssl x509 -in /etc/pki/tls/certs/server.crt -noout -dates

# Paso 2: Generar nuevo CSR (reutilizar clave existente)
openssl req -new -key /etc/pki/tls/private/server.key \
  -out /tmp/server-renewal.csr \
  -subj "/CN=server.example.com"

# Paso 3: Enviar CSR a CA

# Paso 4: Recibir nuevo certificado de CA

# Paso 5: Hacer respaldo del certificado antiguo
sudo cp /etc/pki/tls/certs/server.crt \
     /etc/pki/tls/certs/server.crt.$(date +%Y%m%d).old

# Paso 6: Instalar nuevo certificado
sudo cp new-server.crt /etc/pki/tls/certs/server.crt
sudo chmod 644 /etc/pki/tls/certs/server.crt

# Paso 7: Recargar servicio
sudo systemctl reload httpd

# Paso 8: Probar
curl -v https://localhost/
openssl s_client -connect localhost:443

Rastrear Renovaciones de Certificados

#============================================#
# CREAR RASTREO DE RENOVACIÓN (RHEL 7)
#============================================#

# Tarea cron para verificar expiración
cat > /etc/cron.weekly/check-cert-expiration << 'EOF'
#!/bin/bash
# Verificar certificados que expiran en 60 días

for cert in /etc/pki/tls/certs/*.crt; do
  [ -f "$cert" ] || continue

  if ! openssl x509 -in "$cert" -noout -checkend $((86400*60)); then
    echo "⚠️ $cert expira dentro de 60 días!"
    echo "$cert" | mail -s "Certificado Expirando Pronto" admin@example.com
  fi
done
EOF

chmod +x /etc/cron.weekly/check-cert-expiration

9.6 Problemas Comunes de Certificados en RHEL 7

Problema 1: TLS 1.0/1.1 Obsoleto

Problema: Los clientes modernos rechazan TLS 1.0/1.1

Síntomas:

curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure

Solución:

# Actualizar Apache para deshabilitar versiones TLS antiguas
# /etc/httpd/conf.d/ssl.conf
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1

# Reiniciar Apache
sudo systemctl restart httpd

Problema 2: Cifrados Débiles

Problema: Los escaneos PCI/Seguridad marcan cifrados débiles

Solución:

# Apache: Usar solo cifrados fuertes
# /etc/httpd/conf.d/ssl.conf
SSLCipherSuite HIGH:!aNULL:!MD5:!3DES:!RC4:!EXPORT
SSLHonorCipherOrder on

# Probar
openssl s_client -connect localhost:443 -cipher '3DES'
# Debería fallar si 3DES está deshabilitado

Problema 3: SANs Faltantes

Problema: Los navegadores modernos requieren Subject Alternative Names

Desafío RHEL 7: Los SANs son más difíciles de agregar con OpenSSL 1.0.2

Solución: Usar archivo de configuración

# Crear configuración OpenSSL
cat > /tmp/san.cnf << EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req

[req_distinguished_name]
CN = server.example.com

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = server.example.com
DNS.2 = www.example.com
IP.1 = 10.0.0.100
EOF

# Generar CSR con SANs
openssl req -new -key server.key -out server.csr -config /tmp/san.cnf

# Verificar SANs en CSR
openssl req -in server.csr -noout -text | grep -A3 "Subject Alternative Name"

9.7 certmonger en RHEL 7

Disponible: Sí (versión básica)

#============================================#
# CERTMONGER EN RHEL 7
#============================================#

# Instalar
sudo yum install certmonger -y
sudo systemctl enable certmonger
sudo systemctl start certmonger

# Solicitar certificado de FreeIPA
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/web.crt \
  -k /etc/pki/tls/private/web.key \
  -K host/$(hostname -f)@REALM

# Listar certificados rastreados
sudo getcert list

# Verificar estado de certificado específico
sudo getcert list -f /etc/pki/tls/certs/web.crt

# Monitorear logs de certmonger
sudo tail -f /var/log/messages | grep certmonger

Limitaciones de RHEL 7:

  • Sin soporte ACME (Let’s Encrypt requiere certbot manual)
  • Salida de estado menos detallada
  • Menos opciones de comandos post-guardado

9.8 Consideraciones de Migración

Cuándo Migrar desde RHEL 7

Deberías migrar si:

  • ✅ El soporte terminó (junio 2024) y necesitas actualizaciones
  • ✅ Necesitas soporte TLS 1.3
  • ✅ Quieres crypto-policies para gestión más fácil
  • ✅ Requieres características de seguridad modernas
  • ✅ El cumplimiento requiere SO soportado

Tareas de Certificados Pre-Migración

#============================================#
# AUDITORÍA DE CERTIFICADOS PRE-MIGRACIÓN RHEL 7
#============================================#

# 1. Listar todos los certificados
find /etc/pki/tls/ -name "*.crt" -o -name "*.key"

# 2. Verificar expiraciones
for cert in /etc/pki/tls/certs/*.crt; do
  echo "=== $cert ==="
  openssl x509 -in "$cert" -noout -subject -dates
  echo ""
done

# 3. Verificar algoritmos de firma (SHA-1 no funcionará en RHEL 8+)
for cert in /etc/pki/tls/certs/*.crt; do
  SIG=$(openssl x509 -in "$cert" -noout -text | grep "Signature Algorithm" | head -2)
  echo "$cert: $SIG"
done | grep -i sha1
# ¡Si se encuentra alguno, reemitir antes de migración!

# 4. Documentar CAs personalizadas
ls -l /etc/pki/ca-trust/source/anchors/

# 5. Exportar certificados y claves
tar czf rhel7-certificates-backup-$(date +%Y%m%d).tar.gz \
  /etc/pki/tls/certs/*.crt \
  /etc/pki/tls/private/*.key \
  /etc/pki/ca-trust/source/anchors/*

9.9 Flujos de Trabajo Comunes en RHEL 7

Flujo de Trabajo 1: Configuración Manual de Apache HTTPS

# Flujo de trabajo completo desde cero

# 1. Instalar Apache con SSL
sudo yum install httpd mod_ssl -y

# 2. Generar clave privada
sudo openssl genrsa -out /etc/pki/tls/private/$(hostname -s).key 2048

# 3. Establecer permisos de clave
sudo chmod 600 /etc/pki/tls/private/$(hostname -s).key

# 4. Crear CSR
sudo openssl req -new \
  -key /etc/pki/tls/private/$(hostname -s).key \
  -out /tmp/$(hostname -s).csr \
  -subj "/C=US/O=Company/CN=$(hostname -f)"

# 5. Enviar CSR a CA, esperar certificado

# 6. Instalar certificado
sudo cp $(hostname -s).crt /etc/pki/tls/certs/

# 7. Configurar Apache
sudo vi /etc/httpd/conf.d/ssl.conf
# Editar:
#   SSLCertificateFile /etc/pki/tls/certs/$(hostname -s).crt
#   SSLCertificateKeyFile /etc/pki/tls/private/$(hostname -s).key
#   SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
#   SSLCipherSuite HIGH:!aNULL:!MD5:!3DES

# 8. Probar configuración
sudo apachectl configtest

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

# 10. Iniciar Apache
sudo systemctl enable httpd
sudo systemctl start httpd

# 11. Probar
curl -vk https://$(hostname -f)/

Flujo de Trabajo 2: Integración con FreeIPA

#============================================#
# FLUJO DE TRABAJO DE CERTIFICADO FREEIPA (RHEL 7)
#============================================#

# Prerrequisitos: El sistema debe estar inscrito en IPA
ipa-client-install

# Instalar certmonger
sudo yum install certmonger -y
sudo systemctl enable certmonger
sudo systemctl start certmonger

# Solicitar certificado para Apache
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/$(hostname -s).crt \
  -k /etc/pki/tls/private/$(hostname -s).key \
  -K host/$(hostname -f)@REALM.EXAMPLE.COM \
  -D $(hostname -f)

# Verificar estado
sudo getcert list

# Esperar estado MONITORING (certificado emitido)

# Configurar Apache para usar cert
# /etc/httpd/conf.d/ssl.conf

# Recargar Apache cuando el cert se renueve
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/$(hostname -s).crt \
  -k /etc/pki/tls/private/$(hostname -s).key \
  -K host/$(hostname -f)@REALM \
  -C "systemctl reload httpd"

9.10 Solución de Problemas de Certificados en RHEL 7

Comandos de Diagnóstico

#============================================#
# DIAGNÓSTICO DE CERTIFICADOS RHEL 7
#============================================#

# Verificar versión de OpenSSL
openssl version

# Probar HTTPS localmente
openssl s_client -connect localhost:443

# Verificar configuración SSL de Apache
sudo apachectl -t -D DUMP_VHOSTS | grep 443

# Ver errores SSL de Apache
sudo tail -f /var/log/httpd/ssl_error_log

# Verificar denegaciones SELinux
sudo grep AVC /var/log/audit/audit.log | grep cert

# Verificar permisos de archivos
ls -lZ /etc/pki/tls/certs/*.crt
ls -lZ /etc/pki/tls/private/*.key

# Verificar par certificado/clave
openssl x509 -noout -modulus -in /etc/pki/tls/certs/server.crt | openssl md5
openssl rsa -noout -modulus -in /etc/pki/tls/private/server.key | openssl md5
# Los hashes MD5 deberían coincidir

Errores Comunes de RHEL 7

ErrorCausaSolución
“certificate verify failed”CA faltante en almacén de confianzaAgregar CA a /etc/pki/ca-trust/source/anchors/
“permission denied” en clavePermisos incorrectoschmod 600 en archivo .key
“certificate has expired”Certificado expiradoRenovar certificado manualmente
“no shared cipher”Desajuste de cifrado cliente/servidorActualizar SSLCipherSuite
“wrong version number”Desajuste de versión TLSActualizar SSLProtocol

9.11 Fortalecimiento de Seguridad en RHEL 7

Configuración Recomendada

#============================================#
# ENDURECIMIENTO SSL/TLS DE APACHE (RHEL 7)
#============================================#

# /etc/httpd/conf.d/ssl.conf

# Deshabilitar protocolos antiguos
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1

# Solo cifrados fuertes
SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!3DES:!DES

# Honrar preferencia de cifrado del servidor
SSLHonorCipherOrder on

# Habilitar HSTS (HTTP Strict Transport Security)
Header always set Strict-Transport-Security "max-age=31536000"

# OCSP Stapling (no disponible en OpenSSL 1.0.2 de RHEL 7 por defecto)
# Disponible en algunos backports

# Perfect Forward Secrecy
SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256

9.12 Ruta de Migración a RHEL 8+

Pasos de Migración Específicos de Certificados

#============================================#
# PREPARAR CERTIFICADOS PARA MIGRACIÓN
#============================================#

# 1. Verificar que todos los certificados usen SHA-256+ (sin SHA-1 ni MD5)
for cert in /etc/pki/tls/certs/*.crt; do
  openssl x509 -in "$cert" -noout -text | grep "Signature Algorithm"
done | grep -i sha1 && echo "⚠️ ¡Certificados SHA-1 encontrados! ¡Reemitir antes de migración!"

# 2. Verificar tamaños de clave (2048+ bits)
for cert in /etc/pki/tls/certs/*.crt; do
  SIZE=$(openssl x509 -in "$cert" -noout -text | grep "Public-Key" | grep -oP '\d+')
  if [ "$SIZE" -lt 2048 ]; then
    echo "⚠️ $cert: Clave muy pequeña ($SIZE bits)"
  fi
done

# 3. Respaldar todo
tar czf rhel7-certs-$(hostname)-$(date +%Y%m%d).tar.gz \
  /etc/pki/tls/ \
  /etc/pki/ca-trust/source/anchors/ \
  /etc/httpd/conf.d/ssl.conf \
  /etc/nginx/nginx.conf

# 4. Documentar inventario de certificados
./generate-cert-inventory.sh > cert-inventory-pre-migration.csv

# 5. Probar compatibilidad TLS 1.2
# Asegurar que todos los servicios funcionen solo con TLS 1.2

9.13 Cuándo RHEL 7 Tiene Sentido

¿Aún Usando RHEL 7? Considera:

Razones para Quedarse (Temporalmente):

  • Contrato de Soporte de Ciclo de Vida Extendido activo
  • Aplicaciones legacy críticas que requieren TLS 1.0/1.1
  • Migración planificada para futuro cercano
  • Probando RHEL 8/9 en paralelo

Razones para Migrar:

  • ✅ Mantenimiento extendido terminó en junio 2024
  • ✅ Sin crypto-policies (más difícil de gestionar)
  • ✅ Sin TLS 1.3
  • ✅ Actualizaciones de seguridad limitadas
  • ✅ Aplicaciones modernas dejando de soportar TLS 1.0/1.1

9.14 Conclusiones Clave

  1. RHEL 7 es manual - Sin crypto-policies, se necesita configuración cuidadosa
  2. OpenSSL 1.0.2k - Sintaxis antigua, sin TLS 1.3
  3. TLS 1.0/1.1 habilitado por defecto - Deshabilitarlos manualmente
  4. SHA-1 aún funciona - Pero no después de migración a RHEL 8+
  5. certmonger disponible - Pero básico comparado con RHEL 8+
  6. Planificar migración - El soporte de RHEL 7 está terminando
  7. Documentar todo - Facilita la migración

Referencia Rápida

┌─────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA DE CERTIFICADOS RHEL 7                │
├─────────────────────────────────────────────────────────┤
│ OpenSSL:     1.0.2k-26                                  │
│ TLS:         1.0, 1.1, 1.2 (no 1.3)                     │
│ Política:    Configuración manual (sin crypto-policies) │
│                                                         │
│ Generar:     openssl genrsa -out key.pem 2048           │
│ CSR:         openssl req -new -key key.pem -out req.csr │
│ Ver:         openssl x509 -in cert.crt -noout -text     │
│ Probar:      openssl s_client -connect host:443         │
│                                                         │
│ Fortalecer:  SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1     │
│              SSLCipherSuite HIGH:!aNULL:!MD5:!3DES      │
└─────────────────────────────────────────────────────────┘

Navegación del Capítulo

Capítulo 10: RHEL 8 y Crypto-Policies

Cambio de Juego: RHEL 8 introdujo crypto-policies, revolucionando cómo se gestionan certificados y criptografía en todo el sistema. Esta es la característica más importante que debes entender para RHEL 8.


10.1 ¿Qué Cambió en RHEL 8?

Lanzamiento: 7 de mayo de 2019 Soporte Hasta: 31 de mayo de 2029 Versión Actual: RHEL 8.10 (a partir de 2024)

Cambios Principales Relacionados con Certificados:

CaracterísticaRHEL 7RHEL 8
OpenSSL1.0.2k1.1.1k-14
TLS 1.3❌ No✅ Sí
Crypto-Policies❌ No¡NUEVO!
TLS 1.0/1.1✅ Habilitado❌ Deshabilitado (DEFAULT)
certmongerBásicoMejorado
Seguridad PredeterminadaMixtaMás Fuerte

Paquete: openssl-1.1.1k-14.el8_6.x86_64


10.2 Entender Crypto-Policies

La Idea Revolucionaria

Problema RHEL 7:

❌ Configurar Apache:     SSLProtocol, SSLCipherSuite
❌ Configurar NGINX:      ssl_protocols, ssl_ciphers
❌ Configurar Postfix:    smtpd_tls_protocols
❌ Configurar OpenLDAP:   olcTLSProtocolMin
❌ ¡Configurar cada aplicación de manera diferente!

Solución RHEL 8:

✅ Establecer UNA política en todo el sistema
✅ ¡Todas las aplicaciones cumplen automáticamente!

Cómo Funciona

┌────────────────────────────────────────┐
│  update-crypto-policies --set DEFAULT  │  ← Comando único
└──────────────────┬─────────────────────┘
                   │
      ┌────────────┴────────────┐
      │ Sistema Crypto-Policies │
      └────────────┬────────────┘
                   │
    ┌──────────────┼──────────────┐
    ▼              ▼              ▼
 OpenSSL        GnuTLS         NSS
 Postfix        Apache         NGINX
 OpenSSH        Kerberos       BIND
 (¡todas apps!) (¡automático!) (¡consistente!)

10.3 Crypto-Policies Disponibles

Las Cuatro Políticas Principales

# Verificar política actual
update-crypto-policies --show

# Políticas disponibles en RHEL 8:
PolíticaVersiones TLSRSA MínSHA-13DESCaso de Uso
DEFAULT1.2, 1.32048❌ No❌ NoEstándar (recomendado)
LEGACY1.0+, todas1024⚠️ Sí⚠️ SíCompatibilidad sistemas antiguos
FUTURE1.2, 1.33072❌ No❌ NoSeguridad más estricta
FIPS1.2, 1.32048❌ No❌ NoCumplimiento federal

Detalles de Políticas

Política DEFAULT:

Versiones TLS: 1.2, 1.3
RSA/DH Mínimo: 2048 bits
ECC Mínimo: secp256r1 (P-256)
Cifrados: AES-GCM, ChaCha20-Poly1305, AES-CBC
Firmas: SHA-256, SHA-384, SHA-512
Bloqueados: MD5, firmas SHA-1, 3DES, RC4, DSS

Política LEGACY:

Versiones TLS: 1.0, 1.1, 1.2, 1.3
RSA/DH Mínimo: 1024 bits
Cifrados: Incluye 3DES, cifrados débiles
Firmas: Permite SHA-1
Uso: Solo para compatibilidad con sistemas antiguos (¡temporal!)

Política FUTURE:

Versiones TLS: 1.2, 1.3 (cifrados más estrictos)
RSA/DH Mínimo: 3072 bits
ECC Mínimo: secp384r1 (P-384)
Firmas: SHA-384, SHA-512 preferidos
Bloqueados: Todo en DEFAULT, más otros

Política FIPS:

Versiones TLS: 1.2, 1.3
Algoritmos: Solo aprobados FIPS 140-2
Requiere: Modo FIPS habilitado
Más estricto: Requisitos de cumplimiento federal

10.4 Cambiar Crypto-Policies

Cambios Básicos de Política

#============================================#
# VER POLÍTICA ACTUAL
#============================================#

update-crypto-policies --show
# DEFAULT


#============================================#
# ESTABLECER POLÍTICA
#============================================#

# Establecer a FUTURE (más estricto)
sudo update-crypto-policies --set FUTURE

# Establecer a LEGACY (menos seguro, para compatibilidad)
sudo update-crypto-policies --set LEGACY

# Establecer a FIPS (requiere modo FIPS habilitado)
sudo fips-mode-setup --enable
sudo reboot
sudo update-crypto-policies --set FIPS

# Volver a DEFAULT
sudo update-crypto-policies --set DEFAULT


#============================================#
# APLICAR POLÍTICA (reiniciar servicios)
#============================================#

# Crypto-policies actualiza archivos de configuración, pero los servicios deben reiniciarse
sudo systemctl restart httpd nginx postfix

# O reiniciar (asegura que todo use la nueva política)
sudo reboot

Qué Sucede Cuando Cambias la Política

# Ejemplo: Cambiar a política FUTURE

# Antes:
update-crypto-policies --show
# DEFAULT

# Después:
sudo update-crypto-policies --set FUTURE

# Los cambios ocurren en:
ls -l /etc/crypto-policies/back-ends/
# opensslcnf.config      ← Configuración OpenSSL actualizada
# gnutls.config          ← Configuración GnuTLS actualizada
# nss.config             ← Configuración NSS actualizada
# bind.config            ← Configuración BIND actualizada
# ... y más

# Ver política OpenSSL aplicada:
cat /etc/crypto-policies/back-ends/opensslcnf.config

10.5 Impacto de la Política en Certificados

Impacto de la Política DEFAULT

#============================================#
# QUÉ PERMITE/BLOQUEA LA POLÍTICA DEFAULT
#============================================#

# ✅ PERMITIDO:
- TLS 1.2, 1.3
- RSA 2048+ bits
- AES-128-GCM, AES-256-GCM
- ChaCha20-Poly1305
- Firmas SHA-256, SHA-384, SHA-512

# ❌ BLOQUEADO:
- TLS 1.0, 1.1
- RSA < 2048 bits
- 3DES, RC4, DES
- Firmas MD5, SHA-1
- Claves DSA
- Cifrados de exportación

Probar Contra la Política Actual

#============================================#
# PROBAR SI TU CERTIFICADO FUNCIONA
#============================================#

# Probar TLS 1.2
openssl s_client -connect server.example.com:443 -tls1_2

# Probar TLS 1.3
openssl s_client -connect server.example.com:443 -tls1_3

# Probar cifrado específico
openssl s_client -connect server.example.com:443 \
  -cipher 'ECDHE-RSA-AES256-GCM-SHA384'

# Ver qué cifrados están disponibles bajo la política actual
openssl ciphers -v | head -20

10.6 Características de OpenSSL 1.1.1 (RHEL 8)

Nuevas Características

#============================================#
# SOPORTE TLS 1.3 (¡Nuevo en RHEL 8!)
#============================================#

# Probar TLS 1.3
openssl s_client -connect server.example.com:443 -tls1_3

# Beneficios de TLS 1.3:
# - Handshake más rápido
# - Forward secrecy obligatorio
# - Características obsoletas eliminadas


#============================================#
# GENERACIÓN DE CLAVES MODERNA
#============================================#

# Estilo antiguo (aún funciona)
openssl genrsa -out server.key 2048

# Estilo nuevo (preferido en RHEL 8)
openssl genpkey -algorithm RSA -out server.key \
  -pkeyopt rsa_keygen_bits:2048

# Claves EC (curva elíptica)
openssl genpkey -algorithm EC -out ec.key \
  -pkeyopt ec_paramgen_curve:P-256


#============================================#
# GENERACIÓN DE CSR MEJORADA
#============================================#

# CSR con SANs (¡mucho más fácil que RHEL 7!)
openssl req -new -key server.key -out server.csr \
  -subj "/CN=server.example.com" \
  -addext "subjectAltName=DNS:server.example.com,DNS:www.example.com,IP:10.0.0.100"

# Verificar SANs
openssl req -in server.csr -noout -text | grep -A2 "Subject Alternative Name"

10.7 Mejoras de certmonger en RHEL 8

Características Mejoradas

#============================================#
# CERTMONGER EN RHEL 8
#============================================#

# Mejor integración con IPA
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/web.crt \
  -k /etc/pki/tls/private/web.key \
  -D web.example.com \
  -K host/web.example.com@REALM \
  -C "systemctl reload httpd"  # ¡Comando post-guardado (mejorado!)

# Salida de estado mejorada
sudo getcert list -v

# Mejor reporte de errores
sudo getcert list -f /etc/pki/tls/certs/web.crt
# Muestra mensajes de error detallados si la renovación falla

Mejoras de certmonger en RHEL 8:

  • ✅ Mejores mensajes de error
  • ✅ Soporte de comando post-guardado
  • ✅ Integración mejorada con IPA
  • ✅ Renovación más confiable

10.8 Escenarios Comunes en RHEL 8

Escenario 1: Migrado desde RHEL 7, App TLS 1.0 Falla

Problema:

# La aplicación funcionaba en RHEL 7
# Después de migración a RHEL 8: fallos de conexión

Diagnóstico:

# Verificar crypto-policy
update-crypto-policies --show
# DEFAULT  ← ¡TLS 1.0/1.1 deshabilitado!

# Verificar logs de aplicación
journalctl -xe | grep -i tls
# "wrong version number" o "no shared cipher"

Solución Rápida (Temporal):

# Usar política LEGACY para permitir TLS 1.0/1.1
sudo update-crypto-policies --set LEGACY
sudo systemctl restart <service>

Solución Apropiada:

# Actualizar aplicación para soportar TLS 1.2+
# O configurar aplicación específicamente (optar por no usar política)

Escenario 2: Necesidad de Soportar Clientes Antiguos

Problema: Clientes Windows Server 2008, Java 7 no pueden conectarse

Solución:

# Opción 1: Política LEGACY (no recomendado a largo plazo)
sudo update-crypto-policies --set LEGACY

# Opción 2: Módulo de política personalizada
# Crear /etc/crypto-policies/policies/modules/COMPAT-OLD-CLIENTS.pmod
sudo update-crypto-policies --set DEFAULT:COMPAT-OLD-CLIENTS

# Opción 3: Optar por no usar política en servicio específico
# Configurar ese servicio para permitir TLS 1.0/1.1

Escenario 3: Probar Antes de Producción

#============================================#
# PROBAR IMPACTO DE CRYPTO-POLICY
#============================================#

# Política actual
CURRENT=$(update-crypto-policies --show)

# Probar con política FUTURE
sudo update-crypto-policies --set FUTURE
sudo systemctl restart httpd

# Ejecutar pruebas
curl https://localhost/
# Suite de pruebas de aplicación

# Si hay problemas:
sudo update-crypto-policies --set $CURRENT  # Revertir
sudo systemctl restart httpd

10.9 Sobrescrituras por Aplicación

Cuándo Sobrescribir

A veces necesitas que UNA aplicación opte por no usar la política del sistema:

Ejemplo: La app legacy necesita TLS 1.0, pero quieres DEFAULT para todo lo demás

#============================================#
# SOBRESCRITURA DE APACHE (Optar por No Usar)
#============================================#

# /etc/httpd/conf.d/ssl.conf
# Agregar esto para re-habilitar TLS 1.0 solo para Apache:
SSLProtocol all

# O usar Include para cargar crypto-policy
Include /etc/crypto-policies/back-ends/httpd.config
# Luego sobrescribir ajustes específicos después

# ⚠️ Nota: Esto opta por NO usar crypto-policies para Apache
# Ahora gestionas TLS de Apache manualmente otra vez

Mejor: Usar módulos de política (ver Capítulo 23 para detalles)


10.10 Resolver Problemas de Crypto-Policy

Problemas Comunes

Problema 1: “no shared cipher”

# Diagnóstico
update-crypto-policies --show
# DEFAULT

# Probar qué cifrados están disponibles
openssl ciphers -v

# Verificar solicitud del cliente
openssl s_client -connect localhost:443 -cipher 'ALL'

# Solución: Usar temporalmente LEGACY para identificar problema
sudo update-crypto-policies --set LEGACY
# Si funciona → problema de compatibilidad de cifrado
# Solución apropiada: Actualizar cliente o crear política personalizada

Problema 2: El servicio falla después de cambio de política

# Síntoma
sudo systemctl status httpd
# Failed to start

# Verificar logs
sudo journalctl -xe -u httpd | grep -i tls

# Revertir política
sudo update-crypto-policies --set DEFAULT
sudo systemctl restart httpd

10.11 Mejores Prácticas para RHEL 8

Recomendación: Usar Política DEFAULT

# Para la mayoría de entornos:
sudo update-crypto-policies --set DEFAULT

# Razones:
✅ Seguridad/compatibilidad equilibrada
✅ Probado por Red Hat
✅ Cumple estándares modernos
✅ Bloquea algoritmos débiles conocidos
✅ Funciona con la mayoría de clientes

Cuándo Usar Otras Políticas

Usar LEGACY cuando:

  • Soportar temporalmente clientes muy antiguos
  • Período de migración desde RHEL 7
  • Probar compatibilidad
  • Pero: ¡Planifica volver a DEFAULT lo antes posible!

Usar FUTURE cuando:

  • Requisitos de alta seguridad
  • Todos los clientes son modernos
  • Quieres los ajustes más estrictos
  • Planificación anticipada

Usar FIPS cuando:

  • Se requiere cumplimiento federal
  • Contratos gubernamentales
  • Industrias reguladas
  • Se necesitan certificaciones de seguridad

10.12 Conclusiones Clave (RHEL 8)

  1. Crypto-policies son LA característica - Apréndelas bien
  2. La política DEFAULT es buena - No cambiar sin razón
  3. TLS 1.3 ahora disponible - Más rápido y más seguro
  4. OpenSSL 1.1.1 - Características modernas, mejor sintaxis
  5. certmonger mejorado - Mejor automatización
  6. Migración desde RHEL 7 - Probar exhaustivamente
  7. Planificar para RHEL 9 - OpenSSL 3.x viene

Referencia Rápida

┌────────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA CRYPTO-POLICIES RHEL 8                       │
├────────────────────────────────────────────────────────────────┤
│ OpenSSL:         1.1.1k-14                                     │
│ TLS:             1.2, 1.3 (política DEFAULT)                   │
│ Característica:  Crypto-policies en todo el sistema            │
│                                                                │
│ Ver política:    update-crypto-policies --show                 │
│ Establecer:      sudo update-crypto-policies --set <POLICY>    │
│ Políticas:       DEFAULT, LEGACY, FUTURE, FIPS                 │
│                                                                │
│ Archivos config: /etc/crypto-policies/back-ends/               │
│ Reiniciar:       systemctl restart <services>                  │
│                                                                │
│ Generar clave:   openssl genpkey -algorithm RSA -out key.pem   │
│ CSR con SANs:    openssl req -new -addext "subjectAltName=..." │
└────────────────────────────────────────────────────────────────┘

Navegación del Capítulo

Capítulo 11: Seguridad Moderna en RHEL 9

Estándar Moderno: RHEL 9 representa el estado del arte actual en gestión de certificados en Linux con OpenSSL 3.x, crypto-policies mejoradas y valores predeterminados de seguridad más estrictos.


11.1 Resumen de RHEL 9

Lanzamiento: 17 de mayo de 2022 Soporte Hasta: 31 de mayo de 2032 Versión Actual: RHEL 9.8

Cambios Principales desde RHEL 8:

CaracterísticaRHEL 8RHEL 9
OpenSSL1.1.1k3.5.5
ArquitecturaTradicionalBasada en proveedores
TLS 1.0/1.1Política LEGACYCompletamente eliminado
Crypto-PoliciesBásicasSubpolíticas
ValidaciónEstándarMás Estricta
SHA-1ObsoletoBloqueado
certmongerMejoradoFlujos nativos de IPA y seguimiento

Paquete: openssl-3.5.5-2.el9_8.x86_64


11.2 OpenSSL 3.5.5 - Cambios Principales

Arquitectura de Proveedores (¡Nuevo!)

Qué Cambió: OpenSSL 3.x introdujo un sistema de “proveedores” para diferentes implementaciones crypto.

#============================================#
# LISTAR PROVEEDORES (RHEL 9)
#============================================#

openssl list -providers

# Salida:
# Providers:
#   default
#     name: OpenSSL Default Provider
#     version: 3.5.5
#     status: active
#
#   fips
#     name: OpenSSL FIPS Provider
#     version: 3.5.5
#     status: inactive (a menos que modo FIPS habilitado)
#
#   legacy
#     name: OpenSSL Legacy Provider
#     version: 3.5.5
#     status: inactive
#
#   base
#     name: OpenSSL Base Provider
#     version: 3.5.5
#     status: active

Los Algoritmos Legacy Requieren Proveedor Explícito

Cambio Incompatible: MD5, Blowfish, CAST5 necesitan -provider legacy

#============================================#
# USAR ALGORITMOS LEGACY (RHEL 9)
#============================================#

# Esto FALLA en RHEL 9:
openssl md5 file.txt
# Error: unsupported

# Esto FUNCIONA (proveedor explícito):
openssl md5 -provider legacy file.txt

# Por qué: Algoritmos legacy deshabilitados por defecto por seguridad

Generación Moderna de Claves (RHEL 9)

#============================================#
# GENERAR CLAVES (RHEL 9)
#============================================#

# RSA 2048 (estándar)
openssl genpkey -algorithm RSA -out server.key \
  -pkeyopt rsa_keygen_bits:2048

# RSA 4096 (más fuerte)
openssl genpkey -algorithm RSA -out server.key \
  -pkeyopt rsa_keygen_bits:4096

# EC P-256 (curva elíptica, recomendado)
openssl genpkey -algorithm EC -out ec.key \
  -pkeyopt ec_paramgen_curve:P-256

# EC P-384 (más fuerte)
openssl genpkey -algorithm EC -out ec.key \
  -pkeyopt ec_paramgen_curve:P-384


#============================================#
# GENERAR CSR CON SANS (RHEL 9)
#============================================#

openssl req -new -key server.key -out server.csr \
  -subj "/C=US/ST=State/O=Company/CN=server.example.com" \
  -addext "subjectAltName=DNS:server.example.com,DNS:www.example.com,IP:10.0.0.100" \
  -addext "keyUsage=digitalSignature,keyEncipherment" \
  -addext "extendedKeyUsage=serverAuth,clientAuth"

# Verificar
openssl req -in server.csr -noout -text | grep -A5 "Subject Alternative Name"

11.3 Crypto-Policies Mejoradas (RHEL 9)

Subpolíticas (¡Nueva Característica!)

RHEL 9 introduce modificadores de política:

#============================================#
# SUBPOLÍTICAS DE CRYPTO-POLICY (RHEL 9)
#============================================#

# Política base con módulo NO-SHA1
sudo update-crypto-policies --set DEFAULT:NO-SHA1

# Múltiples módulos
sudo update-crypto-policies --set DEFAULT:NO-SHA1:GOST

# Subpolíticas comunes:
# - NO-SHA1: Deshabilitar completamente SHA-1 (incluso en firmas)
# - NO-ENFORCE-EMS: Deshabilitar Extended Master Secret
# - GOST: Habilitar algoritmos GOST
# - NO-CAMELLIA: Deshabilitar cifrado Camellia

# Ver módulos disponibles
ls /usr/share/crypto-policies/policies/modules/

Módulos Personalizados de Crypto-Policy (RHEL 9)

#============================================#
# CREAR MÓDULO DE POLÍTICA PERSONALIZADO
#============================================#

# Crear módulo personalizado
sudo vi /etc/crypto-policies/policies/modules/CUSTOM.pmod

# Contenido de ejemplo:
min_rsa_size = 3072
min_dh_size = 3072
min_dsa_size = 3072

# Aplicar
sudo update-crypto-policies --set DEFAULT:CUSTOM

# Probar
openssl ciphers -v | head

11.4 Validación de Certificados Más Estricta

¿Qué es Más Estricto en RHEL 9?

#============================================#
# EJEMPLOS DE VALIDACIÓN MÁS ESTRICTA
#============================================#

# 1. Firmas SHA-1 completamente rechazadas
openssl verify sha1-signed-cert.crt
# Error: CA md too weak

# 2. Autofirmados sin confianza CA apropiada rechazados
curl https://self-signed.example.com/
# Error: certificate verify failed

# 3. La cadena de certificados debe estar completa
# Intermedio faltante → conexión falla

# 4. El hostname debe coincidir (CN o SAN)
openssl s_client -connect server.example.com:443 -servername different.example.com
# Verification error: hostname mismatch

# 5. Claves < 2048 bits rechazadas
# (incluso en política LEGACY, < 1024 rechazadas)

Impacto en Aplicaciones

Aplicaciones compiladas contra OpenSSL 3.x:

  • Pueden necesitar cambios de código si usan APIs obsoletas
  • El manejo de errores puede ser diferente
  • El código crypto personalizado necesita pruebas

Administradores de sistema:

  • ✅ La mayoría de cambios transparentes
  • ✅ Los comandos son mayormente iguales
  • ⚠️ La validación más estricta captura más problemas (¡esto es bueno!)

11.5 Automatización en RHEL 9: certmonger, certbot e IdM ACME

Usa el cliente correcto para la CA correcta

#============================================#
# OPCIONES DE AUTOMATIZACIÓN EN RHEL 9
#============================================#

# Flujo nativo de certmonger para FreeIPA / IdM
sudo dnf install certmonger -y
sudo systemctl enable --now certmonger
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/internal.crt \
  -k /etc/pki/tls/private/internal.key \
  -K HTTP/$(hostname -f)@REALM \
  -D $(hostname -f) \
  -C "systemctl reload httpd"

# Flujo público con Let's Encrypt
# Usa certbot, no una definición falsa de CA Let's Encrypt en certmonger.
sudo certbot certonly --apache -d web.example.com

# Flujo IdM ACME (opcional)
# Esto apunta al directorio ACME de tu servidor IPA, no a Let's Encrypt.
sudo certbot certonly \
  --server https://ipa.example.com/acme/directory \
  -d host.example.com

Importante: IdM ACME y Let’s Encrypt son CAs distintas. certmonger sigue siendo la herramienta nativa de RHEL para IPA, CA local y flujos de renovación con seguimiento.


11.6 Mejoras del Almacén de Confianza

Gestión de Confianza Avanzada

#============================================#
# GESTIÓN DE CONFIANZA RHEL 9
#============================================#

# Agregar CA (igual que RHEL 7/8)
sudo cp corporate-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

# NUEVO: Confianza específica por propósito
trust anchor /path/to/ca.crt --purpose server-auth

# Listar confianza con detalles
trust list --filter=ca-anchors

# Exportar CA específica
trust extract --format=pem-bundle --filter=ca-anchors \
  --purpose server-auth /tmp/server-cas.pem

# Eliminar confianza específica
trust anchor --remove "pkcs11:id=%CERT_ID%"

11.7 Problemas y Soluciones Comunes en RHEL 9

Problema 1: Cambios en API de OpenSSL 3.x

Problema: La aplicación personalizada falla con errores de OpenSSL

Síntomas:

Error: EVP_PKEY_RSA no longer supported
Error: Provider not available

Solución:

# Verificar si la aplicación está usando APIs obsoletas
# La aplicación necesita recompilación contra OpenSSL 3.x

# Temporal: Establecer variable de entorno de compatibilidad (si está disponible)
export OPENSSL_CONF=/etc/pki/tls/openssl-compat.cnf

# Largo plazo: Actualizar aplicación

Problema 2: Certificados SHA-1 Rechazados

Problema: Certificados legacy con firmas SHA-1 fallan

Síntomas:

openssl verify cert.crt
# error 3: CA md too weak

Solución:

# Reemitir certificado con SHA-256+
# No hay solución alternativa - SHA-1 está bloqueado por seguridad

# Verificar firma del certificado
openssl x509 -in cert.crt -noout -text | grep "Signature Algorithm"
# Debe mostrar: sha256WithRSAEncryption o mejor

Problema 3: Algoritmo Legacy No Disponible

Problema: La aplicación necesita MD5/RC4/etc.

Síntomas:

openssl md5 file.txt
# Error: unsupported

Solución:

# Usar proveedor legacy explícitamente
openssl md5 -provider legacy file.txt

# Para aplicaciones: Actualizar para usar SHA-256+
# O configurar para cargar proveedor legacy

11.8 Modo FIPS en RHEL 9

Soporte FIPS Mejorado

#============================================#
# MODO FIPS (RHEL 9)
#============================================#

# Habilitar modo FIPS
sudo fips-mode-setup --enable
sudo reboot

# Verificar estado FIPS
fips-mode-setup --check
# FIPS mode is enabled.

# Verificar proveedor FIPS cargado
openssl list -providers | grep -A3 fips
#   fips
#     name: OpenSSL FIPS Provider
#     version: 3.5.5
#     status: active

# Generar certificado compatible con FIPS
openssl req -new -x509 -days 365 -newkey rsa:2048 \
  -keyout fips.key -out fips.crt \
  -subj "/CN=$(hostname)" -provider fips

FIPS en RHEL 9:

  • Usa proveedor FIPS de OpenSSL 3.x
  • Módulos validados FIPS 140-2
  • Transición a FIPS 140-3 en progreso

11.9 Migración desde RHEL 8

Impacto en Certificados

Impacto Moderado:

  • Cambios en API de OpenSSL (afecta apps personalizadas)
  • Validación más estricta (captura más problemas)
  • Algoritmos legacy eliminados
  • SHA-1 completamente bloqueado

Verificaciones Pre-Migración

#============================================#
# PRE-MIGRACIÓN DE CERTIFICADOS RHEL 8 → 9
#============================================#

# 1. Verificar certificados SHA-1 (fallarán en RHEL 9)
for cert in /etc/pki/tls/certs/*.crt; do
  SIG=$(openssl x509 -in "$cert" -noout -text | grep "Signature Algorithm" | head -2)
  echo "$cert: $SIG"
done | grep -i sha1
# ⚠️ ¡Reemitir cualquier cert SHA-1 antes de migración!

# 2. Verificar aplicaciones personalizadas usando OpenSSL
rpm -qa | grep -E "custom|local"
# Probar estas aplicaciones en entorno RHEL 9

# 3. Verificar compatibilidad de crypto-policy
update-crypto-policies --show

# 4. Probar operaciones de certificados
openssl s_client -connect localhost:443

# 5. Respaldar todo
tar czf rhel8-certs-backup-$(date +%Y%m%d).tar.gz \
  /etc/pki/tls/ \
  /etc/pki/ca-trust/source/anchors/

11.10 Mejores Prácticas para RHEL 9

Configuración Recomendada

#============================================#
# CONFIGURACIÓN RECOMENDADA (RHEL 9)
#============================================#

# 1. Usar crypto-policy DEFAULT (a menos que necesidad específica)
sudo update-crypto-policies --set DEFAULT

# 2. Usar certmonger para automatización nativa
sudo dnf install certmonger
sudo systemctl enable --now certmonger

# 3. Para sitios públicos: usar certbot con Let's Encrypt
sudo certbot certonly --apache -d web.example.com

# 4. Para interno: usar FreeIPA con certmonger
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/internal.crt \
  -k /etc/pki/tls/private/internal.key \
  -K host/$(hostname -f)@REALM

# 5. Generar claves EC (más pequeñas, más rápidas)
openssl genpkey -algorithm EC -out ec.key \
  -pkeyopt ec_paramgen_curve:P-256

# 6. Siempre usar SANs
openssl req -new -addext "subjectAltName=DNS:..."

11.11 Nuevas Características Que Deberías Usar

Característica 1: Flujos más sólidos de certmonger + IPA

# Automatización nativa de RHEL para certificados internos
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/internal.crt \
  -k /etc/pki/tls/private/internal.key \
  -K HTTP/$(hostname -f)@REALM \
  -D $(hostname -f) \
  -C "systemctl reload httpd"

# Mejor salida de estado en RHEL 9
sudo getcert list -v

Característica 2: Reporte de Estado Mejorado

# Estado más detallado
sudo getcert list -v

# Mejores mensajes de error
sudo getcert list -f /etc/pki/tls/certs/web.crt
# Muestra razón exacta del error si la renovación falla

Característica 3: Subpolíticas de Crypto-Policy

# Afinar política DEFAULT
sudo update-crypto-policies --set DEFAULT:NO-SHA1

# Múltiples modificadores
sudo update-crypto-policies --set FUTURE:AD-SUPPORT

11.12 Cambios Incompatibles desde RHEL 8

Cambios en API

Si tienes aplicaciones personalizadas:

// RHEL 8 (OpenSSL 1.1.1) - OBSOLETO en RHEL 9:
RSA *rsa = RSA_new();

// RHEL 9 (OpenSSL 3.x) - API NUEVA:
EVP_PKEY *pkey = EVP_PKEY_new();

Impacto: Las aplicaciones compiladas personalizadas pueden necesitar actualizaciones

Cambios en Comandos

# La mayoría de comandos funcionan igual, pero algunos casos especiales:

# RHEL 8: Esto funciona
openssl md5 file.txt

# RHEL 9: Requiere proveedor
openssl md5 -provider legacy file.txt

# Solución: Usar SHA-256 en su lugar
openssl sha256 file.txt

11.13 Escenarios Comunes en RHEL 9

Escenario 1: Configuración HTTPS Apache Nueva en RHEL 9 (CA interna)

#============================================#
# CONFIGURACIÓN COMPLETA APACHE HTTPS (RHEL 9)
#============================================#

# 1. Instalar Apache con mod_ssl
sudo dnf install httpd mod_ssl -y

# 2. Usar certmonger + FreeIPA / IdM
sudo dnf install certmonger -y
sudo systemctl enable --now certmonger

# 3. Solicitar certificado
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/web.crt \
  -k /etc/pki/tls/private/web.key \
  -K HTTP/$(hostname -f)@REALM \
  -D $(hostname -f) \
  -C "systemctl reload httpd"

# 4. Esperar certificado (verificar estado)
sudo getcert list

# 5. Configurar Apache para usar certificado
# /etc/httpd/conf.d/ssl.conf ya apunta a:
#   SSLCertificateFile /etc/pki/tls/certs/localhost.crt
# Actualizar a:
#   SSLCertificateFile /etc/pki/tls/certs/web.crt
#   SSLCertificateKeyFile /etc/pki/tls/private/web.key

# 6. ¡Crypto-policy maneja ajustes TLS automáticamente!
# No necesitas establecer SSLProtocol o SSLCipherSuite

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

# 8. Iniciar Apache
sudo systemctl enable httpd
sudo systemctl start httpd

# 9. Probar
curl -v https://$(hostname -f)/

# 10. ¡La renovación automática ocurre mucho antes de la expiración!

Resultado: ¡HTTPS interno totalmente automatizado con FreeIPA y certmonger!


11.14 Solución de Problemas de Certificados en RHEL 9

Comandos de Diagnóstico

#============================================#
# DIAGNÓSTICO DE CERTIFICADOS RHEL 9
#============================================#

# Verificar versión de OpenSSL
openssl version
# OpenSSL 3.5.5

# Verificar proveedores
openssl list -providers

# Verificar crypto-policy
update-crypto-policies --show

# Probar conexión con TLS 1.3
openssl s_client -connect server:443 -tls1_3

# Verificar algoritmo de firma del certificado
openssl x509 -in cert.crt -noout -text | grep "Signature Algorithm"
# Debe ser SHA-256+ en RHEL 9

# Probar con proveedor legacy (si es necesario)
openssl md5 -provider legacy file.txt

# Verificar rastreo de certmonger
sudo getcert list

# Ver logs de certmonger
sudo journalctl -u certmonger -f

Errores Comunes en RHEL 9

ErrorCausaSolución
“CA md too weak”Firma SHA-1Reemitir con SHA-256+
“Provider not available”Algoritmo legacy usadoAgregar -provider legacy o actualizar a algoritmo moderno
“unsupported” en comando opensslAlgoritmo deshabilitadoUsar alternativa moderna o proveedor legacy
“no shared cipher” (app migrada)Cliente usa cifrados antiguosActualizar cliente o usar política LEGACY temporalmente
“certificate verify failed”Validación más estrictaVerificar cadena cert, SANs, expiración

11.15 Cuándo Usar RHEL 9

Ideal Para:

Nuevos despliegues - Comenzar con seguridad moderna ✅ Entornos enfocados en seguridad - Valores predeterminados más estrictos ✅ Aplicaciones modernas - Beneficiarse de TLS 1.3 ✅ Soporte a largo plazo - 10 años de mantenimiento ✅ Requisitos de cumplimiento - Estándares de seguridad modernos

Momento de Migración:

Desde RHEL 7:

  • ✅ ¡Sí! El mantenimiento de RHEL 7 terminó en junio 2024
  • Planificar cuidadosamente - gran salto (probar exhaustivamente)

Desde RHEL 8:

  • Moderado - OpenSSL 3.x es el cambio principal
  • Probar aplicaciones personalizadas primero
  • Los certificados SHA-1 deben ser reemitidos

11.16 Conclusiones Clave

  1. Arquitectura de proveedores OpenSSL 3.5.5 - Entender proveedores
  2. Validación más estricta - Captura problemas de seguridad (¡bien!)
  3. SHA-1 completamente bloqueado - Reemitir certificados antiguos
  4. Subpolíticas de crypto-policy - Afinar seguridad
  5. certmonger sigue siendo valioso para IPA y flujos de renovación con seguimiento
  6. Soporte obligatorio TLS 1.3 - Más rápido, más seguro
  7. Planificar pruebas - Apps personalizadas pueden necesitar actualizaciones

Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA DE CERTIFICADOS RHEL 9                     │
├──────────────────────────────────────────────────────────────┤
│ OpenSSL:        3.5.5 (arquitectura de proveedores)          │
│ TLS:            1.2, 1.3 (1.0/1.1 eliminados completamente)  │
│ Característica: Subpolíticas, validación más estricta         │
│                                                              │
│ Proveedores:    openssl list -providers                      │
│ Política:       update-crypto-policies --show                │
│ Subpolítica:    update-crypto-policies --set DEFAULT:NO-SHA1 │
│                                                              │
│ Generar clave:  openssl genpkey -algorithm RSA -out key.pem  │
│ Clave EC:       openssl genpkey -algorithm EC -out ec.pem    │
│                 -pkeyopt ec_paramgen_curve:P-256             │
│                                                              │
│ ACME público:   certbot certonly --apache -d example.com     │
│ certmonger:     ipa-getcert request ...                      │
│ Algo legacy:    openssl md5 -provider legacy file.txt        │
└──────────────────────────────────────────────────────────────┘

⚠️ SHA-1 está BLOQUEADO - ¡reemitir certificados antiguos!
✅ Usar certmonger para IPA y automatización con seguimiento
✅ La política DEFAULT funciona para la mayoría de casos

Navegación del Capítulo

Capítulo 12: Características Actuales de RHEL 10

Vanguardia: RHEL 10 GA se lanzó el 20 de mayo de 2025; RHEL 10.2 es la versión menor actual. Aprende sobre las últimas características y prepárate para el futuro de la gestión de certificados en Red Hat Enterprise Linux.


12.1 Resumen de RHEL 10

Lanzamiento GA: 20 de mayo de 2025 Versión Actual: RHEL 10.2 Soporte Hasta: 31 de mayo de 2035 Estado: ✅ Lanzamiento de Producción

Características Clave:

  • Versión OpenSSL: 3.5.5-2 (paquete: openssl-3.5.5-2.el10_2.x86_64)
  • Misma base que: RHEL 9.8 (OpenSSL 3.5.5)
  • Enfoque: Fortalecimiento continuo, preparación post-cuántica, nativo de nube
  • Filosofía: Mejora incremental sobre RHEL 9

Importante: Las características de RHEL 10 pueden evolucionar a través de versiones menores (10.1, 10.2, etc.). Siempre consulta la documentación oficial de Red Hat para tu lanzamiento específico de RHEL 10.x.


12.2 ¿Qué Hay de Nuevo vs. RHEL 9?

Diferencias Clave

CaracterísticaRHEL 9RHEL 10
OpenSSL3.5.53.5.5 (misma base)
Crypto-PoliciesSubpolíticasSubpolíticas mejoradas
Versiones TLS1.2, 1.31.3 preferido, 1.2 soportado
FIPSMódulos 140-2Transición 140-3
Valores Predeterminados de SeguridadEstrictoMás Estricto
Soporte de ContenedoresBuenoMejorado
Post-CuánticoFundamentoPreparación activa

Paquete: openssl-3.5.5-2.el10_2.x86_64

No es un Cambio Revolucionario

A diferencia de RHEL 7→8 (crypto-policies) o RHEL 8→9 (OpenSSL 3.x), RHEL 10 es una mejora incremental.

Piénsalo como:

  • RHEL 7 → 8: 🚀 Revolucionario (crypto-policies)
  • RHEL 8 → 9: 🔄 Mayor (OpenSSL 3.x)
  • RHEL 9 → 10: ⬆️ Incremental (refinamientos)

12.3 Gestión de Certificados en RHEL 10

Mismo Fundamento que RHEL 9

#============================================#
# CONCEPTOS BÁSICOS DE CERTIFICADOS RHEL 10
#============================================#

# Misma versión de OpenSSL que RHEL 9.8
openssl version
# OpenSSL 3.5.5 27 Jan 2026

# Mismo sistema crypto-policies
update-crypto-policies --show

# Mismo certmonger
getcert list

# Misma estructura de directorios
ls -la /etc/pki/tls/

Conclusión: ¡Si conoces RHEL 9, conoces certificados de RHEL 10!


12.4 Características de Seguridad Mejoradas

Valores Predeterminados Más Estrictos

#============================================#
# MEJORAS DE SEGURIDAD RHEL 10
#============================================#

# 1. La política DEFAULT es más estricta
# - Preferencias de cifrado más fuertes
# - Algoritmos débiles adicionales eliminados
# - Validación mejorada

# 2. Política LEGACY más restringida
# - Menos algoritmos legacy permitidos
# - Mínimos más fuertes incluso en LEGACY

# 3. Gestión de certificados de contenedor mejorada
# - Mejor integración con Podman
# - Montaje de certificados simplificado
# - Gestión de secretos mejorada

Preparación para Criptografía Post-Cuántica

Fundamento para el Futuro:

# RHEL 10 se prepara para algoritmos post-cuánticos
# (Aún no predeterminado, pero infraestructura lista)

# Capacidad futura (a medida que los estándares se finalicen):
# - ML-KEM (Module-Lattice Key Encapsulation)
# - ML-DSA (Module-Lattice Digital Signatures)
# - Criptografía híbrida clásica/cuántica

# Estado actual: Monitoreando estándares NIST
# Esperado: Lanzamientos menores RHEL 10.x agregarán soporte PQC

Nota: La criptografía post-cuántica aún está evolucionando. RHEL 10 proporciona el fundamento, la implementación real vendrá a medida que los estándares se finalicen.


12.5 Características Específicas de RHEL 10

Característica 1: Módulos de Crypto-Policy Mejorados

#============================================#
# MEJORAS EN CRYPTO-POLICY DE RHEL 10
#============================================#

# Control más granular
sudo update-crypto-policies --set DEFAULT:NO-SHA1

# Mejor validación
update-crypto-policies --check

# Mensajes de error mejorados cuando las políticas entran en conflicto

Característica 2: Soporte Mejorado de Certificados de Contenedor

#============================================#
# CONTENEDORES CON CERTIFICADOS (RHEL 10)
#============================================#

# Montaje de certificados más fácil en Podman
podman run -d \
  -v /etc/pki/tls/certs/web.crt:/certs/web.crt:ro \
  -v /etc/pki/tls/private/web.key:/certs/web.key:ro \
  -p 443:443 \
  nginx

# Gestión de secretos mejorada
podman secret create web-cert /etc/pki/tls/certs/web.crt
podman secret create web-key /etc/pki/tls/private/web.key

# Usar secretos en contenedor
podman run -d --secret web-cert --secret web-key nginx

Característica 3: Modo FIPS Mejorado

#============================================#
# FIPS EN RHEL 10
#============================================#

# Modo FIPS con proveedor FIPS de OpenSSL 3.x
sudo fips-mode-setup --enable
sudo reboot

# Verificar estado FIPS
fips-mode-setup --check

# RHEL 10: Transición hacia FIPS 140-3
# Actual: Aún módulos validados FIPS 140-2
# Futuro: Cumplimiento FIPS 140-3 a medida que se complete la certificación

12.6 Migración desde RHEL 9

¿Deberías Actualizar?

Consideraciones de Actualización:

Razones para Actualizar:

  • ✅ Quieres 10+ años de soporte (hasta 2035)
  • ✅ Necesitas las últimas mejoras de seguridad
  • ✅ Preparación para el futuro (preparación post-cuántica)
  • ✅ Soporte mejorado de contenedores
  • ✅ Últimas características y mejoras

Razones para Esperar:

  • ⏸️ RHEL 9 soportado hasta 2032
  • ⏸️ No hay características urgentes relacionadas con certificados
  • ⏸️ Deja que otros prueben RHEL 10 en producción primero
  • ⏸️ Quieres esperar por RHEL 10.3 o 10.4

Impacto en Certificados: BAJO

  • Misma base OpenSSL (3.5.5)
  • Mismas herramientas y comandos
  • Cambios incompatibles mínimos
  • Mayormente transparente

Proceso de Migración

#============================================#
# MIGRACIÓN DE CERTIFICADOS RHEL 9 → RHEL 10
#============================================#

# 1. Pre-migración: Verificar certificados
for cert in /etc/pki/tls/certs/*.crt; do
  openssl x509 -in "$cert" -noout -text | grep "Signature Algorithm"
done
# Todos deberían mostrar SHA-256+ (sin SHA-1 ni MD5)

# 2. Respaldo
tar czf rhel9-certs-backup-$(date +%Y%m%d).tar.gz \
  /etc/pki/tls/ \
  /etc/pki/ca-trust/source/anchors/

# 3. Realizar actualización de RHEL
sudo leapp upgrade

# 4. Verificar crypto-policy
update-crypto-policies --show

# 5. Reiniciar servicios
sudo systemctl restart httpd nginx postfix

# 6. Probar certificados
curl -v https://localhost/
openssl s_client -connect localhost:443

# 7. Verificar certmonger
sudo getcert list

12.7 Mejores Prácticas para RHEL 10

Configuración Recomendada

#============================================#
# CONFIGURACIÓN RECOMENDADA DE RHEL 10
#============================================#

# 1. Usar crypto-policy DEFAULT (ya óptima)
sudo update-crypto-policies --set DEFAULT

# 2. Preferir TLS 1.3
# (Ya preferido automáticamente por política DEFAULT)

# 3. Usar claves EC para nuevos certificados
openssl genpkey -algorithm EC -out ec.key \
  -pkeyopt ec_paramgen_curve:P-256

# 4. Automatizar con la herramienta correcta
# Certificado público de Let's Encrypt: usar certbot
sudo certbot certonly --apache -d web.example.com

# Certificado interno de FreeIPA / IdM: usar certmonger
# sudo ipa-getcert request \
#   -f /etc/pki/tls/certs/web.crt \
#   -k /etc/pki/tls/private/web.key \
#   -K HTTP/web.example.com@REALM \
#   -D web.example.com \
#   -C "systemctl reload httpd"

# 5. Monitorear certificados
# Usar monitoreo integrado o herramientas externas

# 6. Planificar para PQC futuro
# Mantente al día con lanzamientos menores RHEL 10.x

12.8 Mirando Hacia Adelante: Preparación Post-Cuántica

¿Qué es la Criptografía Post-Cuántica?

Problema: Las computadoras cuánticas futuras podrían romper el cifrado actual (RSA, ECC) Solución: Nuevos algoritmos resistentes a cuántica

Estándares NIST (Finalizados 2024):

  • ML-KEM-768 (Encapsulación de Clave)
  • ML-DSA-65 (Firmas Digitales)
  • SLH-DSA (Firmas sin estado)

Rol de RHEL 10:

  • Proporciona fundamento para PQC
  • La arquitectura OpenSSL 3.x soporta nuevos algoritmos
  • Futuros lanzamientos RHEL 10.x agregarán soporte PQC

Criptografía Híbrida (Futuro)

# Capacidad futura en RHEL 10.x:
# Usar criptografía clásica Y resistente a cuántica

# Ejemplo (conceptual - aún no en RHEL 10.2):
openssl genpkey -algorithm hybrid-rsa-mlkem768 -out hybrid.key

# Proporciona:
# - Seguridad contra ataques clásicos (RSA)
# - Seguridad contra ataques cuánticos (ML-KEM)

Nota: El soporte PQC vendrá en versiones menores futuras de RHEL 10.x a medida que los estándares se finalicen y prueben.


12.9 Qué Permanece Igual

Sin Cambios Incompatibles Mayores

#============================================#
# LOS COMANDOS FAMILIARES AÚN FUNCIONAN
#============================================#

# Generar clave (igual que RHEL 9)
openssl genpkey -algorithm RSA -out server.key \
  -pkeyopt rsa_keygen_bits:2048

# Generar CSR (igual que RHEL 9)
openssl req -new -key server.key -out server.csr \
  -subj "/CN=server.example.com" \
  -addext "subjectAltName=DNS:server.example.com"

# Ver certificado (igual)
openssl x509 -in cert.crt -noout -text

# Probar conexión (igual)
openssl s_client -connect server:443

# Gestión de confianza (igual)
sudo cp ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

# certmonger (igual)
sudo getcert list

# crypto-policies (igual)
update-crypto-policies --show

¡Si conoces RHEL 9, estás listo para RHEL 10!


12.10 Cuándo Adoptar RHEL 10

Recomendaciones de Cronograma de Adopción

Adoptadores Tempranos (2025-2026):

  • Entornos de prueba
  • Cargas de trabajo no críticas
  • Quieren las últimas características
  • Investigación de seguridad

Mainstream (2026-2027):

  • Nuevos despliegues
  • Infraestructura renovada
  • Después del lanzamiento de RHEL 10.3/10.4
  • Cuando las apps principales estén certificadas

Conservador (2027-2028):

  • Sistemas de producción críticos
  • Cargas de trabajo estables
  • Después de pruebas extensivas de la comunidad
  • Cuando la migración desde RHEL 9 sea necesaria

Recomendación Actual (Finales de 2025):

  • Proyectos nuevos: Considerar RHEL 10
  • ⏸️ RHEL 9 existente: No hay urgencia para actualizar
  • RHEL 8 o anterior: Evaluar RHEL 9 o 10
  • RHEL 7: Actualización requerida (soporte terminado)

12.11 Monitorear la Evolución de RHEL 10

Mantenerse Actualizado

# Verificar versión menor de RHEL 10
cat /etc/redhat-release
# Red Hat Enterprise Linux release 10.2 (Coughlan)

# Verificar actualizaciones
sudo dnf check-update

# Monitorear anuncios de Red Hat
# - https://access.redhat.com/articles/3078
# - Notas de lanzamiento de RHEL 10
# - Avisos de seguridad de Red Hat

# Suscribirse a boletines de Red Hat
# Seguir notas de lanzamiento para 10.3, 10.4, etc.

Características a Vigilar

Esperado en lanzamientos menores RHEL 10.x:

  • Soporte de criptografía post-cuántica
  • Mejoras adicionales en crypto-policy
  • Mayor integración de contenedores
  • Herramientas de automatización mejoradas
  • Módulos FIPS 140-3 adicionales

12.12 Configuración Práctica de Certificados en RHEL 10

Ejemplo Completo: Configuración HTTPS Moderna

#!/bin/bash
# Configuración HTTPS moderna completa en RHEL 10

echo "=== Configuración HTTPS Moderna RHEL 10 ==="

# 1. Instalar paquetes
sudo dnf install -y httpd mod_ssl epel-release certbot python3-certbot-apache

# 2. Habilitar servicios
sudo systemctl enable --now httpd

# 3. Solicitar certificado de Let's Encrypt con certbot
sudo certbot --apache -d $(hostname -f)

# 4. Verificar el certificado
sudo certbot certificates

# 5. Actualizar configuración de Apache
# certbot normalmente actualiza Apache automáticamente; ajusta manualmente solo si hace falta
sudo sed -i "s|SSLCertificateFile.*|SSLCertificateFile /etc/letsencrypt/live/$(hostname -f)/fullchain.pem|" \
  /etc/httpd/conf.d/ssl.conf
sudo sed -i "s|SSLCertificateKeyFile.*|SSLCertificateKeyFile /etc/letsencrypt/live/$(hostname -f)/privkey.pem|" \
  /etc/httpd/conf.d/ssl.conf

# 6. Crypto-policy ya óptima (DEFAULT)
update-crypto-policies --show

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

# 8. Recargar Apache
sudo systemctl reload httpd

# 9. Probar
curl -v https://$(hostname -f)/

echo "✅ ¡Configuración HTTPS moderna de RHEL 10 completa!"
echo "   - TLS 1.3 soportado"
echo "   - Certificado Let's Encrypt"
echo "   - Renovación automática habilitada"
echo "   - Seguridad óptima (política DEFAULT)"

12.13 Estrategias de Preparación para el Futuro

Preparándose para la Evolución de RHEL 10.x

#============================================#
# GESTIÓN DE CERTIFICADOS PREPARADA PARA EL FUTURO
#============================================#

# 1. Usar algoritmos modernos (listo para transición PQC)
# Preferir EC sobre RSA
openssl genpkey -algorithm EC -out ec.key -pkeyopt ec_paramgen_curve:P-256

# 2. Mantener certificados de corta vida (90 días o menos)
# Más fácil rotar cuando cambien los algoritmos

# 3. Automatizar todo
# Usar certbot para ACME público y certmonger para flujos IPA/internos

# 4. Monitorear anuncios de Red Hat
# Suscribirse a notificaciones de seguridad y lanzamiento

# 5. Probar PQC cuando esté disponible
# Ser probador temprano de nuevas características en RHEL 10.x

# 6. Documentar tu configuración
# Facilita transiciones futuras

12.14 Problemas Conocidos y Soluciones

Problema 1: Igual que RHEL 9 (OpenSSL 3.x)

La mayoría de problemas de RHEL 9 aplican a RHEL 10:

  • Los algoritmos legacy necesitan -provider legacy
  • SHA-1 bloqueado
  • Apps personalizadas pueden necesitar actualizaciones OpenSSL 3.x

Referencia: Ver Capítulo 11 para problemas OpenSSL 3.x

Problema 2: Validación Aún Más Estricta

RHEL 10 puede capturar problemas que RHEL 9 permitía:

# Ejemplo: Certificado marginal que funcionaba en RHEL 9
# podría fallar en RHEL 10

# Solución: Siempre usar mejores prácticas
# - Firmas SHA-256+
# - Claves de 2048+ bits (4096 recomendado)
# - SANs apropiados
# - Cadenas de confianza válidas

12.15 Cuándo Elegir RHEL 10

Matriz de Decisión

EscenarioRHEL 9RHEL 10Recomendación
Nuevo despliegue 2025+✅ Bueno✅ MejorRHEL 10
RHEL 9 existente✅ Mantener⏸️ EsperarQuedarse en 9 por ahora
Migrando desde RHEL 8✅ Sí✅ ConsiderarCualquiera (9 es más seguro)
Migrando desde RHEL 7✅ Sí⚠️ Gran saltoIr a 9 primero
Horizonte 10+ años⏸️ Soporte 2032✅ Soporte 2035RHEL 10
Seguridad de vanguardia✅ Bueno✅ MejorRHEL 10
Producción crítica✅ Probado⏸️ Más nuevoRHEL 9 (más seguro)

12.16 Conclusiones Clave

  1. RHEL 10 = RHEL 9 + mejoras incrementales
  2. Misma base OpenSSL 3.5.5 - Sin cambios API mayores
  3. Valores predeterminados de seguridad más estrictos - Bueno para seguridad
  4. Preparación post-cuántica - Infraestructura lista para el futuro
  5. Sin cambios urgentes de certificados - La transición es suave
  6. Conocimiento de RHEL 9 se transfiere - Mismas herramientas y comandos
  7. Vigilar lanzamientos menores - 10.3, 10.4 pueden agregar características

12.17 Solución de Problemas en RHEL 10

Enfoque de Diagnóstico

#============================================#
# RESOLUCIÓN DE PROBLEMAS DE CERTIFICADOS RHEL 10
#============================================#

# Usar la metodología de solución de problemas (Capítulo 27) y los patrones de RHEL 9 (Capítulo 11)

# 1. Verificar versión de RHEL 10
cat /etc/redhat-release
# Red Hat Enterprise Linux release 10.2 (Coughlan)

# 2. Verificar OpenSSL
openssl version
# OpenSSL 3.5.5

# 3. Verificar crypto-policy
update-crypto-policies --show

# 4. Probar certificado
openssl x509 -in cert.crt -noout -text

# 5. Probar conexión
openssl s_client -connect server:443 -tls1_3

# 6. Verificar proveedores (si hay problemas)
openssl list -providers

# 7. Verificar logs
sudo journalctl -xe | grep -i cert

¡No se necesitan nuevas técnicas de solución de problemas - igual que RHEL 9!


12.18 Ruta de Migración Recomendada

De RHEL 9 a RHEL 10

#============================================#
# MIGRACIÓN SEGURA PARA CERTIFICADOS RHEL 9→10
#============================================#

# Fase 1: Preparación
# - Respaldar todos los certificados
# - Documentar configuración actual
# - Probar en entorno de laboratorio

# Fase 2: Migración
# - Usar proceso estándar de actualización de RHEL
# - Los certificados deberían transferirse sin problemas

# Fase 3: Verificación
# - Verificar crypto-policy sin cambios
# - Probar todas las operaciones de certificados
# - Confirmar rastreo de certmonger mantenido
# - Probar servicios usando certificados

# Fase 4: Optimización
# - Considerar claves EC para nuevos certificados
# - Revisar y actualizar crypto-policy si es necesario
# - Monitorear mejoras de RHEL 10.x

12.19 Documentación y Recursos

Recursos Oficiales

## Recursos de Certificados RHEL 10

### Documentación Oficial
- Notas de Lanzamiento RHEL 10 (verificar tu versión 10.x específica)
- https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/10

### Actualizaciones de Seguridad
- https://access.redhat.com/security/
- Suscribirse a anuncios de seguridad de RHEL

### Crypto-Policies
- https://access.redhat.com/articles/3642912
- Verificar actualizaciones específicas de RHEL 10

### Soporte
- Portal de Clientes Red Hat
- Casos de Soporte Red Hat
- Foros de la comunidad RHEL

12.20 Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA DE CERTIFICADOS RHEL 10                    │
├──────────────────────────────────────────────────────────────┤
│ OpenSSL:      3.5.5-2 (igual que RHEL 9.8)                   │
│ TLS:          1.3 preferido, 1.2 soportado                   │
│ Lanzado:      20 de mayo de 2025 (RHEL 10.0 GA)              │
│ Estado:       Listo para producción                          │
│                                                              │
│ Cambio clave: Mejoras de seguridad incrementales             │
│ Migración:    Bajo impacto desde RHEL 9                      │
│ Comandos:     Iguales que RHEL 9                             │
│ Herramientas: Iguales que RHEL 9                             │
│                                                              │
│ Futuro:       Preparación criptografía post-cuántica         │
│               Vigilar características en 10.3, 10.4+         │
│                                                              │
│ Verificar:    cat /etc/redhat-release                        │
│               openssl version                                │
│               update-crypto-policies --show                  │
└──────────────────────────────────────────────────────────────┘

✅ ¡Si conoces certificados RHEL 9, conoces RHEL 10!
⚠️ Siempre verificar docs oficiales para tu versión menor 10.x específica

Navegación del Capítulo

Capítulo 13: Compatibilidad entre Versiones

Desafío del Mundo Real: Tu entorno probablemente tiene sistemas RHEL 7, 8 y 9 todos comunicándose entre sí. ¿Cómo haces que los certificados funcionen en todas las versiones?


13.1 La Realidad del Entorno Mixto

La mayoría de las empresas no actualizan todo a la vez. Encontrarás:

Entorno de Producción (Típico):
├── Servidor de App Legacy (RHEL 7)
├── Servidor de Base de Datos (RHEL 8)
├── Capa Web (RHEL 9)
├── Nodo de Gestión (RHEL 10)
└── Clientes: Windows, Mac, Linux, Mobile

Desafío: Estos sistemas tienen diferentes:

  • Soporte de versión TLS
  • Suites de cifrado
  • Reglas de validación de certificados
  • Versiones de OpenSSL
  • Crypto-policies (o falta de ellas)

13.2 Problemas Comunes de Compatibilidad

Problema 1: Desajustes de Versión TLS

Escenario: Servidor RHEL 9 (solo TLS 1.2+) ← Cliente RHEL 7 (TLS 1.0/1.1 predeterminado)

# Cliente RHEL 7 intentando conectarse a servidor RHEL 9
curl https://rhel9-server.example.com/
# Error: SSL routines:ssl3_get_record:wrong version number

# Por qué: RHEL 7 intenta TLS 1.0 primero, RHEL 9 lo rechaza

Solución:

# Opción 1: Actualizar cliente RHEL 7 para usar TLS 1.2
# Editar /etc/httpd/conf.d/ssl.conf (si cliente Apache)
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1

# Opción 2: Política LEGACY temporal en RHEL 9 (NO recomendado)
# sudo update-crypto-policies --set LEGACY  # En servidor RHEL 9

# Opción 3: Mejor - ¡Actualizar sistemas RHEL 7!

Problema 2: Desajustes de Suite de Cifrado

Escenario: Servidor moderno no soporta cifrados de cliente antiguo

# Cliente RHEL 7 → Servidor RHEL 9
openssl s_client -connect rhel9-server:443 -cipher '3DES'
# Error: no shared cipher

Por qué: 3DES está bloqueado en política DEFAULT de RHEL 8+

Solución:

# Verificar qué cifrados están disponibles
openssl ciphers -v 'HIGH:!aNULL:!MD5' | head

# Probar cifrado específico en cliente
openssl s_client -connect server:443 -cipher 'AES256-GCM-SHA384'

# En servidor RHEL 9, si DEBES soportar clientes antiguos:
sudo update-crypto-policies --set LEGACY  # ¡Temporal!

Problema 3: Diferencias de Validación de Certificados

Escenario: Certificado firmado con SHA-1

Certificado con firma SHA-1:
├── ✅ Funciona en RHEL 7
├── ❌ Rechazado por RHEL 8 DEFAULT
├── ❌ Rechazado por RHEL 9
└── ❌ Rechazado por RHEL 10

Solución:

# Reemitir certificado con SHA-256 o mejor
openssl req -new -key server.key -out server.csr -sha256

# Verificar algoritmo de firma
openssl x509 -in cert.crt -noout -text | grep "Signature Algorithm"
# Debería mostrar: sha256WithRSAEncryption (o mejor)

13.3 Matriz de Compatibilidad

Compatibilidad Cliente → Servidor

Cliente ↓ Servidor →Servidor RHEL 7Servidor RHEL 8 (DEFAULT)Servidor RHEL 9 (DEFAULT)Servidor RHEL 10
Cliente RHEL 7✅ Completo⚠️ Problema TLS 1.0/1.1⚠️ Problema TLS 1.0/1.1⚠️ Problema TLS 1.0/1.1
Cliente RHEL 8✅ Completo✅ Completo✅ Completo✅ Completo
Cliente RHEL 9⚠️ Advertencia cifrado débil✅ Completo✅ Completo✅ Completo
Cliente RHEL 10⚠️ Advertencia cifrado débil✅ Completo✅ Completo✅ Completo
Windows 10✅ Completo✅ Completo✅ Completo✅ Completo
Windows Server 2012✅ Completo⚠️ Puede necesitar TLS 1.0/1.1⚠️ Puede necesitar TLS 1.0/1.1⚠️ Puede necesitar TLS 1.0/1.1
Java 7 antiguo✅ Completo❌ No TLS 1.2❌ No TLS 1.2❌ No TLS 1.2

Leyenda:

  • ✅ Funciona sin cambios
  • ⚠️ Funciona con cambios de configuración
  • ❌ Incompatible sin actualizaciones mayores

13.4 Requisitos de Certificado para Máxima Compatibilidad

El Perfil de Certificado “Universal”

Para funcionar en todas las versiones de RHEL (7-10) y clientes externos:

# Requisitos del Certificado:
✅ Clave RSA: 2048 bits mínimo (4096 para preparación futura)
✅ Firma: SHA-256 o mejor (¡no SHA-1!)
✅ Subject Alternative Names (SANs) requeridos
✅ Validez: ≤ 365 días (requisito de navegador)
✅ Key Usage: Extensiones apropiadas establecidas

❌ Evitar: Firmas SHA-1
❌ Evitar: RSA < 2048 bits
❌ Evitar: SANs faltantes
❌ Evitar: Certificados solo CN

Generar un Certificado Compatible

#============================================#
# PASO 1: Generar Clave (funciona en todas las versiones de RHEL)
#============================================#

# RSA 2048 (mínimo, compatible)
openssl genpkey -algorithm RSA -out universal.key -pkeyopt rsa_keygen_bits:2048

# O RSA 4096 (mejor, aún compatible)
openssl genpkey -algorithm RSA -out universal.key -pkeyopt rsa_keygen_bits:4096


#============================================#
# PASO 2: Crear CSR con SANs
#============================================#

openssl req -new -key universal.key -out universal.csr \
  -subj "/C=US/ST=State/L=City/O=Company/CN=server.example.com" \
  -addext "subjectAltName=DNS:server.example.com,DNS:www.example.com,IP:10.0.0.100" \
  -addext "keyUsage=digitalSignature,keyEncipherment" \
  -addext "extendedKeyUsage=serverAuth,clientAuth"


#============================================#
# PASO 3: Verificar CSR
#============================================#

openssl req -in universal.csr -noout -text | grep -A2 "Subject Alternative Name"
# Debería mostrar tus SANs

openssl req -in universal.csr -noout -text | grep "Public-Key"
# Debería mostrar: Public-Key: (2048 bit) o superior

13.5 Probar Compatibilidad entre Versiones

Script de Suite de Pruebas

#!/bin/bash
# test-cert-compatibility.sh
# Prueba si el certificado funciona desde varias versiones de RHEL

SERVER_HOST="server.example.com"
SERVER_PORT="443"
CERT_FILE="/etc/pki/tls/certs/server.crt"

echo "=== Suite de Pruebas de Compatibilidad de Certificados ==="
echo ""

#============================================#
# PRUEBA 1: Propiedades del Certificado
#============================================#

echo "1. Propiedades del Certificado:"
echo "   Algoritmo de Firma:"
openssl x509 -in "$CERT_FILE" -noout -text | grep "Signature Algorithm" | head -1

echo "   Tamaño de Clave:"
openssl x509 -in "$CERT_FILE" -noout -text | grep "Public-Key"

echo "   SANs:"
openssl x509 -in "$CERT_FILE" -noout -ext subjectAltName 2>/dev/null || echo "   ¡No se encontraron SANs!"

echo ""


#============================================#
# PRUEBA 2: Soporte de Versión TLS
#============================================#

echo "2. Soporte de Versión TLS:"

for version in tls1 tls1_1 tls1_2 tls1_3; do
  if openssl s_client -connect "$SERVER_HOST:$SERVER_PORT" -"$version" </dev/null 2>&1 | grep -q "Cipher"; then
    echo "   ${version//_/.}: ✅ Soportado"
  else
    echo "   ${version//_/.}: ❌ No soportado"
  fi
done

echo ""


#============================================#
# PRUEBA 3: Compatibilidad de Suite de Cifrado
#============================================#

echo "3. Pruebas de Cifrado Comunes:"

# Cifrado moderno (RHEL 8+)
if openssl s_client -connect "$SERVER_HOST:$SERVER_PORT" -cipher 'ECDHE-RSA-AES256-GCM-SHA384' </dev/null 2>&1 | grep -q "Cipher"; then
  echo "   Cifrado moderno (ECDHE-RSA-AES256-GCM-SHA384): ✅"
else
  echo "   Cifrado moderno: ❌"
fi

# Cifrado legacy (RHEL 7)
if openssl s_client -connect "$SERVER_HOST:$SERVER_PORT" -cipher 'AES256-SHA' </dev/null 2>&1 | grep -q "Cipher"; then
  echo "   Cifrado legacy (AES256-SHA): ✅ (puede indicar política LEGACY)"
else
  echo "   Cifrado legacy: ❌ (bueno para seguridad)"
fi


#============================================#
# PRUEBA 4: Validación de Certificado
#============================================#

echo ""
echo "4. Validación de Certificado:"

if openssl verify -CAfile /etc/pki/tls/certs/ca-bundle.crt "$CERT_FILE" | grep -q "OK"; then
  echo "   Cadena de confianza: ✅ Válida"
else
  echo "   Cadena de confianza: ❌ Inválida"
fi

echo ""
echo "=== Prueba Completa ==="

Uso:

chmod +x test-cert-compatibility.sh
sudo ./test-cert-compatibility.sh

13.6 Manejar Escenarios Específicos de Compatibilidad

Escenario 1: Cliente RHEL 7 → Servidor RHEL 9

Problema: La conexión falla con error de versión TLS

Solución Lado Cliente (RHEL 7):

# Para curl
curl --tlsv1.2 https://rhel9-server/

# Para wget
wget --secure-protocol=TLSv1_2 https://rhel9-server/

# Para aplicaciones usando OpenSSL, establecer variable de entorno
export OPENSSL_CONF=/etc/pki/tls/openssl-tls12.cnf

# Crear configuración personalizada
cat > /etc/pki/tls/openssl-tls12.cnf << 'EOF'
openssl_conf = default_conf

[default_conf]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT@SECLEVEL=1
EOF

Solución Lado Servidor (RHEL 9) - NO RECOMENDADO:

# ¡Solo si es absolutamente necesario y temporalmente!
sudo update-crypto-policies --set LEGACY
sudo systemctl restart httpd  # O tu servicio

Escenario 2: Confianza CA Mixta

Problema: CA corporativa confiable en algunos sistemas pero no en otros

Solución: Almacén de confianza consistente en todas las versiones

#============================================#
# SCRIPT DE DESPLIEGUE (ejecutar en todas las versiones de RHEL)
#============================================#

#!/bin/bash
# deploy-corporate-ca.sh

CA_CERT_URL="http://pki.example.com/ca-chain.crt"
CA_CERT_FILE="/etc/pki/ca-trust/source/anchors/corporate-ca-chain.crt"

# Descargar certificado CA
curl -o "$CA_CERT_FILE" "$CA_CERT_URL"

# Actualizar almacén de confianza (funciona en todas las versiones de RHEL)
update-ca-trust extract

# Verificar
if trust list | grep -q "Corporate Root CA"; then
  echo "✅ CA corporativa instalada exitosamente"
else
  echo "❌ Falló la instalación de CA corporativa"
  exit 1
fi

Escenario 3: Aplicación Usando Biblioteca TLS Antigua

Problema: La aplicación Java 7 no puede conectarse a servidores modernos

Verificar Soporte TLS de Java:

# Verificar versión de Java
java -version

# Probar soporte TLS
java -Djavax.net.debug=ssl:handshake -jar app.jar 2>&1 | grep "TLS"

Opciones:

# Opción 1: Actualizar Java (mejor)
sudo dnf install java-11-openjdk

# Opción 2: Habilitar TLS 1.2 en Java 7 (si actualización imposible)
# Agregar al inicio de Java:
-Dhttps.protocols=TLSv1.2

# Opción 3: Usar script wrapper
#!/bin/bash
export JAVA_OPTS="-Dhttps.protocols=TLSv1.2 -Djavax.net.ssl.trustStore=/etc/pki/java/cacerts"
java $JAVA_OPTS -jar /path/to/app.jar

13.7 Compatibilidad de Crypto-Policy

Entender el Impacto de la Política entre Versiones

#============================================#
# RHEL 7 (Sin crypto-policies)
#============================================#

# Configuración manual en cada app
# Apache: /etc/httpd/conf.d/ssl.conf
# NGINX: /etc/nginx/nginx.conf
# Postfix: /etc/postfix/main.cf


#============================================#
# RHEL 8/9/10 (crypto-policies)
#============================================#

# Control en todo el sistema
update-crypto-policies --set DEFAULT

# Para soportar clientes RHEL 7, podría necesitarse:
update-crypto-policies --set LEGACY  # ¡Temporalmente!

Equivalentes de Política para Entornos Mixtos

Si necesitas mantener compatibilidad:

Opción A: Usar LEGACY en sistemas modernos (no recomendado a largo plazo)

# En servidores RHEL 8/9/10
sudo update-crypto-policies --set LEGACY

Opción B: Configurar RHEL 7 para coincidir con DEFAULT (recomendado)

# En RHEL 7, configurar manualmente para coincidir con DEFAULT de RHEL 8+
# Ejemplo Apache:
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5:!3DES:!CAMELLIA
SSLHonorCipherOrder on

13.8 Ruta de Migración: Actualización Gradual

Fase 1: Preparar RHEL 7 (Pre-Migración)

# 1. Reemitir todos los certificados con SHA-256+
# 2. Probar compatibilidad TLS 1.2
# 3. Actualizar configuraciones de cifrado
# 4. Documentar inventario actual de certificados

Fase 2: Desplegar RHEL 8 (Transición)

# 1. Comenzar con política LEGACY
sudo update-crypto-policies --set LEGACY

# 2. Desplegar servicios
# 3. Probar exhaustivamente
# 4. Cambiar gradualmente a DEFAULT
sudo update-crypto-policies --set DEFAULT

Fase 3: Actualizar a RHEL 9 (Modernización)

# 1. Todos los clientes deberían ser RHEL 8+ o capaces de TLS 1.2
# 2. Usar política DEFAULT
# 3. Monitorear problemas de compatibilidad
# 4. Considerar política FUTURE después de estabilización

13.9 Resolver Problemas entre Versiones

Comandos de Diagnóstico

#============================================#
# EN EL CLIENTE
#============================================#

# Probar versión TLS específica
openssl s_client -connect server:443 -tls1_2

# Probar con salida verbosa
curl -v --tlsv1.2 https://server/

# Verificar OpenSSL del cliente
openssl version
openssl ciphers -v


#============================================#
# EN EL SERVIDOR
#============================================#

# Verificar crypto-policy (RHEL 8+)
update-crypto-policies --show

# Verificar configuración de OpenSSL
openssl version
cat /etc/crypto-policies/back-ends/opensslcnf.config

# Probar certificado del servidor
openssl s_client -connect localhost:443 -servername $(hostname)

# Verificar logs de servicio
sudo journalctl -xe | grep -i tls
sudo tail -f /var/log/httpd/ssl_error_log

Mensajes de Error Comunes

ErrorCausaSolución
“wrong version number”Desajuste versión TLSActualizar cliente a TLS 1.2+
“no shared cipher”Incompatibilidad de cifradoVerificar crypto-policy o configuración de cifrado
“certificate verify failed”Problema de confianza o validaciónVerificar confianza CA, validez de certificado
“sslv3 alert handshake failure”Incompatibilidad de protocoloActualizar versiones TLS
“unsafe legacy renegotiation”OpenSSL antiguo en clienteActualizar OpenSSL del cliente

13.10 Mejores Prácticas para Entornos Mixtos

1. Estandarizar Emisión de Certificados

# Estándar de Certificado (ejemplo)
Algorithm: RSA
Key Size: 2048 bits mínimo (4096 preferido)
Signature: SHA-256 o mejor
Validity: 365 días máximo
SANs: Siempre incluir
Extensions: Uso de clave apropiado establecido

2. Mantener Almacenes de Confianza Consistentes

# Script de despliegue para todos los sistemas
for host in rhel7-hosts rhel8-hosts rhel9-hosts; do
  ssh "$host" 'sudo cp /path/to/ca.crt /etc/pki/ca-trust/source/anchors/ && sudo update-ca-trust'
done

3. Probar Antes de Desplegar

# Matriz de pruebas
Cliente RHEL 7 → Servidor RHEL 7 ✓
Cliente RHEL 7 → Servidor RHEL 8 ✓
Cliente RHEL 7 → Servidor RHEL 9 ✓
Cliente RHEL 8 → Servidor RHEL 7 ✓
Cliente RHEL 8 → Servidor RHEL 9 ✓
Cliente RHEL 9 → Servidor RHEL 8 ✓

4. Documentar Tu Entorno

## Matriz de Compatibilidad de Certificados

### Servidores:
- Servidor App 1: RHEL 7.9, TLS 1.0-1.2, RSA 2048
- Base de Datos: RHEL 8.10, política DEFAULT, RSA 2048
- Capa Web: RHEL 9.8, política DEFAULT, RSA 4096

### Limitaciones Conocidas:
- Los sistemas RHEL 7 requieren TLS 1.0/1.1 para app legacy X
- La base de datos requiere cifrado específico: AES256-GCM-SHA384

### Plan de Actualización:
- T1 2025: Migrar Servidor App 1 a RHEL 8
- T2 2025: Actualizar todos los certificados a RSA 4096

13.11 Conclusiones Clave

  1. Los entornos mixtos son normales - Planificar para compatibilidad
  2. TLS 1.2+ es el mínimo para sistemas modernos
  3. Firmas SHA-256+ requeridas para RHEL 8+
  4. Crypto-policies cambiaron todo (RHEL 8+)
  5. Probar en todas las versiones antes de desplegar
  6. Documentar todo - especialmente excepciones
  7. La ruta de actualización es gradual - no apresurar, probar exhaustivamente

Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ LISTA DE VERIFICACIÓN DE COMPATIBILIDAD ENTRE VERSIONES      │
├──────────────────────────────────────────────────────────────┤
│ ✅ RSA 2048+ bits                                            │
│ ✅ Firma SHA-256+                                            │
│ ✅ SANs incluidos                                            │
│ ✅ Soporte TLS 1.2+                                          │
│ ✅ Cifrados modernos                                         │
│ ✅ Confianza CA consistente                                  │
│ ✅ Probado en todas las versiones                            │
└──────────────────────────────────────────────────────────────┘

Comando de prueba:
openssl s_client -connect server:443 -tls1_2 -servername server

Verificar política (RHEL 8+):
update-crypto-policies --show

Navegación del Capítulo

Capítulo 14: Apache httpd en RHEL

Más Común: Apache (httpd) es el servidor web más ampliamente desplegado en RHEL. Domina la configuración HTTPS de Apache en todas las versiones de RHEL.


14.1 Resumen de Apache en RHEL

Nombre del Paquete: httpd Módulo SSL/TLS: mod_ssl Ubicación de Config: /etc/httpd/conf.d/ssl.conf Ruta de Certificados: /etc/pki/tls/certs/ Ruta de Claves: /etc/pki/tls/private/

Comparación de Versiones

Versión RHELVersión ApacheOpenSSLEnfoque de Config
RHEL 72.4.61.0.2kConfiguración SSL manual
RHEL 82.4.37+1.1.1kManual + crypto-policies
RHEL 92.4.53+3.5.5Crypto-policies preferido
RHEL 102.4.62+3.5.5Crypto-policies óptimo

14.2 Instalación

RHEL 7

#============================================#
# INSTALAR APACHE CON SSL (RHEL 7)
#============================================#

sudo yum install httpd mod_ssl -y
sudo systemctl enable httpd
sudo systemctl start httpd

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

# Verificar
systemctl status httpd

RHEL 8/9/10

#============================================#
# INSTALAR APACHE CON SSL (RHEL 8/9/10)
#============================================#

sudo dnf install httpd mod_ssl -y
sudo systemctl enable httpd
sudo systemctl start httpd

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

# Verificar
systemctl status httpd
ss -tlnp | grep :443  # Verificar si escucha en 443

14.3 Configuración Básica SSL

Configuración SSL Predeterminada

# Archivo principal de configuración SSL
/etc/httpd/conf.d/ssl.conf

# Directivas clave:
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

Ejemplo Completo de Virtual Host

#============================================#
# /etc/httpd/conf.d/ssl.conf
# O /etc/httpd/conf.d/mysite-ssl.conf
#============================================#

<VirtualHost *:443>
    ServerName www.example.com
    ServerAlias example.com
    DocumentRoot /var/www/html

    # Habilitar SSL/TLS
    SSLEngine on

    # Archivos de certificado
    SSLCertificateFile      /etc/pki/tls/certs/www.example.com.crt
    SSLCertificateKeyFile   /etc/pki/tls/private/www.example.com.key
    SSLCertificateChainFile /etc/pki/tls/certs/chain.crt

    # Protocolos TLS (RHEL 7 - config manual)
    SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1

    # Suite de cifrado (RHEL 7 - manual)
    SSLCipherSuite          HIGH:!aNULL:!MD5:!3DES:!RC4
    SSLHonorCipherOrder     on

    # HSTS (recomendado)
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

    # Logging
    ErrorLog  /var/log/httpd/ssl_error_log
    CustomLog /var/log/httpd/ssl_access_log combined
</VirtualHost>

14.4 Configuración Específica por Versión

RHEL 7: Configuración SSL Manual

#============================================#
# APACHE SSL - MEJORES PRÁCTICAS RHEL 7
#============================================#

<VirtualHost *:443>
    ServerName www.example.com
    SSLEngine on

    # Certificados
    SSLCertificateFile      /etc/pki/tls/certs/www.crt
    SSLCertificateKeyFile   /etc/pki/tls/private/www.key
    SSLCertificateChainFile /etc/pki/tls/certs/chain.crt

    # REQUERIDO: Deshabilitar versiones TLS antiguas manualmente
    SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1

    # REQUERIDO: Solo cifrados fuertes
    SSLCipherSuite 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
    SSLHonorCipherOrder on

    # Encabezados de seguridad
    Header always set Strict-Transport-Security "max-age=31536000"
    Header always set X-Frame-Options DENY
    Header always set X-Content-Type-Options nosniff
</VirtualHost>

RHEL 8/9/10: Integrado con Crypto-Policies

#============================================#
# APACHE SSL - RHEL 8/9/10 CON CRYPTO-POLICIES
#============================================#

<VirtualHost *:443>
    ServerName www.example.com
    SSLEngine on

    # Certificados
    SSLCertificateFile      /etc/pki/tls/certs/www.crt
    SSLCertificateKeyFile   /etc/pki/tls/private/www.key
    SSLCertificateChainFile /etc/pki/tls/certs/chain.crt

    # ¡NO NECESITAS establecer SSLProtocol o SSLCipherSuite!
    # Crypto-policies lo maneja automáticamente
    # (a menos que tengas requisitos específicos)

    # Encabezados de seguridad (aún manuales)
    Header always set Strict-Transport-Security "max-age=31536000"
    Header always set X-Frame-Options DENY
    Header always set X-Content-Type-Options nosniff
</VirtualHost>

Diferencia Clave: ¡En RHEL 8+, crypto-policies configura automáticamente versiones TLS y cifrados!

Verificar Integración con Crypto-Policy

#============================================#
# VERIFICAR CRYPTO-POLICY (RHEL 8/9/10)
#============================================#

# Verificar política actual
update-crypto-policies --show

# Ver política específica de Apache
cat /etc/crypto-policies/back-ends/httpd.config

# Apache incluye esto automáticamente
grep -r "crypto-policies" /etc/httpd/

14.5 Generación de Certificados para Apache

Flujo de Trabajo Completo

#============================================#
# GENERAR CERTIFICADO PARA APACHE (TODAS LAS VERSIONES)
#============================================#

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

# Paso 2: Establecer permisos
sudo chmod 600 /etc/pki/tls/private/www.example.com.key
sudo chown root:root /etc/pki/tls/private/www.example.com.key

# Paso 3: Generar CSR con SANs
sudo openssl req -new \
  -key /etc/pki/tls/private/www.example.com.key \
  -out /tmp/www.example.com.csr \
  -subj "/C=US/ST=State/L=City/O=Company/CN=www.example.com" \
  -addext "subjectAltName=DNS:www.example.com,DNS:example.com"

# Paso 4: Enviar CSR a CA, recibir certificado

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

# Paso 6: Si usas certificados intermedios, instalar cadena
sudo cp chain.crt /etc/pki/tls/certs/www.example.com-chain.crt

# Paso 7: Actualizar configuración de Apache (ver sección 14.3)

# Paso 8: Probar configuración
sudo apachectl configtest

# Paso 9: Recargar Apache
sudo systemctl reload httpd

# Paso 10: Probar HTTPS
curl -v https://www.example.com/
openssl s_client -connect www.example.com:443 -servername www.example.com

14.6 Integración con certmonger (¡Automatización!)

Usar certmonger con Apache

#============================================#
# AUTOMATIZAR CERTIFICADOS APACHE CON CERTMONGER
#============================================#

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

# Opción 1: FreeIPA (CA Interna)
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/www.example.com.crt \
  -k /etc/pki/tls/private/www.example.com.key \
  -D www.example.com \
  -K host/www.example.com@REALM \
  -C "systemctl reload httpd"  # ¡Auto-recargar Apache después de renovación!

# Opción 2: Let's Encrypt (RHEL 9+)
sudo getcert request \
  -c lets-encrypt \
  -f /etc/pki/tls/certs/www.example.com.crt \
  -k /etc/pki/tls/private/www.example.com.key \
  -D www.example.com \
  -C "systemctl reload httpd"

# Verificar estado
sudo getcert list

# Esperar estado MONITORING
# ¡El certificado se renueva automáticamente ~30 días antes de expirar!

Beneficios:

  • ✅ Renovación automática
  • ✅ Sin tiempo de inactividad (recarga, no reinicio)
  • ✅ Rastrea expiración
  • ✅ Alertas por email si falla

14.7 Let’s Encrypt con certbot

⚠️ IMPORTANTE: EPEL Requerido

certbot NO está disponible en repositorios oficiales de RHEL. Requiere EPEL (Extra Packages for Enterprise Linux), un repositorio mantenido por la comunidad.

Para entornos RHEL de producción, considera:

  • FreeIPA con certmonger (recomendado para RHEL)
  • Gestión manual de certificados
  • CA comercial con certmonger
#============================================#
# CONFIGURACIÓN DE CERTBOT (¡REQUIERE EPEL!)
#============================================#

# Paso 1: Habilitar EPEL (TODAS las versiones RHEL)
sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E %rhel).noarch.rpm

# O en RHEL 8/9/10:
sudo dnf install epel-release

# Paso 2: Instalar certbot
sudo dnf install certbot python3-certbot-apache

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

# Paso 4: Certbot automáticamente:
#  - Genera certificado
#  - Configura Apache
#  - Configura temporizador de renovación
#  - Habilita redirección HTTPS

# Paso 5: Probar renovación automática
sudo certbot renew --dry-run

# Verificar temporizador de renovación
systemctl list-timers | grep certbot

Pros:

  • ✅ Completamente automatizado
  • ✅ Certificados gratuitos
  • ✅ Configuración de Apache manejada automáticamente

Contras:

  • ❌ Requiere EPEL (no soportado oficialmente por Red Hat)
  • ❌ Dependencia externa (Let’s Encrypt)
  • ⚠️ El dominio debe ser públicamente accesible

14.8 Solución de Problemas de Apache HTTPS

Lista de Verificación de Problemas Comunes

#============================================#
# LISTA DE VERIFICACIÓN SOLUCIÓN DE PROBLEMAS APACHE SSL
#============================================#

# 1. Verificar si mod_ssl está cargado
sudo httpd -M | grep ssl_module
# Debería mostrar: ssl_module (shared)

# 2. Verificar sintaxis de configuración
sudo apachectl configtest
# Debería mostrar: Syntax OK

# 3. Verificar que existan archivos de certificado
ls -l /etc/pki/tls/certs/www.crt
ls -l /etc/pki/tls/private/www.key

# 4. Verificar permisos
ls -l /etc/pki/tls/private/www.key
# Debería ser: -rw------- (600)

# 5. Verificar contexto SELinux
ls -Z /etc/pki/tls/certs/www.crt
ls -Z /etc/pki/tls/private/www.key
# Debería mostrar: cert_t

# 6. Probar coincidencia par certificado/clave
CERT_MOD=$(openssl x509 -noout -modulus -in /etc/pki/tls/certs/www.crt | openssl md5)
KEY_MOD=$(openssl rsa -noout -modulus -in /etc/pki/tls/private/www.key | openssl md5)
[ "$CERT_MOD" = "$KEY_MOD" ] && echo "✅ Coincide" || echo "❌ ¡No coincide!"

# 7. Verificar si el puerto 443 está escuchando
ss -tlnp | grep :443

# 8. Verificar firewall
sudo firewall-cmd --list-services | grep https

# 9. Probar localmente
curl -vk https://localhost/

# 10. Verificar logs
sudo tail -f /var/log/httpd/ssl_error_log

Errores Comunes y Soluciones

Mensaje de ErrorCausaSolución
“SSLCertificateFile: file does not exist”Ruta incorrectaCorregir ruta en ssl.conf
“Permission denied” en archivo de clavePermisos incorrectoschmod 600 en clave
“certificate verify failed”Problema de cadenaInstalar certs intermedios
“SSLCertificateKeyFile: file does not exist”Clave faltanteGenerar o restaurar clave
“Private key does not match certificate”Desajuste cert/claveRegenerar CSR con clave correcta
“SSL Library Error”mod_ssl no cargadoInstalar paquete mod_ssl
“ca md too weak” (RHEL 9+)Firma SHA-1Reemitir con SHA-256+
“name mismatch”Hostname no coincide CN/SANCorregir SANs del certificado

14.9 Solución de Problemas Específica por Versión

Específico RHEL 7

#============================================#
# PROBLEMAS APACHE RHEL 7
#============================================#

# Problema: Navegadores modernos rechazan TLS 1.0/1.1
# Solución: Deshabilitar TLS antiguo en ssl.conf
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1

# Problema: Cifrados débiles marcados por escaneo
# Solución: Usar cifrados fuertes
SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5
SSLHonorCipherOrder on

# Problema: Sin SANs en certificado
# Solución: Reemitir con SANs (ver 13.5)

# Probar
openssl s_client -connect localhost:443 -tls1_2

Específico RHEL 8/9/10

#============================================#
# PROBLEMAS APACHE RHEL 8/9/10
#============================================#

# Problema: El servicio falla después de cambio de crypto-policy
# Diagnóstico:
update-crypto-policies --show
sudo journalctl -xe -u httpd | grep -i tls

# Solución 1: Verificar que la política sea correcta
sudo update-crypto-policies --set DEFAULT

# Solución 2: Verificar si sobrescribes manualmente la política
grep -E "SSLProtocol|SSLCipherSuite" /etc/httpd/conf.d/*.conf
# Si se encuentra, eliminar (dejar que crypto-policy lo maneje)

# Problema: Error "no shared cipher"
# Diagnóstico: Cliente muy antiguo o política muy estricta
# Solución temporal:
sudo update-crypto-policies --set LEGACY
sudo systemctl restart httpd

# Solución apropiada: Actualizar cliente o crear módulo de política personalizado

14.10 Mejores Prácticas de Seguridad

Configuración SSL Apache Fortalecida

#============================================#
# CONFIGURACIÓN SSL FORTALECIDA (TODAS LAS VERSIONES)
#============================================#

<VirtualHost *:443>
    ServerName secure.example.com

    SSLEngine on
    SSLCertificateFile      /etc/pki/tls/certs/secure.crt
    SSLCertificateKeyFile   /etc/pki/tls/private/secure.key

    # RHEL 7: Configuración TLS manual
    # SSLProtocol TLSv1.2 TLSv1.3
    # SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256
    # SSLHonorCipherOrder on

    # RHEL 8/9/10: Crypto-policies manejan lo anterior automáticamente

    # HSTS (forzar HTTPS por 1 año)
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

    # Prevenir clickjacking
    Header always set X-Frame-Options "DENY"

    # Prevenir MIME-type sniffing
    Header always set X-Content-Type-Options "nosniff"

    # Deshabilitar firma del servidor
    ServerSignature Off
    ServerTokens Prod

    # OCSP Stapling (RHEL 8/9/10)
    SSLUseStapling on
    SSLStaplingCache "shmcb:/var/run/ocsp(128000)"

    # Autenticación de certificado de cliente (opcional)
    # SSLVerifyClient require
    # SSLVerifyDepth 3
    # SSLCACertificateFile /etc/pki/tls/certs/client-ca.crt
</VirtualHost>

# Fuera de VirtualHost (configuraciones SSL globales)
SSLStaplingCache "shmcb:/var/run/ocsp(128000)"

14.11 Redirección HTTP a HTTPS

Forzar HTTPS

#============================================#
# REDIRIGIR HTTP → HTTPS
#============================================#

# Método 1: VirtualHost Separado
<VirtualHost *:80>
    ServerName www.example.com
    Redirect permanent / https://www.example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName www.example.com
    # ... configuración SSL ...
</VirtualHost>

# Método 2: mod_rewrite
<VirtualHost *:80>
    ServerName www.example.com

    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>

14.12 Probar Apache HTTPS

Pruebas Comprehensivas

#============================================#
# SUITE DE PRUEBAS APACHE HTTPS
#============================================#

# Prueba 1: Sintaxis de configuración
sudo apachectl configtest

# Prueba 2: Módulo SSL cargado
sudo httpd -M | grep ssl

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

# Prueba 4: Conexión local
curl -vk https://localhost/

# Prueba 5: Hostname real
curl -v https://www.example.com/

# Prueba 6: Validación de certificado
openssl s_client -connect www.example.com:443 -servername www.example.com

# 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: Verificar detalles del certificado desde servidor
echo | openssl s_client -connect www.example.com:443 -servername www.example.com 2>&1 | \
  openssl x509 -noout -text | head -30

# Prueba 10: Prueba online (externa)
# Usar: https://www.ssllabs.com/ssltest/

14.13 Optimización de Rendimiento

Ajuste de Rendimiento SSL/TLS

#============================================#
# AJUSTE DE RENDIMIENTO
#============================================#

<VirtualHost *:443>
    # ... configuración básica ...

    # Caché de sesión (mejora el rendimiento)
    SSLSessionCache         "shmcb:/var/cache/httpd/ssl_scache(512000)"
    SSLSessionCacheTimeout  300

    # OCSP Stapling (reduce búsqueda del lado del cliente)
    SSLUseStapling on
    SSLStaplingCache "shmcb:/var/run/ocsp(128000)"

    # Keep-Alive (reutilizar conexiones)
    KeepAlive On
    MaxKeepAliveRequests 100
    KeepAliveTimeout 5

    # HTTP/2 (RHEL 8/9/10)
    Protocols h2 h2c http/1.1
</VirtualHost>

14.14 Monitorear Apache HTTPS

Qué Monitorear

#============================================#
# MONITOREO APACHE HTTPS
#============================================#

# Expiración de certificado
openssl s_client -connect localhost:443 -servername $(hostname -f) 2>/dev/null | \
  openssl x509 -noout -dates

# Estado del servicio
systemctl status httpd

# Conteo de conexiones
ss -tn | grep :443 | wc -l

# Monitoreo de log de errores
sudo tail -f /var/log/httpd/ssl_error_log

# Estado de certmonger (si se usa)
sudo getcert list -f /etc/pki/tls/certs/www.crt

# Análisis de log de acceso
sudo tail -f /var/log/httpd/ssl_access_log | grep -E "HTTP/[12]"

14.15 Guía Rápida de Solución de Problemas

¿Apache HTTPS No Funciona?

├─ ¿Apache no inicia?
│  ├─ Verificar: apachectl configtest
│  ├─ Verificar: journalctl -xe -u httpd
│  └─ Solución: Errores de configuración
│
├─ ¿No puedes conectar al puerto 443?
│  ├─ Verificar: ss -tlnp | grep :443
│  ├─ Verificar: firewall-cmd --list-services
│  └─ Solución: Abrir firewall, iniciar httpd
│
├─ ¿Advertencias de certificado en el navegador?
│  ├─ Verificar: Expiración de certificado
│  ├─ Verificar: Coincidencia de hostname (CN/SANs)
│  ├─ Verificar: Cadena de confianza
│  └─ Solución: Renovar cert, corregir SANs, instalar CA
│
├─ ¿Error "No shared cipher"?
│  ├─ Verificar: update-crypto-policies --show
│  ├─ Verificar: Versión TLS del cliente
│  └─ Solución: Actualizar política o cliente
│
└─ ¿Errores de permisos?
   ├─ Verificar: ls -lZ /etc/pki/tls/private/*.key
   ├─ Verificar: Denegaciones SELinux
   └─ Solución: chmod 600, restorecon

14.16 Conclusiones Clave

  1. Apache + mod_ssl es el servidor web estándar de RHEL
  2. RHEL 7: Configuración TLS manual requerida
  3. RHEL 8/9/10: Crypto-policies simplifican la configuración
  4. Integración con certmonger habilita automatización
  5. certbot requiere EPEL (no soportado oficialmente)
  6. Siempre usar SANs en certificados
  7. Probar exhaustivamente antes de despliegue en producción

Tarjeta de Referencia Rápida

┌─────────────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA APACHE HTTPD HTTPS                                │
├─────────────────────────────────────────────────────────────────────┤
│ Instalar:       dnf install httpd mod_ssl                           │
│ Config:         /etc/httpd/conf.d/ssl.conf                          │
│ Certs:          /etc/pki/tls/certs/                                 │
│ Claves:         /etc/pki/tls/private/ (¡modo 600!)                  │
│                                                                     │
│ Probar config:  apachectl configtest                                │
│ Recargar:       systemctl reload httpd                              │
│ Logs:           /var/log/httpd/ssl_error_log                        │
│                                                                     │
│ certmonger:     ipa-getcert request ... -C "systemctl reload httpd" │
│ certbot:        certbot --apache (¡requiere EPEL!)                  │
│                                                                     │
│ Probar:         curl -v https://localhost/                          │
│                 openssl s_client -connect host:443                  │
└─────────────────────────────────────────────────────────────────────┘

⚠️ RHEL 8/9/10: Dejar que crypto-policies maneje config TLS/cifrado
⚠️ certbot requiere EPEL (no soportado oficialmente)

🧪 Laboratorio Práctico

Lab 06: Configuración HTTPS de Apache

Configura Apache con SSL/TLS en diferentes versiones de RHEL

  • 📁 Ubicación: labs/es_ES/06-apache-https/
  • ⏱️ Tiempo: 30-40 minutos
  • 🎯 Nivel: Intermedio

Navegación del Capítulo

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

Capítulo 16: TLS en Servidor de Correo Postfix

Seguridad del Email: Aprende cómo configurar cifrado TLS para servidores de correo Postfix en RHEL, protegiendo las comunicaciones de email con certificados.


16.1 Resumen de Postfix en RHEL

Nombre del Paquete: postfix Ubicación de Config: /etc/postfix/main.cf Ruta de Certificados: /etc/pki/tls/certs/ Ruta de Claves: /etc/pki/tls/private/ Puertos: 25 (SMTP), 465 (SMTPS), 587 (Submission con STARTTLS)

¿Por Qué TLS para Email?

  • Cifrar email en tránsito (prevenir escucha clandestina)
  • Autenticar servidores de correo (prevenir suplantación)
  • Cumplir requisitos de cumplimiento (HIPAA, PCI-DSS)
  • Prevenir spam/phishing (SPF, DKIM, DMARC funcionan mejor con TLS)

16.2 Instalación

Todas las Versiones RHEL

#============================================#
# INSTALAR POSTFIX
#============================================#

# Instalar Postfix
sudo dnf install postfix -y

# Detener y deshabilitar Sendmail (si está presente)
sudo systemctl stop sendmail 2>/dev/null
sudo systemctl disable sendmail 2>/dev/null

# Habilitar Postfix
sudo systemctl enable postfix
sudo systemctl start postfix

# Abrir firewall
sudo firewall-cmd --permanent --add-service=smtp
sudo firewall-cmd --permanent --add-service=smtps
sudo firewall-cmd --permanent --add-service=smtp-submission
sudo firewall-cmd --reload

# Verificar
systemctl status postfix
ss -tlnp | grep -E ':(25|465|587)'

16.3 Configuración TLS Lado Servidor

Recibir Correo con TLS (SMTPD)

#============================================#
# /etc/postfix/main.cf - TLS DE SERVIDOR (RECEPCIÓN)
#============================================#

# Archivos de certificado
smtpd_tls_cert_file = /etc/pki/tls/certs/mail.example.com.crt
smtpd_tls_key_file = /etc/pki/tls/private/mail.example.com.key
smtpd_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt

# Nivel de seguridad TLS
smtpd_tls_security_level = may  # o 'encrypt' para requerir TLS

# Logging
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes

# Caché de sesión (rendimiento)
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache

# Autenticación - solo sobre TLS
smtpd_tls_auth_only = yes

# RHEL 7: Especificar protocolos manualmente
# smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
# smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1

# RHEL 8/9/10: Crypto-policies manejan protocolos automáticamente
# (no necesitas especificar smtpd_tls_protocols)

Niveles de Seguridad Explicados:

NivelComportamientoCaso de Uso
noneTLS deshabilitadoNo recomendado
mayTLS opcional (oportunista)Estándar (compatible)
encryptTLS requeridoEntornos de alta seguridad
daneValidación basada en DNSSECConfiguraciones avanzadas

16.4 Configuración TLS Lado Cliente

Enviar Correo con TLS (SMTP)

#============================================#
# /etc/postfix/main.cf - TLS DE CLIENTE (ENVÍO)
#============================================#

# Archivos de certificado (opcional para cliente)
smtp_tls_cert_file = /etc/pki/tls/certs/mail.example.com.crt
smtp_tls_key_file = /etc/pki/tls/private/mail.example.com.key
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt

# Nivel de seguridad TLS para salida
smtp_tls_security_level = may  # o 'encrypt' para requerir

# Logging
smtp_tls_loglevel = 1

# Caché de sesión
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# RHEL 7: Especificar protocolos
# smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
# smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1

# RHEL 8/9/10: Crypto-policies lo manejan

16.5 Configuración Completa TLS de Postfix

Ejemplo de Configuración Completa

#============================================#
# CONFIGURACIÓN TLS COMPLETA DE POSTFIX
#============================================#

# 1. Generar certificado y clave
sudo openssl genpkey -algorithm RSA \
  -out /etc/pki/tls/private/mail.example.com.key \
  -pkeyopt rsa_keygen_bits:2048

sudo chmod 600 /etc/pki/tls/private/mail.example.com.key

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

# 3. Obtener certificado de CA, instalarlo
sudo cp mail.example.com.crt /etc/pki/tls/certs/
sudo chmod 644 /etc/pki/tls/certs/mail.example.com.crt

# 4. Editar /etc/postfix/main.cf
sudo vi /etc/postfix/main.cf

# Agregar configuración TLS (ver secciones 16.3 y 16.4)

# 5. Probar configuración
sudo postfix check

# 6. Recargar Postfix
sudo systemctl reload postfix

# 7. Probar SMTP TLS
openssl s_client -starttls smtp -connect mail.example.com:25

16.6 Configuración SMTPS (Puerto 465)

Habilitar Servicio SMTPS

#============================================#
# /etc/postfix/master.cf - HABILITAR SMTPS
#============================================#

# Descomentar o agregar servicio SMTPS (puerto 465)
smtps     inet  n       -       n       -       -       smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

# Recargar
sudo systemctl reload postfix

# Verificar
ss -tlnp | grep :465

Probar SMTPS

# Conectar a SMTPS (TLS inmediato, sin STARTTLS)
openssl s_client -connect mail.example.com:465

# Debería mostrar handshake TLS inmediatamente

16.7 Puerto de Submission (587) con STARTTLS

Habilitar Servicio Submission

#============================================#
# /etc/postfix/master.cf - HABILITAR SUBMISSION
#============================================#

# Descomentar o agregar servicio submission (puerto 587)
submission inet n       -       n       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

# Recargar
sudo systemctl reload postfix

# Verificar
ss -tlnp | grep :587

Probar Puerto Submission

# Probar STARTTLS en puerto 587
openssl s_client -starttls smtp -connect mail.example.com:587

# Debería mostrar:
# STARTTLS
# 220 2.0.0 Ready to start TLS

16.8 Integración con certmonger

Gestión Automatizada de Certificados para Postfix

#============================================#
# CERTMONGER + POSTFIX
#============================================#

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

# Solicitar certificado de FreeIPA
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/mail.example.com.crt \
  -k /etc/pki/tls/private/mail.example.com.key \
  -D mail.example.com \
  -K host/mail.example.com@REALM \
  -C "postfix reload"  # Auto-recargar Postfix después de renovación

# Verificar estado
sudo getcert list

# ¡Postfix usa automáticamente el certificado renovado!

16.9 Autenticación de Certificado de Cliente

Requerir Certificados de Cliente (mTLS para SMTP)

#============================================#
# /etc/postfix/main.cf - AUTENTICACIÓN CERT CLIENTE
#============================================#

# Certificados de servidor (como antes)
smtpd_tls_cert_file = /etc/pki/tls/certs/mail.crt
smtpd_tls_key_file = /etc/pki/tls/private/mail.key

# Verificación de certificado de cliente
smtpd_tls_CAfile = /etc/pki/tls/certs/client-ca.crt
smtpd_tls_ask_ccert = yes
smtpd_tls_req_ccert = yes  # Requerir cert de cliente

# Mapear certificado a usuario
smtpd_recipient_restrictions =
  permit_tls_clientcerts,
  reject

# Recargar
sudo postfix reload

Probar con certificado de cliente:

openssl s_client -starttls smtp \
  -connect mail.example.com:25 \
  -cert client.crt \
  -key client.key \
  -CAfile ca.crt

16.10 Solución de Problemas Postfix TLS

Comandos de Diagnóstico

#============================================#
# SOLUCIÓN DE PROBLEMAS POSTFIX TLS
#============================================#

# Verificar configuración de Postfix
sudo postconf | grep -i tls

# Probar sintaxis de configuración
sudo postfix check

# Ver ajustes TLS específicos
sudo postconf smtpd_tls_cert_file smtpd_tls_key_file

# Verificar que existan archivos de certificado
ls -l /etc/pki/tls/certs/mail.crt
ls -l /etc/pki/tls/private/mail.key

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

# Probar SMTP STARTTLS
openssl s_client -starttls smtp -connect mail.example.com:25

# Probar SMTPS (puerto 465)
openssl s_client -connect mail.example.com:465

# Verificar logs
sudo tail -f /var/log/maillog | grep -i tls

# Verificar cola de Postfix
mailq

# Logging verboso (para solución de problemas)
sudo postconf smtpd_tls_loglevel=2
sudo postfix reload
# Verificar /var/log/maillog para info TLS detallada

Problemas Comunes de Postfix TLS

ErrorCausaSolución
“SSL_accept error”Problema certificado/claveVerificar coincidencia par cert/clave
“No shared cipher”Incompatibilidad de cifradoVerificar crypto-policy o cliente
“certificate verify failed”Cadena de confianza rotaInstalar certs intermedios
“Permission denied” en clavePermisos incorrectoschmod 600 en archivo de clave
“TLS is required but not available”TLS no habilitadoEstablecer smtpd_tls_security_level = may
“STARTTLS failed”Problema TLS del clienteVerificar soporte TLS del cliente

16.11 Consideraciones Específicas por Versión

RHEL 7

#============================================#
# POSTFIX TLS - ESPECÍFICO RHEL 7
#============================================#

# /etc/postfix/main.cf

# DEBE especificar manualmente protocolos TLS
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1

smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1

# DEBE especificar manualmente cifrados
smtpd_tls_mandatory_ciphers = high
smtpd_tls_ciphers = high

smtp_tls_mandatory_ciphers = high
smtp_tls_ciphers = high

# Excluir cifrados débiles
smtpd_tls_mandatory_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, MD5, PSK, aECDH, EDH-DSS-DES-CBC3-SHA, EDH-RSA-DES-CBC3-SHA, KRB5-DES, CBC3-SHA

RHEL 8/9/10

#============================================#
# POSTFIX TLS - RHEL 8/9/10 CON CRYPTO-POLICIES
#============================================#

# /etc/postfix/main.cf

# Archivos de certificado
smtpd_tls_cert_file = /etc/pki/tls/certs/mail.crt
smtpd_tls_key_file = /etc/pki/tls/private/mail.key
smtpd_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt

# Ajustes TLS (¡crypto-policies manejan protocolos/cifrados!)
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_loglevel = 1

# TLS de cliente
smtp_tls_cert_file = /etc/pki/tls/certs/mail.crt
smtp_tls_key_file = /etc/pki/tls/private/mail.key
smtp_tls_security_level = may
smtp_tls_loglevel = 1

# ¡Eso es todo! Mucho más simple que RHEL 7
# crypto-policies configuran automáticamente versiones TLS y cifrados

Diferencia Clave: ¡RHEL 8+ depende de crypto-policies, haciendo la configuración mucho más simple!


16.12 Probar Postfix TLS

Suite de Pruebas Comprehensiva

#============================================#
# PRUEBAS POSTFIX TLS
#============================================#

# Prueba 1: STARTTLS en puerto 25
openssl s_client -starttls smtp -connect mail.example.com:25

# Buscar:
# - "250-STARTTLS" en capacidades del servidor
# - Handshake TLS exitoso
# - Detalles del certificado

# Prueba 2: SMTPS en puerto 465 (TLS directo)
openssl s_client -connect mail.example.com:465

# Prueba 3: Puerto submission 587 con STARTTLS
openssl s_client -starttls smtp -connect mail.example.com:587

# Prueba 4: Verificar certificado desde servidor
echo "QUIT" | openssl s_client -starttls smtp -connect mail.example.com:25 2>&1 | \
  openssl x509 -noout -subject -dates

# Prueba 5: Enviar email de prueba
echo "Test email" | mail -s "Prueba TLS" test@example.com

# Prueba 6: Verificar TLS en logs
sudo tail -f /var/log/maillog | grep TLS

# Prueba 7: Verificar si TLS se está usando
sudo postconf | grep -i tls | grep -i level

16.13 Mejores Prácticas de Seguridad

Configuración Postfix TLS Fortalecida

#============================================#
# CONFIGURACIÓN POSTFIX TLS FORTALECIDA
#============================================#

# /etc/postfix/main.cf

# TLS de servidor (recibir correo)
smtpd_tls_cert_file = /etc/pki/tls/certs/mail.crt
smtpd_tls_key_file = /etc/pki/tls/private/mail.key
smtpd_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt

# REQUERIR TLS para autenticación
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes

# TLS de cliente (enviar correo)
smtp_tls_cert_file = /etc/pki/tls/certs/mail.crt
smtp_tls_key_file = /etc/pki/tls/private/mail.key
smtp_tls_security_level = may

# RHEL 7: Deshabilitar manualmente protocolos débiles
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1

# Obligatorio para conexiones autenticadas
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1

# Ajustes de cifrado (RHEL 7)
smtpd_tls_mandatory_ciphers = high
smtpd_tls_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, MD5, PSK, aECDH, EDH-DSS-DES-CBC3-SHA, EDH-RSA-DES-CBC3-SHA, KRB5-DES, CBC3-SHA

# Caché de sesión
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# Logging mejorado (temporal para solución de problemas)
smtpd_tls_loglevel = 1
smtp_tls_loglevel = 1

# Rendimiento
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom

16.14 Dovecot IMAP/POP3 con TLS

Configuración de Dovecot

Aunque este capítulo se enfoca en Postfix (SMTP), Dovecot a menudo se ejecuta junto para IMAP/POP3:

#============================================#
# DOVECOT TLS (/etc/dovecot/conf.d/10-ssl.conf)
#============================================#

# Habilitar SSL
ssl = required

# Archivos de certificado
ssl_cert = </etc/pki/tls/certs/mail.example.com.crt
ssl_key = </etc/pki/tls/private/mail.example.com.key

# CA para verificación de cert de cliente (opcional)
#ssl_ca = </etc/pki/tls/certs/ca-bundle.crt

# RHEL 8/9/10: crypto-policies lo manejan

# Protocolos TLS (RHEL 7)
#ssl_min_protocol = TLSv1.2

# Preferencias de suite de cifrado
#ssl_cipher_list = HIGH:!aNULL:!MD5

# Recargar
sudo systemctl reload dovecot

Probar IMAPS:

openssl s_client -connect mail.example.com:993

# Probar POP3S
openssl s_client -connect mail.example.com:995

16.15 Escenarios Comunes

Escenario 1: TLS Oportunista (Estándar)

Objetivo: Aceptar conexiones cifradas y no cifradas

# /etc/postfix/main.cf
smtpd_tls_security_level = may  # TLS opcional
smtp_tls_security_level = may   # TLS opcional

# Por qué: Máxima compatibilidad
# Desventaja: Algunas conexiones pueden no estar cifradas

Escenario 2: TLS Obligatorio (Alta Seguridad)

Objetivo: Rechazar conexiones no cifradas

# /etc/postfix/main.cf
smtpd_tls_security_level = encrypt  # REQUERIR TLS
smtp_tls_security_level = encrypt   # REQUERIR TLS

# Por qué: Máxima seguridad
# Desventaja: Sistemas antiguos pueden fallar al conectar

Escenario 3: Certificado de Cliente para Relay

Objetivo: Permitir relay solo con certificado de cliente válido

# /etc/postfix/main.cf
smtpd_tls_cert_file = /etc/pki/tls/certs/mail.crt
smtpd_tls_key_file = /etc/pki/tls/private/mail.key
smtpd_tls_CAfile = /etc/pki/tls/certs/client-ca.crt

smtpd_tls_ask_ccert = yes
smtpd_tls_req_ccert = yes

smtpd_recipient_restrictions =
  permit_tls_clientcerts,
  reject_unauth_destination

# Solo clientes con cert válido de client-ca.crt pueden hacer relay

16.16 Monitorear Postfix TLS

Qué Monitorear

#============================================#
# MONITOREO POSTFIX TLS
#============================================#

# Verificar uso de TLS en logs
sudo grep "TLS connection established" /var/log/maillog | tail -20

# Contar conexiones TLS vs no-TLS
sudo grep "connect from" /var/log/maillog | grep -c "TLS"

# Verificar errores TLS
sudo grep "TLS" /var/log/maillog | grep -i error

# Monitorear expiración de certificado
openssl x509 -in /etc/pki/tls/certs/mail.crt -noout -checkend $((86400*30))

# Estado de certmonger (si se usa)
sudo getcert list -f /etc/pki/tls/certs/mail.crt

# Verificar cola de errores TLS
mailq

Script de Monitoreo

#!/bin/bash
# monitor-postfix-tls.sh

echo "=== Monitoreo TLS de Postfix ==="

# Expiración de certificado
echo "1. Expiración de Certificado:"
openssl x509 -in /etc/pki/tls/certs/mail.crt -noout -enddate

# Conexiones TLS hoy
echo ""
echo "2. Conexiones TLS Hoy:"
sudo grep "$(date '+%b %e')" /var/log/maillog | grep "TLS connection" | wc -l

# Errores TLS hoy
echo ""
echo "3. Errores TLS Hoy:"
sudo grep "$(date '+%b %e')" /var/log/maillog | grep -i "tls.*error" | tail -5

# Estado del servicio
echo ""
echo "4. Estado de Postfix:"
systemctl is-active postfix

# Puertos escuchando
echo ""
echo "5. Escuchando en:"
ss -tlnp | grep master | grep -E ':(25|465|587)'

16.17 Problemas Comunes y Soluciones

Problema 1: Certificado No Confiable por Clientes

Síntoma: Los clientes obtienen advertencias de “certificado no confiable”

Diagnóstico:

# Probar cadena de certificado
openssl s_client -starttls smtp -connect mail.example.com:25 -showcerts

# Verificar si se incluyen certificados intermedios
sudo postconf smtpd_tls_cert_file
# Debería incluir cadena completa o usar smtpd_tls_chain_files

Solución:

# Opción 1: Incluir cadena en archivo de certificado
cat server.crt intermediate.crt > /etc/pki/tls/certs/mail-chain.crt

# Actualizar configuración
sudo postconf -e 'smtpd_tls_cert_file = /etc/pki/tls/certs/mail-chain.crt'
sudo postfix reload

# Opción 2: Usar archivo de cadena separado (Postfix 3.4+)
sudo postconf -e 'smtpd_tls_chain_files = /etc/pki/tls/certs/chain.crt'

Problema 2: “Permission denied” en Clave Privada

Síntoma: Postfix no inicia, logs muestran error de permiso

Solución:

# Establecer permisos correctos
sudo chmod 600 /etc/pki/tls/private/mail.key
sudo chown root:postfix /etc/pki/tls/private/mail.key

# Corregir contexto SELinux
sudo restorecon -v /etc/pki/tls/private/mail.key

# Reiniciar Postfix
sudo systemctl restart postfix

Problema 3: TLS No Ofrecido a Clientes

Síntoma: STARTTLS no mostrado en respuesta EHLO

Diagnóstico:

# Telnet al servidor
telnet mail.example.com 25
# Escribir: EHLO test
# Debería mostrar: 250-STARTTLS

# Si no se muestra, verificar configuración
sudo postconf smtpd_tls_security_level
# Debería ser 'may' o 'encrypt', no 'none'

Solución:

sudo postconf -e 'smtpd_tls_security_level = may'
sudo postfix reload

16.18 Tabla de Comparación de Versiones

CaracterísticaRHEL 7RHEL 8RHEL 9RHEL 10
Versión Postfix2.10.x3.3.x+3.5.x+3.8.x+
OpenSSL1.0.2k1.1.1k3.5.53.5.5
Config TLSManualCrypto-policiesCrypto-policiesCrypto-policies
TLS PredeterminadoPuede incluir 1.0/1.1TLS 1.2+TLS 1.2+TLS 1.3 preferido
certmongerBásicoMejoradoSoporte ACMESoporte ACME

16.19 Script de Configuración Rápida

#!/bin/bash
# setup-postfix-tls.sh - Configuración completa Postfix TLS

DOMAIN="example.com"
HOSTNAME="mail.$DOMAIN"

echo "=== Configuración Postfix TLS para $HOSTNAME ==="

# 1. Instalar Postfix
sudo dnf install -y postfix

# 2. Generar certificado (o usar certmonger)
sudo openssl genpkey -algorithm RSA \
  -out /etc/pki/tls/private/$HOSTNAME.key \
  -pkeyopt rsa_keygen_bits:2048

sudo chmod 600 /etc/pki/tls/private/$HOSTNAME.key

# 3. Generar autofirmado para pruebas (¡reemplazar con cert apropiado!)
sudo openssl req -new -x509 -days 365 \
  -key /etc/pki/tls/private/$HOSTNAME.key \
  -out /etc/pki/tls/certs/$HOSTNAME.crt \
  -subj "/CN=$HOSTNAME" \
  -addext "subjectAltName=DNS:$HOSTNAME,DNS:smtp.$DOMAIN"

# 4. Configurar Postfix
sudo postconf -e "smtpd_tls_cert_file = /etc/pki/tls/certs/$HOSTNAME.crt"
sudo postconf -e "smtpd_tls_key_file = /etc/pki/tls/private/$HOSTNAME.key"
sudo postconf -e "smtpd_tls_security_level = may"
sudo postconf -e "smtpd_tls_auth_only = yes"
sudo postconf -e "smtpd_tls_loglevel = 1"

sudo postconf -e "smtp_tls_cert_file = /etc/pki/tls/certs/$HOSTNAME.crt"
sudo postconf -e "smtp_tls_key_file = /etc/pki/tls/private/$HOSTNAME.key"
sudo postconf -e "smtp_tls_security_level = may"

# 5. Abrir firewall
sudo firewall-cmd --permanent --add-service=smtp
sudo firewall-cmd --permanent --add-service=smtps
sudo firewall-cmd --permanent --add-service=smtp-submission
sudo firewall-cmd --reload

# 6. Iniciar Postfix
sudo systemctl enable postfix
sudo systemctl restart postfix

# 7. Probar
echo "Probando SMTP STARTTLS..."
echo "QUIT" | openssl s_client -starttls smtp -connect localhost:25 2>&1 | grep -E "(CONNECTED|subject=)"

echo "✅ ¡Configuración Postfix TLS completa!"
echo "⚠️ Reemplazar cert autofirmado con certificado apropiado de CA"

16.20 Conclusiones Clave

  1. Postfix soporta TLS en puertos 25 (STARTTLS), 465 (SMTPS), 587 (Submission)
  2. RHEL 7 requiere configuración TLS manual (protocolos, cifrados)
  3. RHEL 8+ usa crypto-policies (¡mucho más simple!)
  4. Niveles de seguridad: none, may, encrypt, dane
  5. certmonger funciona excelente con Postfix
  6. Siempre probar con openssl s_client -starttls smtp
  7. Monitorear logs para errores TLS

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA POSTFIX TLS                                │
├──────────────────────────────────────────────────────────────┤
│ Config:       /etc/postfix/main.cf                           │
│ Certs:        smtpd_tls_cert_file = /path/to/cert.crt        │
│ Claves:       smtpd_tls_key_file = /path/to/key.key          │
│ Seguridad:    smtpd_tls_security_level = may|encrypt         │
│                                                              │
│ Probar:       openssl s_client -starttls smtp -connect :25   │
│ Recargar:     postfix reload                                 │
│ Verificar:    postfix check                                  │
│ Logs:         tail -f /var/log/maillog | grep TLS            │
│                                                              │
│ Puertos:      25 (SMTP+STARTTLS)                             │
│               465 (SMTPS - TLS directo)                      │
│               587 (Submission con STARTTLS)                  │
│                                                              │
│ certmonger:   ipa-getcert ... -C "postfix reload"            │
└──────────────────────────────────────────────────────────────┘

⚠️ RHEL 7: Configuración manual de protocolo/cifrado necesaria
✅ RHEL 8/9/10: Crypto-policies manejan ajustes TLS

🧪 Laboratorio Práctico

Lab 08: TLS de Postfix

Configura TLS para servidor de correo Postfix

  • 📁 Ubicación: labs/es_ES/08-postfix-tls/
  • ⏱️ Tiempo: 30 minutos
  • 🎯 Nivel: Intermedio

Navegación del Capítulo

Capítulo 17: OpenLDAP y Servicios de Directorio

Directorio Empresarial: Aprende cómo asegurar servicios de directorio OpenLDAP con TLS/SSL en RHEL, protegiendo la autenticación de usuarios y consultas de directorio.


17.1 LDAP vs LDAPS vs STARTTLS

Tres Formas de Asegurar LDAP

MétodoPuertoCifradoCaso de Uso
LDAP389❌ NingunoLegacy, no recomendado
LDAPS636✅ TLS desde el inicioPreferido, cifrado
LDAP+STARTTLS389✅ Actualizar a TLSAlternativa a LDAPS

Recomendación: Usar LDAPS (puerto 636) para simplicidad y seguridad.


17.2 Instalación de OpenLDAP

Todas las Versiones RHEL

#============================================#
# INSTALAR SERVIDOR OPENLDAP
#============================================#

# Instalar servidor OpenLDAP
sudo dnf install openldap-servers openldap-clients -y

# Iniciar y habilitar
sudo systemctl enable slapd
sudo systemctl start slapd

# Abrir firewall
sudo firewall-cmd --permanent --add-service=ldap
sudo firewall-cmd --permanent --add-service=ldaps
sudo firewall-cmd --reload

# Verificar
systemctl status slapd
ss -tlnp | grep -E ':(389|636)'

17.3 Generar Certificados para LDAP

Requisitos del Certificado

Los certificados LDAP deben incluir:

  • CN coincidiendo con hostname del servidor LDAP
  • SANs con FQDN del servidor LDAP
  • Server Authentication key usage
  • Cadena de confianza válida
#============================================#
# GENERAR CERTIFICADO DE SERVIDOR LDAP
#============================================#

# Paso 1: Generar clave privada
sudo openssl genpkey -algorithm RSA \
  -out /etc/openldap/certs/ldap.key \
  -pkeyopt rsa_keygen_bits:2048

# Paso 2: Establecer permisos (¡importante!)
sudo chmod 600 /etc/openldap/certs/ldap.key
sudo chown ldap:ldap /etc/openldap/certs/ldap.key

# Paso 3: Generar CSR
sudo openssl req -new \
  -key /etc/openldap/certs/ldap.key \
  -out /tmp/ldap.csr \
  -subj "/CN=ldap.example.com" \
  -addext "subjectAltName=DNS:ldap.example.com,DNS:dir.example.com"

# Paso 4: Obtener certificado de CA

# Paso 5: Instalar certificado
sudo cp ldap.crt /etc/openldap/certs/
sudo chmod 644 /etc/openldap/certs/ldap.crt
sudo chown ldap:ldap /etc/openldap/certs/ldap.crt

# Paso 6: Instalar certificado CA
sudo cp ca.crt /etc/openldap/certs/
sudo chmod 644 /etc/openldap/certs/ca.crt

17.4 Configuración TLS de OpenLDAP

Método 1: cn=config (Configuración Dinámica)

#============================================#
# CONFIGURAR TLS CON cn=config (PREFERIDO)
#============================================#

# Crear archivo LDIF
cat > /tmp/tls-config.ldif << EOF
dn: cn=config
changetype: modify
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/openldap/certs/ldap.crt
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/openldap/certs/ldap.key
-
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/openldap/certs/ca.crt
-
replace: olcTLSProtocolMin
olcTLSProtocolMin: 3.2
EOF

# Aplicar configuración
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /tmp/tls-config.ldif

# Reiniciar slapd
sudo systemctl restart slapd

# Verificar
sudo slapcat -b "cn=config" | grep -i tls

Método 2: slapd.conf (Legacy)

#============================================#
# CONFIGURAR TLS CON slapd.conf (LEGACY)
#============================================#

# Editar /etc/openldap/slapd.conf

TLSCertificateFile      /etc/openldap/certs/ldap.crt
TLSCertificateKeyFile   /etc/openldap/certs/ldap.key
TLSCACertificateFile    /etc/openldap/certs/ca.crt

# RHEL 7: Especificar manualmente versión TLS
TLSProtocolMin          1.2

# Reiniciar
sudo systemctl restart slapd

17.5 Configuración de Cliente

Configurar Cliente LDAP para TLS

#============================================#
# /etc/openldap/ldap.conf - CONFIG CLIENTE
#============================================#

# URI del servidor (usar ldaps:// para puerto 636)
URI ldaps://ldap.example.com

# Certificado CA para validación
TLS_CACERT /etc/pki/tls/certs/ca-bundle.crt

# Verificación de certificado
TLS_REQCERT demand  # requerir certificado válido

# RHEL 7: Especificar versión TLS mínima
# TLS_PROTOCOL_MIN 1.2

Probar Conexión de Cliente LDAP

#============================================#
# PROBAR CONEXIÓN DE CLIENTE LDAPS
#============================================#

# Probar LDAPS (puerto 636)
ldapsearch -H ldaps://ldap.example.com:636 \
  -D "cn=admin,dc=example,dc=com" \
  -W \
  -b "dc=example,dc=com" \
  "(objectClass=*)"

# Probar LDAP con STARTTLS (puerto 389)
ldapsearch -H ldap://ldap.example.com:389 -ZZ \
  -D "cn=admin,dc=example,dc=com" \
  -W \
  -b "dc=example,dc=com"

# -ZZ fuerza STARTTLS (falla si no disponible)
# -Z intenta STARTTLS (continúa sin él si no disponible)

17.6 Integración con FreeIPA

Nota: FreeIPA se cubre en detalle en el Capítulo 19. Esto es un resumen rápido.

FreeIPA Maneja LDAPS Automáticamente

#============================================#
# LDAPS DE FREEIPA (¡AUTOMÁTICO!)
#============================================#

# FreeIPA configura LDAPS automáticamente
# ¡No se necesita configuración manual de certificado!

# Probar LDAPS de FreeIPA
ldapsearch -H ldaps://ipa.example.com:636 \
  -D "uid=admin,cn=users,cn=accounts,dc=example,dc=com" \
  -W \
  -b "dc=example,dc=com"

# Certificados de FreeIPA gestionados por certmonger automáticamente
sudo getcert list | grep -A10 "Directory Server"

17.7 Probar OpenLDAP TLS

Pruebas Comprehensivas

#============================================#
# PRUEBAS OPENLDAP TLS
#============================================#

# Prueba 1: Verificar si slapd está escuchando
ss -tlnp | grep slapd
# Debería mostrar puertos 389 y/o 636

# Prueba 2: Probar conexión LDAPS con OpenSSL
openssl s_client -connect ldap.example.com:636

# Buscar:
# - Handshake TLS exitoso
# - Detalles del certificado
# - Verify return code: 0 (ok)

# Prueba 3: Probar con ldapsearch (anónimo)
ldapsearch -H ldaps://ldap.example.com:636 \
  -x -b "" -s base "(objectClass=*)" namingContexts

# Prueba 4: Probar consulta autenticada
ldapsearch -H ldaps://ldap.example.com:636 \
  -D "cn=admin,dc=example,dc=com" \
  -W \
  -b "dc=example,dc=com" \
  "(uid=*)"

# Prueba 5: Probar STARTTLS
ldapsearch -H ldap://ldap.example.com:389 -ZZ \
  -x -b "" -s base

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

17.8 Solución de Problemas OpenLDAP TLS

Comandos de Diagnóstico

#============================================#
# DIAGNÓSTICO OPENLDAP TLS
#============================================#

# Verificar configuración de slapd
sudo slapcat -b "cn=config" | grep -i tls

# Verificar archivos de certificado
sudo ls -lZ /etc/openldap/certs/

# Verificar permisos
# La clave debería ser legible por el usuario 'ldap'
sudo -u ldap cat /etc/openldap/certs/ldap.key >/dev/null && \
  echo "✅ Clave legible" || echo "❌ Permission denied"

# Verificar contexto SELinux
ls -Z /etc/openldap/certs/*.{crt,key}

# Verificar logs de slapd
sudo journalctl -u slapd -f

# Probar con OpenSSL verboso
openssl s_client -connect ldap.example.com:636 -showcerts -debug

# Probar STARTTLS
ldapsearch -H ldap://ldap.example.com:389 -ZZ -d 1

Problemas Comunes de OpenLDAP TLS

ErrorCausaSolución
“TLS: can’t connect”Certificado/clave no legibleVerificar ownership: chown ldap:ldap
“TLS: hostname does not match”Desajuste CN/SANRegenerar cert con hostname correcto
“Certificate verification failed”CA no confiableAgregar CA al almacén de confianza del cliente
“Permission denied” en claveOwnership/permisos incorrectoschmod 600, chown ldap:ldap
“TLS engine not initialized”TLS no configuradoAgregar directivas TLS a configuración
“error:14094410:SSL routines”Desajuste protocolo/cifradoVerificar crypto-policy (RHEL 8+)

17.9 Autenticación de Certificado de Cliente

Requerir Certificados de Cliente

#============================================#
# OPENLDAP CON AUTENTICACIÓN CERT CLIENTE
#============================================#

# Configuración de servidor (cn=config)
cat > /tmp/client-cert.ldif << EOF
dn: cn=config
changetype: modify
add: olcTLSVerifyClient
olcTLSVerifyClient: demand
-
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/openldap/certs/client-ca.crt
EOF

sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /tmp/client-cert.ldif

# Reiniciar
sudo systemctl restart slapd

Conexión de cliente con certificado:

# El cliente debe proporcionar certificado
ldapsearch -H ldaps://ldap.example.com:636 \
  -x -b "dc=example,dc=com" \
  -ZZ

# Configurar cert de cliente en /etc/openldap/ldap.conf:
TLS_CERT /etc/openldap/certs/client.crt
TLS_KEY /etc/openldap/certs/client.key

17.10 Consideraciones Específicas por Versión

RHEL 7

#============================================#
# OPENLDAP TLS - RHEL 7
#============================================#

# Especificación manual de protocolo TLS
# En slapd.conf o cn=config:
TLSProtocolMin 1.2

# O con cn=config:
olcTLSProtocolMin: 3.2  # 3.1=TLS1.0, 3.2=TLS1.1, 3.3=TLS1.2

# Configuración manual de cifrado
TLSCipherSuite HIGH:!aNULL:!MD5:!3DES

# Probar
openssl s_client -connect ldap.example.com:636 -tls1_2

RHEL 8/9/10

#============================================#
# OPENLDAP TLS - RHEL 8/9/10
#============================================#

# Crypto-policies configuran TLS automáticamente
# ¡No necesitas especificar TLSProtocolMin o cifrados!

# Solo configurar certificados:
olcTLSCertificateFile: /etc/openldap/certs/ldap.crt
olcTLSCertificateKeyFile: /etc/openldap/certs/ldap.key
olcTLSCACertificateFile: /etc/openldap/certs/ca.crt

# Crypto-policy maneja el resto
update-crypto-policies --show

17.11 certmonger con OpenLDAP

Gestión Automatizada de Certificados

#============================================#
# CERTMONGER + OPENLDAP
#============================================#

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

# Solicitar certificado de FreeIPA
sudo ipa-getcert request \
  -f /etc/openldap/certs/ldap.crt \
  -k /etc/openldap/certs/ldap.key \
  -D ldap.example.com \
  -K ldap/ldap.example.com@REALM \
  -C "systemctl restart slapd"  # Reiniciar slapd después de renovación

# Establecer ownership apropiado
sudo chown ldap:ldap /etc/openldap/certs/ldap.{crt,key}
sudo chmod 600 /etc/openldap/certs/ldap.key

# Monitorear
sudo getcert list

17.12 Solución de Problemas LDAPS

Pasos de Diagnóstico

#============================================#
# SOLUCIÓN DE PROBLEMAS LDAPS
#============================================#

# Paso 1: Verificar que slapd está escuchando en 636
ss -tlnp | grep 636

# Paso 2: Verificar configuración de certificado
sudo slapcat -b "cn=config" | grep olcTLS

# Paso 3: Probar archivo de certificado
sudo openssl x509 -in /etc/openldap/certs/ldap.crt -noout -text

# Paso 4: Probar archivo de clave
sudo openssl rsa -in /etc/openldap/certs/ldap.key -check

# Paso 5: Verificar coincidencia cert/clave
CERT_MOD=$(openssl x509 -noout -modulus -in /etc/openldap/certs/ldap.crt | openssl md5)
KEY_MOD=$(openssl rsa -noout -modulus -in /etc/openldap/certs/ldap.key | openssl md5)
[ "$CERT_MOD" = "$KEY_MOD" ] && echo "✅ Coincide" || echo "❌ ¡Desajuste!"

# Paso 6: Verificar permisos
ls -l /etc/openldap/certs/
# La clave debería ser propiedad de ldap:ldap con modo 600

# Paso 7: Probar conexión
openssl s_client -connect ldap.example.com:636

# Paso 8: Verificar logs
sudo journalctl -u slapd | grep -i tls

# Paso 9: Probar desde cliente
ldapsearch -H ldaps://ldap.example.com:636 -x -b "" -s base

# Paso 10: Verificar SELinux
sudo ausearch -m avc -ts recent | grep ldap

17.13 Problemas Comunes y Soluciones

Problema 1: Error “TLS: can’t accept”

Síntoma: Conexión LDAPS rechazada

Diagnóstico:

sudo journalctl -u slapd | grep "TLS: can't accept"

Causas y Soluciones:

# Causa 1: Clave no legible por usuario ldap
sudo chown ldap:ldap /etc/openldap/certs/ldap.key
sudo chmod 600 /etc/openldap/certs/ldap.key

# Causa 2: Bloqueo de SELinux
sudo restorecon -Rv /etc/openldap/certs/
# O verificar denegaciones:
sudo ausearch -m avc -ts recent | grep ldap

# Causa 3: Desajuste certificado/clave
# Regenerar CSR con clave correcta

Problema 2: “TLS: hostname does not match”

Síntoma: El cliente obtiene error de desajuste de hostname

Diagnóstico:

# Verificar CN y SANs del certificado
openssl x509 -in /etc/openldap/certs/ldap.crt -noout -subject -ext subjectAltName

Solución:

# Reemitir certificado con hostname correcto en SANs
openssl req -new -key /etc/openldap/certs/ldap.key -out /tmp/ldap.csr \
  -subj "/CN=ldap.example.com" \
  -addext "subjectAltName=DNS:ldap.example.com,DNS:ldap,IP:10.0.0.10"

# O en el lado del cliente: permitir verificación más laxa (NO recomendado para producción)
# En /etc/openldap/ldap.conf:
TLS_REQCERT allow  # en lugar de 'demand'

Problema 3: Certificado No Confiable

Síntoma: “Certificate verification failed”

Solución:

# Agregar CA al almacén de confianza del sistema
sudo cp ldap-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

# O especificar CA en configuración de cliente
# /etc/openldap/ldap.conf:
TLS_CACERT /etc/openldap/certs/ca.crt

17.14 Mejores Prácticas de Seguridad

Configuración OpenLDAP TLS Fortalecida

#============================================#
# CONFIGURACIÓN LDAP TLS FORTALECIDA (cn=config)
#============================================#

dn: cn=config
changetype: modify
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/openldap/certs/ldap.crt
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/openldap/certs/ldap.key
-
replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/openldap/certs/ca.crt
-
replace: olcTLSProtocolMin
olcTLSProtocolMin: 3.3
-
replace: olcTLSCipherSuite
olcTLSCipherSuite: HIGH:!aNULL:!MD5:!RC4
-
add: olcTLSVerifyClient
olcTLSVerifyClient: never

Aplicar:

sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f hardened-tls.ldif
sudo systemctl restart slapd

17.15 Integración con Servicios del Sistema

SSSD con LDAPS (Autenticación del Sistema)

#============================================#
# CONFIGURAR SSSD PARA USAR LDAPS
#============================================#

# /etc/sssd/sssd.conf

[domain/example.com]
id_provider = ldap
auth_provider = ldap
ldap_uri = ldaps://ldap.example.com:636
ldap_search_base = dc=example,dc=com
ldap_tls_cacert = /etc/pki/tls/certs/ca-bundle.crt
ldap_tls_reqcert = demand

# Reiniciar SSSD
sudo systemctl restart sssd

# Probar
id ldapuser@example.com

17.16 Monitorear LDAP TLS

Comandos de Monitoreo

#============================================#
# MONITOREAR LDAP TLS
#============================================#

# Verificar expiración de certificado
openssl s_client -connect ldap.example.com:636 2>/dev/null | \
  openssl x509 -noout -dates

# Verificar conexiones TLS
sudo journalctl -u slapd | grep "TLS established"

# Contar conexiones LDAPS vs LDAP
sudo journalctl -u slapd --since today | grep -c "conn=.*LDAPS"
sudo journalctl -u slapd --since today | grep -c "conn=.*LDAP"

# Verificar errores TLS
sudo journalctl -u slapd | grep -i "tls.*error"

# Estado de certmonger (si se usa)
sudo getcert list -d /etc/openldap/certs

17.17 Conclusiones Clave

  1. LDAPS (puerto 636) es más simple que STARTTLS
  2. Ownership del certificado crítico - Debe ser legible por usuario ldap
  3. cn=config preferido sobre slapd.conf (RHEL moderno)
  4. FreeIPA maneja LDAPS automáticamente - ¡Mucho más fácil!
  5. Configuración de cliente importa - Establecer TLS_CACERT correctamente
  6. Probar exhaustivamente - Usar openssl s_client y ldapsearch -ZZ
  7. certmonger automatiza renovación de certificados

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA OPENLDAP TLS                               │
├──────────────────────────────────────────────────────────────┤
│ Config:        cn=config (dinámico) o slapd.conf (legacy)    │
│ Certs:         /etc/openldap/certs/                          │
│ Ownership:     chown ldap:ldap *.{crt,key}                   │
│ Permisos:      chmod 600 ldap.key                            │
│                                                              │
│ LDAPS:         Puerto 636 (TLS desde inicio)                 │
│ STARTTLS:      Puerto 389 (actualizar a TLS)                 │
│                                                              │
│ Probar LDAPS:  openssl s_client -connect host:636            │
│ Probar STLS:   ldapsearch -H ldap://host:389 -ZZ             │
│                                                              │
│ Cliente:       /etc/openldap/ldap.conf                       │
│                TLS_CACERT /path/to/ca.crt                    │
│                TLS_REQCERT demand                            │
│                                                              │
│ Logs:          journalctl -u slapd | grep TLS                │
└──────────────────────────────────────────────────────────────┘

⚠️ ¡La clave debe ser propiedad del usuario 'ldap'!
✅ Usar FreeIPA para gestión LDAP+TLS más fácil

🧪 Laboratorio Práctico

Lab 09: LDAPS de OpenLDAP

Configura LDAPS para servicios de directorio seguros

  • 📁 Ubicación: labs/es_ES/09-openldap-ldaps/
  • ⏱️ Tiempo: 35-40 minutos
  • 🎯 Nivel: Intermedio

Navegación del Capítulo

Capítulo 18: TLS en Bases de Datos (PostgreSQL, MySQL)

Datos en Tránsito: Protege las conexiones de base de datos con cifrado TLS. Aprende cómo configurar PostgreSQL y MySQL/MariaDB con certificados en RHEL.


18.1 ¿Por Qué TLS en Bases de Datos?

Proteger Datos Sensibles:

  • ✅ Cifrar consultas y resultados de base de datos
  • ✅ Prevenir escucha clandestina de credenciales
  • ✅ Autenticar servidores de bases de datos
  • ✅ Habilitar autenticación de certificado de cliente
  • ✅ Cumplir requisitos de cumplimiento (PCI-DSS, HIPAA)

Modelo de Amenaza:

  • Sin TLS: Contraseñas y datos viajan en texto claro
  • Con TLS: Toda comunicación cifrada

18.2 PostgreSQL con SSL/TLS

Instalación

#============================================#
# INSTALAR POSTGRESQL
#============================================#

# RHEL 7/8/9/10
sudo dnf install postgresql-server -y

# Inicializar base de datos
sudo postgresql-setup --initdb

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

# Verificar
systemctl status postgresql
ss -tlnp | grep 5432

Generar Certificados PostgreSQL

#============================================#
# GENERAR CERTIFICADOS POSTGRESQL
#============================================#

# Paso 1: Generar clave del servidor
sudo -u postgres openssl genpkey -algorithm RSA \
  -out /var/lib/pgsql/data/server.key \
  -pkeyopt rsa_keygen_bits:2048

# Paso 2: Establecer permisos (¡crítico!)
sudo chmod 600 /var/lib/pgsql/data/server.key
sudo chown postgres:postgres /var/lib/pgsql/data/server.key

# Paso 3: Generar CSR
sudo -u postgres openssl req -new \
  -key /var/lib/pgsql/data/server.key \
  -out /tmp/postgres.csr \
  -subj "/CN=db.example.com" \
  -addext "subjectAltName=DNS:db.example.com,DNS:postgres.example.com"

# Paso 4: Obtener certificado de CA

# Paso 5: Instalar certificado
sudo cp postgres.crt /var/lib/pgsql/data/server.crt
sudo chmod 600 /var/lib/pgsql/data/server.crt
sudo chown postgres:postgres /var/lib/pgsql/data/server.crt

# Paso 6: Instalar certificado CA
sudo cp ca.crt /var/lib/pgsql/data/root.crt
sudo chmod 644 /var/lib/pgsql/data/root.crt

Configurar PostgreSQL para SSL

#============================================#
# CONFIGURAR POSTGRESQL SSL
#============================================#

# Editar /var/lib/pgsql/data/postgresql.conf
sudo -u postgres vi /var/lib/pgsql/data/postgresql.conf

# Habilitar SSL
ssl = on

# Archivos de certificado (relativos al directorio de datos)
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
ssl_ca_file = 'root.crt'

# RHEL 7: Especificar versión TLS mínima
# ssl_min_protocol_version = 'TLSv1.2'

# RHEL 8/9/10: Usa crypto-policy del sistema
# (no necesitas especificar ssl_min_protocol_version)

# Opcional: Preferir cifrados del servidor
ssl_prefer_server_ciphers = on

# Reiniciar PostgreSQL
sudo systemctl restart postgresql

Configurar Autenticación de Cliente

#============================================#
# /var/lib/pgsql/data/pg_hba.conf
#============================================#

# Requerir SSL para todas las conexiones
hostssl all all 0.0.0.0/0 md5

# Requerir certificado de cliente
hostssl all alice 0.0.0.0/0 cert clientcert=verify-full

# Recargar configuración
sudo systemctl reload postgresql

Tipos HBA:

  • host: Permitir sin SSL
  • hostssl: Requerir SSL
  • hostnossl: Prohibir explícitamente SSL

Opciones de Cert de Cliente:

  • md5: SSL requerido, autenticación por contraseña
  • cert: SSL + certificado de cliente requerido
  • clientcert=verify-full: Verificar cert de cliente contra CA

Probar PostgreSQL SSL

#============================================#
# PROBAR POSTGRESQL SSL
#============================================#

# Prueba 1: Conectar con SSL requerido
psql "host=db.example.com port=5432 user=testuser dbname=testdb sslmode=require"

# Prueba 2: Conectar con verificación completa
psql "host=db.example.com port=5432 user=testuser dbname=testdb sslmode=verify-full sslrootcert=/etc/pki/tls/certs/ca-bundle.crt"

# Prueba 3: Con certificado de cliente
psql "host=db.example.com port=5432 user=alice dbname=mydb sslmode=verify-full sslcert=/home/alice/.postgresql/client.crt sslkey=/home/alice/.postgresql/client.key sslrootcert=/etc/pki/tls/certs/ca-bundle.crt"

# Prueba 4: Verificar SSL desde dentro de PostgreSQL
psql -h db.example.com -U testuser -d testdb -c "SELECT ssl, version FROM pg_stat_ssl WHERE pid = pg_backend_pid();"

# Prueba 5: Prueba OpenSSL
openssl s_client -connect db.example.com:5432 -starttls postgres

Modos SSL:

  • disable: Sin SSL
  • allow: Intentar SSL, volver a no-SSL
  • prefer: Preferir SSL, fallback permitido
  • require: Requerir SSL (no verificar cert)
  • verify-ca: Requerir SSL, verificar CA
  • verify-full: Requerir SSL, verificar hostname + CA

18.3 MySQL/MariaDB con SSL/TLS

Instalación

#============================================#
# INSTALAR MARIADB (REEMPLAZO MYSQL EN RHEL 8+)
#============================================#

# RHEL 8/9/10
sudo dnf install mariadb-server -y

# Iniciar y habilitar
sudo systemctl enable mariadb
sudo systemctl start mariadb

# Instalación segura
sudo mysql_secure_installation

# Verificar
systemctl status mariadb
ss -tlnp | grep 3306

Generar Certificados MySQL/MariaDB

#============================================#
# GENERAR CERTIFICADOS MYSQL/MARIADB
#============================================#

# Crear directorio de certificados
sudo mkdir -p /etc/mysql/certs
sudo chmod 755 /etc/mysql/certs

# Paso 1: Generar clave del servidor
sudo openssl genpkey -algorithm RSA \
  -out /etc/mysql/certs/server.key \
  -pkeyopt rsa_keygen_bits:2048

sudo chmod 600 /etc/mysql/certs/server.key
sudo chown mysql:mysql /etc/mysql/certs/server.key

# Paso 2: Generar CSR
sudo openssl req -new \
  -key /etc/mysql/certs/server.key \
  -out /tmp/mysql.csr \
  -subj "/CN=db.example.com" \
  -addext "subjectAltName=DNS:db.example.com,DNS:mysql.example.com"

# Paso 3: Obtener certificado de CA

# Paso 4: Instalar certificado y CA
sudo cp mysql.crt /etc/mysql/certs/server.crt
sudo cp ca.crt /etc/mysql/certs/ca.crt
sudo chmod 644 /etc/mysql/certs/{server.crt,ca.crt}
sudo chown mysql:mysql /etc/mysql/certs/{server.crt,ca.crt}

Configurar MySQL/MariaDB para SSL

#============================================#
# CONFIGURAR MYSQL/MARIADB SSL
#============================================#

# Editar /etc/my.cnf.d/server.cnf (o /etc/my.cnf)
sudo vi /etc/my.cnf.d/server.cnf

[mysqld]
# Configuración SSL/TLS
ssl-ca=/etc/mysql/certs/ca.crt
ssl-cert=/etc/mysql/certs/server.crt
ssl-key=/etc/mysql/certs/server.key

# Requerir transporte seguro (opcional, fuerza TLS para todos)
require_secure_transport=ON

# RHEL 7: Especificar versión TLS
# tls_version=TLSv1.2,TLSv1.3

# Reiniciar MySQL/MariaDB
sudo systemctl restart mariadb

Verificar que SSL está Habilitado

#============================================#
# VERIFICAR MYSQL SSL
#============================================#

# Conectar y verificar estado SSL
mysql -u root -p -e "SHOW VARIABLES LIKE '%ssl%';"

# Debería mostrar:
# have_ssl           | YES
# ssl_ca             | /etc/mysql/certs/ca.crt
# ssl_cert           | /etc/mysql/certs/server.crt
# ssl_key            | /etc/mysql/certs/server.key

# Verificar conexiones activas
mysql -u root -p -e "SHOW STATUS LIKE 'Ssl_cipher';"

Probar Conexión SSL MySQL

#============================================#
# PROBAR CONEXIÓN SSL MYSQL
#============================================#

# Conectar con SSL
mysql --ssl-ca=/etc/mysql/certs/ca.crt \
  --ssl-mode=REQUIRED \
  -h db.example.com \
  -u testuser \
  -p

# Verificar SSL en uso
mysql> \s
# Buscar: "SSL: Cipher in use is ..."

# O verificar desde línea de comandos
mysql -h db.example.com -u testuser -p -e "STATUS" | grep SSL

18.4 Autenticación de Certificado de Cliente

PostgreSQL con Certificados de Cliente

#============================================#
# AUTENTICACIÓN CERT CLIENTE POSTGRESQL
#============================================#

# Lado servidor: pg_hba.conf
hostssl all alice 0.0.0.0/0 cert clientcert=verify-full

# Generar certificado de cliente
openssl genpkey -algorithm RSA -out alice.key -pkeyopt rsa_keygen_bits:2048
openssl req -new -key alice.key -out alice.csr -subj "/CN=alice"
# Obtener firmado por CA

# Conexión de cliente
psql "host=db.example.com user=alice dbname=mydb sslmode=verify-full sslcert=alice.crt sslkey=alice.key sslrootcert=ca.crt"

MySQL/MariaDB con Certificados de Cliente

#============================================#
# AUTENTICACIÓN CERT CLIENTE MYSQL/MARIADB
#============================================#

# Crear usuario requiriendo X.509
mysql -u root -p << EOF
CREATE USER 'alice'@'%' REQUIRE X509;
GRANT ALL ON mydb.* TO 'alice'@'%';
FLUSH PRIVILEGES;
EOF

# Conexión de cliente
mysql --ssl-ca=ca.crt \
  --ssl-cert=alice.crt \
  --ssl-key=alice.key \
  -h db.example.com \
  -u alice \
  -p mydb

18.5 Solución de Problemas Database TLS

Solución de Problemas PostgreSQL

#============================================#
# SOLUCIÓN DE PROBLEMAS SSL POSTGRESQL
#============================================#

# Verificar que SSL está habilitado
sudo -u postgres psql -c "SHOW ssl;"
# Debería mostrar: on

# Ver ajustes SSL
sudo -u postgres psql -c "SHOW ssl_cert_file; SHOW ssl_key_file; SHOW ssl_ca_file;"

# Verificar archivos de certificado
ls -l /var/lib/pgsql/data/server.{crt,key}

# Verificar ownership
# Debería ser: postgres:postgres

# Verificar permisos
# server.key debería ser 600

# Probar conexión con depuración SSL
psql "host=db.example.com sslmode=require" -d postgres -U testuser --set=sslcompression=on

# Verificar logs de PostgreSQL
sudo tail -f /var/lib/pgsql/data/log/postgresql-*.log | grep -i ssl

Solución de Problemas MySQL/MariaDB

#============================================#
# SOLUCIÓN DE PROBLEMAS SSL MYSQL/MARIADB
#============================================#

# Verificar variables SSL
mysql -u root -p -e "SHOW VARIABLES LIKE '%ssl%';"

# Si have_ssl = NO, verificar:
# 1. Que existan archivos de certificado
ls -l /etc/mysql/certs/

# 2. Permisos
# Deberían ser legibles por usuario mysql

# 3. Reiniciar base de datos
sudo systemctl restart mariadb

# Verificar log de errores
sudo tail -f /var/log/mariadb/mariadb.log | grep -i ssl

# Probar conexión
mysql --ssl-ca=/etc/mysql/certs/ca.crt \
  --ssl-mode=REQUIRED \
  -h localhost \
  -u root \
  -p \
  -e "STATUS" | grep SSL

18.6 Problemas Comunes y Soluciones

Problema 1: PostgreSQL “Permission denied” en server.key

Síntoma: PostgreSQL no inicia, logs muestran error de permiso

Solución:

# Establecer permisos correctos
sudo chmod 600 /var/lib/pgsql/data/server.key
sudo chown postgres:postgres /var/lib/pgsql/data/server.key

# Corregir contexto SELinux
sudo restorecon -Rv /var/lib/pgsql/data/

# Reiniciar
sudo systemctl restart postgresql

Problema 2: MySQL “SSL connection error”

Diagnóstico:

# Verificar si SSL está disponible
mysql -u root -p -e "SHOW VARIABLES LIKE 'have_ssl';"
# Debería mostrar: YES

# Si muestra: DISABLED
# Verificar rutas de certificado en my.cnf

Solución:

# Verificar rutas en /etc/my.cnf.d/server.cnf
[mysqld]
ssl-ca=/etc/mysql/certs/ca.crt
ssl-cert=/etc/mysql/certs/server.crt
ssl-key=/etc/mysql/certs/server.key

# Reiniciar
sudo systemctl restart mariadb

Problema 3: Certificado de Cliente Rechazado

Síntoma: La conexión falla con cert de cliente

Solución PostgreSQL:

# Verificar pg_hba.conf
cat /var/lib/pgsql/data/pg_hba.conf | grep hostssl

# Asegurar que CA de cliente está instalada
sudo cp client-ca.crt /var/lib/pgsql/data/root.crt

# Recargar
sudo systemctl reload postgresql

Solución MySQL:

# Verificar que usuario requiere X.509
mysql -u root -p -e "SELECT user, host, ssl_type FROM mysql.user WHERE user='alice';"
# Debería mostrar: X509

# Verificar archivo CA configurado
mysql -u root -p -e "SHOW VARIABLES LIKE 'ssl_ca';"

18.7 Consideraciones Específicas por Versión

Versiones PostgreSQL en RHEL

Versión RHELPostgreSQLSoporte SSLNotas
RHEL 79.2✅ SíConfig manual versión TLS
RHEL 810.x+✅ SíCrypto-policy del sistema
RHEL 913.x+✅ SíMejorado, crypto-policy
RHEL 1015.x+✅ SíÚltimo, crypto-policy

Versiones MySQL/MariaDB en RHEL

Versión RHELBase de DatosSoporte SSLNotas
RHEL 7MariaDB 5.5✅ SíConfig manual
RHEL 8MariaDB 10.3+✅ SíCompatible crypto-policy
RHEL 9MariaDB 10.5+✅ SíTLS moderno
RHEL 10MariaDB 10.11+✅ SíÚltimas características

18.8 Consideraciones de Rendimiento

Rendimiento SSL PostgreSQL

#============================================#
# AJUSTE DE RENDIMIENTO SSL POSTGRESQL
#============================================#

# /var/lib/pgsql/data/postgresql.conf

# SSL habilitado
ssl = on

# Compresión SSL (deshabilitada por seguridad, ataque CRIME)
ssl_compression = off

# Cifrados SSL (RHEL 7 - manual)
# ssl_ciphers = 'HIGH:!aNULL:!MD5'

# RHEL 8/9/10: crypto-policy maneja cifrados

# Connection pooling ayuda (usar pgBouncer)
# Terminación SSL en proxy puede mejorar rendimiento

Rendimiento SSL MySQL

#============================================#
# RENDIMIENTO SSL MYSQL
#============================================#

# [mysqld] en /etc/my.cnf.d/server.cnf

# SSL habilitado
ssl-ca=/etc/mysql/certs/ca.crt
ssl-cert=/etc/mysql/certs/server.crt
ssl-key=/etc/mysql/certs/server.key

# Deshabilitar cifrados débiles (RHEL 7)
# tls_version=TLSv1.2,TLSv1.3
# ssl_cipher='ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256'

# RHEL 8/9/10: crypto-policy lo maneja

# Connection pooling (usar ProxySQL o similar)

18.9 Monitorear Database TLS

Monitoreo PostgreSQL

#============================================#
# MONITOREAR SSL POSTGRESQL
#============================================#

# Verificar conexiones SSL
sudo -u postgres psql -c "SELECT datname, usename, ssl, version FROM pg_stat_ssl JOIN pg_stat_activity ON pg_stat_ssl.pid = pg_stat_activity.pid;"

# Contar SSL vs no-SSL
sudo -u postgres psql -c "SELECT ssl, COUNT(*) FROM pg_stat_ssl GROUP BY ssl;"

# Verificar expiración de certificado
openssl x509 -in /var/lib/pgsql/data/server.crt -noout -checkend $((86400*30))

# Monitorear conexiones
sudo -u postgres psql -c "SELECT COUNT(*) FROM pg_stat_activity WHERE ssl = true;"

Monitoreo MySQL

#============================================#
# MONITOREAR SSL MYSQL
#============================================#

# Verificar estado SSL
mysql -u root -p -e "SHOW STATUS LIKE 'Ssl%';"

# Contar conexiones SSL
mysql -u root -p -e "SHOW STATUS LIKE 'Ssl_accepts';"

# Conexiones SSL actuales
mysql -u root -p -e "SELECT user, host, connection_type FROM information_schema.processlist WHERE connection_type = 'SSL/TLS';"

# Expiración de certificado
openssl x509 -in /etc/mysql/certs/server.crt -noout -checkend $((86400*30))

18.10 Scripts de Configuración Completos

Script de Configuración SSL PostgreSQL

#!/bin/bash
# setup-postgresql-ssl.sh

echo "=== Configuración SSL PostgreSQL ==="

# Generar cert autofirmado (¡reemplazar con cert apropiado de CA!)
sudo -u postgres openssl req -new -x509 -days 365 -nodes \
  -out /var/lib/pgsql/data/server.crt \
  -keyout /var/lib/pgsql/data/server.key \
  -subj "/CN=$(hostname -f)"

# Establecer permisos
sudo chmod 600 /var/lib/pgsql/data/server.{crt,key}
sudo chown postgres:postgres /var/lib/pgsql/data/server.{crt,key}

# Habilitar SSL en postgresql.conf
sudo -u postgres psql -c "ALTER SYSTEM SET ssl = on;"

# Reiniciar
sudo systemctl restart postgresql

# Probar
sudo -u postgres psql -c "SHOW ssl;"

echo "✅ SSL PostgreSQL habilitado"
echo "⚠️ Reemplazar cert autofirmado con certificado apropiado de CA"

18.11 Conclusiones Clave

  1. PostgreSQL y MySQL soportan SSL/TLS
  2. Ownership de archivo crítico - postgres:postgres o mysql:mysql
  3. Permisos: 600 para claves, 644 para certs
  4. pg_hba.conf controla acceso PostgreSQL (hostssl)
  5. sslmode importante para clientes PostgreSQL
  6. Certificados de cliente habilitan autenticación fuerte
  7. Probar exhaustivamente antes de forzar TLS
  8. Monitorear uso SSL - Asegurar que los clientes realmente lo usen

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA DATABASE TLS                               │
├──────────────────────────────────────────────────────────────┤
│ === POSTGRESQL ===                                           │
│ Config:       /var/lib/pgsql/data/postgresql.conf            │
│ Acceso:       /var/lib/pgsql/data/pg_hba.conf                │
│ Certs:        /var/lib/pgsql/data/server.{crt,key}           │
│ Owner:        postgres:postgres                              │
│ Habilitar:    ssl = on                                       │
│ Probar:       psql "sslmode=require"                         │
│                                                              │
│ === MYSQL/MARIADB ===                                        │
│ Config:       /etc/my.cnf.d/server.cnf                       │
│ Certs:        /etc/mysql/certs/server.{crt,key}              │
│ Owner:        mysql:mysql                                    │
│ Habilitar:    ssl-ca, ssl-cert, ssl-key en [mysqld]          │
│ Probar:       mysql --ssl-mode=REQUIRED                      │
│                                                              │
│ Permisos:     chmod 600 *.key                                │
│               chmod 644 *.crt                                │
└──────────────────────────────────────────────────────────────┘

⚠️ ¡Ownership y permisos de archivos son críticos!
✅ Usar hostssl en pg_hba.conf para requerir SSL

🧪 Laboratorio Práctico

Lab 10: TLS de PostgreSQL

Configura TLS para conexiones de base de datos PostgreSQL

  • 📁 Ubicación: labs/es_ES/10-postgresql-tls/
  • ⏱️ Tiempo: 25-30 minutos
  • 🎯 Nivel: Intermedio

Navegación del Capítulo

Capítulo 19: Servicios de Certificados FreeIPA

CA Empresarial: FreeIPA es la solución integrada de gestión de identidad y certificados de Red Hat. Es la forma recomendada de ejecutar una CA interna en RHEL.


19.1 ¿Qué es FreeIPA?

FreeIPA (Identidad, Política, Auditoría) es una solución integrada de gestión de información de seguridad que combina:

  • 🔐 Gestión de Identidad (directorio LDAP)
  • 🎫 Autenticación (Kerberos)
  • 🔏 Autoridad Certificadora (Dogtag PKI)
  • 📋 Gestión de Políticas (sudo, HBAC)
  • 🔍 DNS (integración BIND)

¿Por Qué FreeIPA para Certificados?

En lugar de:

  • ❌ Gestionar manualmente certificados por servidor
  • ❌ Costos de CA externa
  • ❌ Infraestructura PKI compleja

FreeIPA Proporciona:

  • ✅ CA interna (¡gratis!)
  • ✅ Inscripción automática de certificados
  • ✅ Renovación automática vía certmonger
  • ✅ Perfiles de certificados
  • ✅ Gestión por UI web y CLI
  • ✅ Integración con servicios RHEL

19.2 Instalación de FreeIPA (Servidor)

Prerrequisitos

#============================================#
# PRERREQUISITOS PARA SERVIDOR FREEIPA
#============================================#

# Requisitos:
# - RHEL 7/8/9/10
# - Mínimo 2 GB RAM (4 GB recomendado)
# - Hostname completamente cualificado
# - Resolución DNS apropiada
# - Dirección IP estática

# Verificar hostname
hostnamectl
# Debe mostrar FQDN: ipa.example.com

# Verificar DNS
nslookup $(hostname -f)

# Establecer hostname si es necesario
sudo hostnamectl set-hostname ipa.example.com

Instalar Servidor FreeIPA

#============================================#
# INSTALAR SERVIDOR FREEIPA
#============================================#

# Instalar paquetes
sudo dnf install ipa-server ipa-server-dns -y

# Ejecutar asistente de instalación
sudo ipa-server-install \
  --realm EXAMPLE.COM \
  --domain example.com \
  --ds-password 'DirectoryPassword123!' \
  --admin-password 'AdminPassword123!' \
  --hostname ipa.example.com \
  --setup-dns \
  --forwarder 8.8.8.8 \
  --forwarder 8.8.4.4 \
  --unattended

# La instalación toma 5-15 minutos

# Abrir firewall
sudo firewall-cmd --add-service={http,https,dns,ntp,freeipa-ldap,freeipa-ldaps,freeipa-replication} --permanent
sudo firewall-cmd --reload

# Verificar
sudo ipactl status

# Debería mostrar múltiples servicios ejecutándose:
# - Directory Service (389-ds)
# - Certificate Authority (pki-tomcatd)
# - Kerberos KDC
# - Apache Web Server
# - DNS (named)

Acceder a la UI Web de FreeIPA

# Obtener ticket Kerberos
kinit admin
# Contraseña: AdminPassword123!

# Acceder a UI Web
# https://ipa.example.com/
# Usuario: admin
# Contraseña: AdminPassword123!

19.3 Inscribir Clientes

Instalación de Cliente

#============================================#
# INSCRIBIR CLIENTE A FREEIPA
#============================================#

# En sistema cliente (web01.example.com)

# Instalar cliente IPA
sudo dnf install ipa-client -y

# Inscribir
sudo ipa-client-install \
  --domain example.com \
  --realm EXAMPLE.COM \
  --server ipa.example.com \
  --principal admin \
  --password 'AdminPassword123!' \
  --mkhomedir \
  --unattended

# Verificar
# sudo ipa-client-install --uninstall  # ¡Solo bromeando, no ejecutar esto!

# Verificar inscripción
ipa ping
# Pong!

# Verificar rastreo de certificados
sudo getcert list
# Muestra certmonger rastreando certificado de host

19.4 Solicitar Certificados de FreeIPA

Método 1: UI Web

  1. Navegar a https://ipa.example.com/
  2. Identidad → Hosts → Seleccionar host → Acciones → Nuevo Certificado
  3. O: Identidad → Servicios → Agregar servicio → Solicitar certificado

Método 2: CLI (Recomendado)

#============================================#
# SOLICITAR CERTIFICADO DE FREEIPA
#============================================#

# Para servicio HTTP en web01
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/web01.crt \
  -k /etc/pki/tls/private/web01.key \
  -K HTTP/web01.example.com@EXAMPLE.COM \
  -D web01.example.com \
  -C "systemctl reload httpd"

# Para servicio personalizado
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/myapp.crt \
  -k /etc/pki/tls/private/myapp.key \
  -K myapp/web01.example.com@EXAMPLE.COM \
  -D myapp.example.com

# Verificar estado
sudo getcert list

# Esperar estado MONITORING (cert emitido)

Método 3: ipa cert-request (Avanzado)

#============================================#
# AVANZADO: IPA CERT-REQUEST
#============================================#

# Generar CSR
openssl req -new -key server.key -out server.csr \
  -subj "/CN=server.example.com"

# Solicitar certificado vía IPA
ipa cert-request server.csr \
  --principal HTTP/server.example.com@EXAMPLE.COM

# Obtener ID de certificado de la salida
# Certificate: MIIDXTCCAkWgAwIBAgI...
# Request ID: 12345

# Recuperar certificado
ipa cert-show 12345 --out server.crt

19.5 Perfiles de Certificados

Perfiles Disponibles

#============================================#
# PERFILES DE CERTIFICADOS FREEIPA
#============================================#

# Listar perfiles disponibles
ipa certprofile-find

# Perfiles comunes:
# - caIPAserviceCert: Certificados de servicio (HTTP, LDAP, etc.)
# - IECUserRoles: Certificados de usuario
# - smimeUserCert: Certificados email S/MIME
# - caSelfSignedCert: CA autofirmada

# Ver detalles del perfil
ipa certprofile-show caIPAserviceCert

# Crear perfil personalizado
ipa certprofile-import MyCustomProfile \
  --file custom-profile.cfg \
  --store TRUE

Usar Perfil Específico

# Solicitar con perfil específico
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/custom.crt \
  -k /etc/pki/tls/private/custom.key \
  -K HTTP/web01.example.com@EXAMPLE.COM \
  -T caIPAserviceCert  # Especificar perfil

19.6 Renovación Automática

Cómo Funciona

FreeIPA + certmonger = ¡Ciclo de Vida Automático de Certificados!

#============================================#
# RENOVACIÓN AUTOMÁTICA CON FREEIPA
#============================================#

# certmonger automáticamente:
# 1. Rastrea expiración de certificado
# 2. Envía solicitud de renovación a IPA
# 3. Obtiene certificado renovado
# 4. Guarda en archivo
# 5. Ejecuta comando post-guardado (ej: reload httpd)

# Verificar estado de renovación
sudo getcert list

# Salida de ejemplo:
# Request ID '20240101000000':
#   status: MONITORING
#   stuck: no
#   key pair storage: type=FILE,location='/etc/pki/tls/private/web.key'
#   certificate: type=FILE,location='/etc/pki/tls/certs/web.crt'
#   CA: IPA
#   issuer: CN=Certificate Authority,O=EXAMPLE.COM
#   subject: CN=web01.example.com,O=EXAMPLE.COM
#   expires: 2025-01-01 00:00:00 UTC
#   pre-save command:
#   post-save command: systemctl reload httpd
#   track: yes
#   auto-renew: yes

# ¡La renovación ocurre automáticamente ~28 días antes de expirar!

Renovación Manual (Si Se Necesita)

# Forzar renovación ahora
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt

# O por ID de solicitud
sudo ipa-getcert resubmit -i 20240101000000

# Verificar si fue exitosa
sudo getcert list -f /etc/pki/tls/certs/web.crt

19.7 FreeIPA como CA Empresarial

Gestión de Certificados CA

#============================================#
# GESTIÓN CA DE FREEIPA
#============================================#

# Ver certificado CA
ipa ca-show ipa

# Exportar certificado CA
ipa ca-show ipa --certificate --out /tmp/ipa-ca.crt

# Instalar en clientes (automático durante ipa-client-install)
# Manual: Copiar a almacén de confianza
sudo cp /tmp/ipa-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

# Renovar certificado CA (cuando sea necesario)
sudo ipa-cacert-manage renew

# Verificar expiración CA
sudo getcert list -d /var/lib/ipa | grep "CA:"

Sub-CAs (Avanzado)

#============================================#
# SUB-CA DE FREEIPA (RHEL 8+)
#============================================#

# Crear sub-CA
ipa ca-add subca \
  --subject "CN=SubCA,O=EXAMPLE.COM" \
  --desc "Sub-CA de Departamento"

# Emitir certificado de sub-CA
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/dept.crt \
  -k /etc/pki/tls/private/dept.key \
  -X subca \
  -K HTTP/dept.example.com@EXAMPLE.COM

19.8 Ejemplos de Integración de Servicios

Apache con Certificados FreeIPA

#============================================#
# CONFIGURACIÓN COMPLETA APACHE + FREEIPA
#============================================#

# 1. Inscribir sistema a IPA (si aún no)
sudo ipa-client-install

# 2. Solicitar certificado para Apache
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/$(hostname -f).crt \
  -k /etc/pki/tls/private/$(hostname -f).key \
  -K HTTP/$(hostname -f)@EXAMPLE.COM \
  -D $(hostname -f) \
  -C "systemctl reload httpd"

# 3. Esperar certificado
until sudo getcert list -f /etc/pki/tls/certs/$(hostname -f).crt | grep -q "MONITORING"; do
  sleep 5
  echo "Esperando certificado..."
done

# 4. Configurar Apache para usarlo
# /etc/httpd/conf.d/ssl.conf:
# SSLCertificateFile /etc/pki/tls/certs/$(hostname -f).crt
# SSLCertificateKeyFile /etc/pki/tls/private/$(hostname -f).key

# 5. Recargar Apache
sudo systemctl reload httpd

# ¡El certificado se renueva automáticamente!

LDAP con Certificados FreeIPA

# El servicio LDAP propio de FreeIPA usa automáticamente certificados IPA
# ¡No se necesita configuración manual!

# Probar
ldapsearch -H ldaps://ipa.example.com:636 -x -b "dc=example,dc=com"

19.9 Solución de Problemas de Certificados FreeIPA

Problemas Comunes

Problema 1: CA_UNREACHABLE

# Síntoma
sudo getcert list
# status: CA_UNREACHABLE

# Diagnóstico
# 1. Verificar conectividad con servidor IPA
ipa ping

# 2. Verificar ticket Kerberos
klist

# 3. Renovar ticket si expiró
kinit -k host/$(hostname -f)@EXAMPLE.COM

# 4. Verificar servicios IPA
ssh ipa.example.com "sudo ipactl status"

# 5. Reintentar
sudo ipa-getcert resubmit -i <request-id>

Problema 2: Solicitud de Certificado Denegada

# Verificar estado de solicitud
sudo getcert list -v

# Causas comunes:
# 1. Principal de servicio no existe
ipa service-find HTTP/$(hostname -f)

# Si no se encuentra, agregarlo:
ipa service-add HTTP/$(hostname -f)

# 2. Host no inscrito
ipa host-show $(hostname -f)

# 3. Permisos insuficientes
# Debe solicitar como principal de host inscrito

Problema 3: Certificado No Renovado

# Verificar logs de certmonger
sudo journalctl -u certmonger | tail -50

# Verificar estado CA de IPA
sudo ipactl status | grep "CA"

# Forzar renovación
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt

# Verificar expiración de certificado CA
sudo openssl x509 -in /etc/ipa/ca.crt -noout -dates

19.10 Características Avanzadas

Soporte ACME (RHEL 9+)

¡FreeIPA puede actuar como servidor ACME!

#============================================#
# HABILITAR ACME EN FREEIPA (RHEL 9+)
#============================================#

# En servidor IPA (RHEL 9+)
sudo ipa-acme-manage enable

# Verificar que ACME está disponible
curl https://ipa.example.com/acme/directory

# En cliente: Usar certbot o certmonger con ACME
sudo certbot register --server https://ipa.example.com/acme/directory
sudo certbot certonly --server https://ipa.example.com/acme/directory \
  -d web01.example.com

Retención/Revocación de Certificados

#============================================#
# REVOCAR CERTIFICADOS
#============================================#

# Poner certificado en retención (temporal)
ipa cert-revoke 12345 --revocation-reason 6

# Revocar permanentemente
ipa cert-revoke 12345 --revocation-reason 1

# Razones:
# 0: unspecified
# 1: keyCompromise
# 2: cACompromise
# 4: superseded
# 6: certificateHold (puede ser removido)

# Remover de retención
ipa cert-remove-hold 12345

# Verificar estado de revocación
ipa cert-show 12345

19.11 Monitorear PKI de FreeIPA

Verificaciones de Salud

#============================================#
# MONITOREO DE SALUD PKI FREEIPA
#============================================#

# Verificar estado general de IPA
sudo ipactl status

# Verificar subsistema CA
sudo systemctl status pki-tomcatd@pki-tomcat

# Verificar expiraciones de certificados
ipa-healthcheck --source ipahealthcheck.ipa.certs

# Verificar rastreo de certificados
sudo getcert list | grep -E "(Request|status|expires)"

# Monitorear certificado CA
openssl x509 -in /etc/ipa/ca.crt -noout -dates

# Verificar certificados expirando
ipa cert-find --validnotafter-from=$(date -d '+60 days' +%Y-%m-%d)

19.12 Respaldo y Recuperación

Respaldar Servidor IPA

#============================================#
# RESPALDAR FREEIPA (INCLUYENDO CA)
#============================================#

# Respaldo completo
sudo ipa-backup --data --online

# Ubicación de respaldo
ls -lh /var/lib/ipa/backup/

# Incluir claves CA (¡solo respaldo offline!)
sudo ipactl stop
sudo ipa-backup --data --gpg
# Ingresar passphrase GPG
sudo ipactl start

Restaurar Servidor IPA

# Restaurar desde respaldo
sudo ipactl stop
sudo ipa-restore /var/lib/ipa/backup/ipa-full-YYYY-MM-DD-HH-MM-SS/
sudo ipactl start

19.13 Mejores Prácticas

Mejores Prácticas de Certificados FreeIPA

✅ Usar FreeIPA para todos los certificados internos
✅ Dejar que certmonger maneje renovación (no renovar manualmente)
✅ Usar principales de servicio (HTTP/host, ldap/host, etc.)
✅ Agregar SANs al solicitar certificados
✅ Establecer comandos post-guardado (flag -C) para recarga de servicio
✅ Monitorear salud del servidor IPA regularmente
✅ Respaldar servidor IPA semanalmente (incluyendo claves CA)
✅ Tener al menos 2 réplicas IPA (HA)
✅ Monitorear expiración de certificado CA
✅ Probar renovación de certificado antes de expirar
✅ Usar perfiles de certificados para estandarización

19.14 Ejemplos de Integración

Configuración Completa de Servicio con FreeIPA

#!/bin/bash
# setup-service-with-ipa.sh
# Flujo de trabajo completo para certificado de servicio desde FreeIPA

SERVICE_NAME="HTTP"  # O LDAP, postgresql, etc.
HOST=$(hostname -f)
PRINCIPAL="${SERVICE_NAME}/${HOST}@EXAMPLE.COM"
CERT_FILE="/etc/pki/tls/certs/${HOST}.crt"
KEY_FILE="/etc/pki/tls/private/${HOST}.key"
POST_COMMAND="systemctl reload httpd"

echo "=== Solicitando Certificado de FreeIPA ==="

# 1. Asegurar que el principal de servicio existe
if ! ipa service-show "${SERVICE_NAME}/${HOST}" &>/dev/null; then
  echo "Creando principal de servicio..."
  ipa service-add "${SERVICE_NAME}/${HOST}"
fi

# 2. Solicitar certificado
sudo ipa-getcert request \
  -f "$CERT_FILE" \
  -k "$KEY_FILE" \
  -K "$PRINCIPAL" \
  -D "$HOST" \
  -C "$POST_COMMAND"

# 3. Esperar certificado
echo "Esperando emisión de certificado..."
until sudo getcert list -f "$CERT_FILE" | grep -q "MONITORING"; do
  sleep 5
done

# 4. Verificar
echo "✅ ¡Certificado emitido!"
sudo openssl x509 -in "$CERT_FILE" -noout -subject -issuer -dates

# 5. ¡El certificado se renovará automáticamente!
echo "✅ Rastreo de certificado habilitado - renovación automática activa"

19.15 Conclusiones Clave

  1. FreeIPA es la CA interna recomendada de Red Hat
  2. Combina identidad + certificados + autenticación
  3. Integración con certmonger es automática
  4. Los certificados se renuevan automáticamente (¡sin trabajo manual!)
  5. Usar principales de servicio (HTTP/host, ldap/host)
  6. Soporte ACME en RHEL 9+ (puede reemplazar Let’s Encrypt para interno)
  7. UI Web y CLI ambos disponibles
  8. Escala a empresa - Soporta réplicas, sub-CAs

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA SERVICIOS CERTIFICADOS FREEIPA             │
├──────────────────────────────────────────────────────────────┤
│ Instalar:         dnf install ipa-server                     │
│ Configurar:       ipa-server-install                         │
│ Estado:           ipactl status                              │
│ UI Web:           https://ipa.example.com/                   │
│                                                              │
│ Inscribir:        ipa-client-install                         │
│ Solicitar:        ipa-getcert request -K service/host@REALM  │
│ Listar:           getcert list                               │
│ Reenviar:         ipa-getcert resubmit -f /path/to/cert.crt  │
│                                                              │
│ Principal:        HTTP/host.example.com@REALM                │
│                   ldap/host.example.com@REALM                │
│                   postgresql/host.example.com@REALM          │
│                                                              │
│ Renovación auto:  Automática vía certmonger                  │
│ ACME:             ipa-acme-manage enable (RHEL 9+)           │
└──────────────────────────────────────────────────────────────┘

✅ Mejor para gestión de certificados empresarial interno
✅ Completamente integrado con RHEL
✅ ¡No se necesita renovación manual!

Navegación del Capítulo

Capítulo 20: Otros Servicios RHEL con Certificados

Más Allá de lo Básico: Muchos otros servicios RHEL usan certificados. Este capítulo cubre Cockpit, servicios VPN, registros de contenedores y más.


20.1 Servicios Cubiertos

Este capítulo proporciona guías de inicio rápido para:

  • 🖥️ Cockpit (Consola de administración basada en web)
  • 🔒 OpenVPN (Servicio VPN)
  • 🛡️ strongSwan (VPN IPsec)
  • 📦 Registro de Contenedores (Registro Podman/Docker)
  • 📡 HAProxy (Balanceador de carga)
  • 🔌 Redis con TLS (usando stunnel)
  • ⚙️ Ansible Tower/AWX (Plataforma de automatización)

20.2 Consola Web Cockpit

¿Qué es Cockpit?

Cockpit es la interfaz de administración basada en web integrada de RHEL.

Predeterminado: Usa certificado autofirmado Objetivo: Reemplazar con certificado apropiado

Configurar Cockpit con Certificados

#============================================#
# COCKPIT CON CERTIFICADO APROPIADO
#============================================#

# Instalar Cockpit
sudo dnf install cockpit -y
sudo systemctl enable --now cockpit.socket

# Abrir firewall
sudo firewall-cmd --add-service=cockpit --permanent
sudo firewall-cmd --reload

# Ubicación de certificado de Cockpit
ls -l /etc/cockpit/ws-certs.d/

# Método 1: Colocar certificado con nombre específico
# Cockpit usa certificados en /etc/cockpit/ws-certs.d/
# Formato de nombre de archivo: NN-name.cert (donde NN = prioridad, menor = mayor prioridad)

sudo cat server.crt server.key > /etc/cockpit/ws-certs.d/01-server.cert
sudo chmod 644 /etc/cockpit/ws-certs.d/01-server.cert

# Reiniciar Cockpit
sudo systemctl restart cockpit.socket

# Método 2: Usar certmonger
sudo ipa-getcert request \
  -f /etc/cockpit/ws-certs.d/01-cockpit.cert \
  -k /etc/cockpit/ws-certs.d/01-cockpit.cert \
  -K HTTP/$(hostname -f)@REALM \
  -D $(hostname -f) \
  -C "systemctl restart cockpit.socket" \
  -F /etc/cockpit/ws-certs.d/01-cockpit.cert  # Cert+clave combinados

# Acceder a Cockpit
# https://server.example.com:9090/

Nota: ¡Cockpit espera cert+clave combinados en un solo archivo!


20.3 OpenVPN

Configuración de Servidor con Certificados

#============================================#
# SERVIDOR OPENVPN CON CERTIFICADOS
#============================================#

# Instalar OpenVPN (de EPEL en RHEL 7, repos en RHEL 8+)
sudo dnf install openvpn -y

# Generar u obtener certificados:
# - Certificado CA
# - Certificado de servidor + clave
# - Certificados de cliente

# /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun

ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
dh /etc/openvpn/server/dh2048.pem

tls-auth /etc/openvpn/server/ta.key 0
cipher AES-256-GCM
auth SHA256

server 10.8.0.0 255.255.255.0

# Iniciar OpenVPN
sudo systemctl enable --now openvpn-server@server

# Abrir firewall
sudo firewall-cmd --add-port=1194/udp --permanent
sudo firewall-cmd --reload

Probar OpenVPN

# Verificar si está ejecutándose
systemctl status openvpn-server@server

# Probar desde cliente
openvpn --config client.ovpn --verb 3

20.4 strongSwan IPsec VPN

Configurar con Certificados

#============================================#
# STRONGSWAN CON CERTIFICADOS
#============================================#

# Instalar
sudo dnf install strongswan -y

# Ubicaciones de certificados
# CA: /etc/strongswan/ipsec.d/cacerts/
# Certs Servidor/Cliente: /etc/strongswan/ipsec.d/certs/
# Claves privadas: /etc/strongswan/ipsec.d/private/

# Copiar certificados
sudo cp ca.crt /etc/strongswan/ipsec.d/cacerts/
sudo cp server.crt /etc/strongswan/ipsec.d/certs/
sudo cp server.key /etc/strongswan/ipsec.d/private/
sudo chmod 600 /etc/strongswan/ipsec.d/private/server.key

# /etc/strongswan/ipsec.conf
config setup
    charondebug="ike 2, knl 2, cfg 2"

conn example-ipsec
    left=%any
    leftid=@server.example.com
    leftcert=server.crt
    leftsubnet=10.0.0.0/24

    right=%any
    rightid=@client.example.com
    rightcert=client.crt

    auto=add
    type=tunnel
    keyexchange=ikev2

# Iniciar strongSwan
sudo systemctl enable --now strongswan

# Verificar estado
sudo swanctl --list-sas

20.5 Registro de Contenedores con TLS

Registro Podman/Docker

#============================================#
# REGISTRO DE CONTENEDOR CON TLS
#============================================#

# Instalar registry
sudo dnf install -y podman
sudo podman pull docker.io/library/registry:2

# Crear certificado para registry
sudo mkdir -p /etc/registry/certs
sudo openssl genpkey -algorithm RSA \
  -out /etc/registry/certs/registry.key \
  -pkeyopt rsa_keygen_bits:2048

sudo openssl req -new -x509 -days 365 \
  -key /etc/registry/certs/registry.key \
  -out /etc/registry/certs/registry.crt \
  -subj "/CN=registry.example.com" \
  -addext "subjectAltName=DNS:registry.example.com"

# Ejecutar registry con TLS
sudo podman run -d \
  --name registry \
  -p 5000:5000 \
  -v /etc/registry/certs:/certs:ro \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/registry.key \
  registry:2

# Probar
curl https://registry.example.com:5000/v2/_catalog

Configuración de Cliente

# Agregar CA del registry al almacén de confianza del sistema
sudo cp /etc/registry/certs/registry.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

# Probar pull
podman pull registry.example.com:5000/myimage:latest

20.6 Terminación TLS de HAProxy

Balanceador de Carga con TLS

#============================================#
# TERMINACIÓN TLS HAPROXY
#============================================#

# Instalar HAProxy
sudo dnf install haproxy -y

# HAProxy requiere cert+clave+cadena combinados en UN archivo
cat server.crt intermediate.crt server.key > /etc/haproxy/certs/bundle.pem
sudo chmod 600 /etc/haproxy/certs/bundle.pem

# /etc/haproxy/haproxy.cfg
frontend https-in
    bind *:443 ssl crt /etc/haproxy/certs/bundle.pem
    mode http
    default_backend web_servers

    # Forzar HTTPS
    http-request redirect scheme https unless { ssl_fc }

    # Encabezados de seguridad
    http-response set-header Strict-Transport-Security "max-age=31536000"

backend web_servers
    mode http
    balance roundrobin
    server web1 10.0.1.10:80 check
    server web2 10.0.1.11:80 check
    server web3 10.0.1.12:80 check

# Iniciar HAProxy
sudo systemctl enable --now haproxy

# Probar
curl -v https://loadbalancer.example.com/

20.7 Redis con TLS (vía stunnel)

Proxy TLS de Redis

#============================================#
# REDIS CON TLS USANDO STUNNEL
#============================================#

# Instalar Redis y stunnel
sudo dnf install redis stunnel -y

# Configurar Redis (escuchar solo en localhost)
# /etc/redis/redis.conf
bind 127.0.0.1

# Iniciar Redis
sudo systemctl enable --now redis

# Configurar stunnel
# /etc/stunnel/redis.conf
[redis-tls]
accept = 0.0.0.0:6380
connect = 127.0.0.1:6379
cert = /etc/pki/tls/certs/redis.crt
key = /etc/pki/tls/private/redis.key
CAfile = /etc/pki/tls/certs/ca-bundle.crt

# Opcional: Requerir certificados de cliente
verify = 2
CApath = /etc/pki/tls/certs/

# Iniciar stunnel
sudo systemctl enable --now stunnel@redis

# Probar
openssl s_client -connect localhost:6380
# Luego escribir: PING
# Debería responder: +PONG

20.8 Ansible Tower/AWX

Tower/AWX con Certificado Personalizado

#============================================#
# CERTIFICADO PERSONALIZADO ANSIBLE TOWER/AWX
#============================================#

# Ubicación de certificado de Tower
# /etc/tower/tower.cert
# /etc/tower/tower.key

# Reemplazar con certificado apropiado
sudo cp tower.example.com.crt /etc/tower/tower.cert
sudo cp tower.example.com.key /etc/tower/tower.key
sudo chmod 600 /etc/tower/tower.key

# Reiniciar servicios de Tower
sudo ansible-tower-service restart

# O para AWX (containerizado)
# Actualizar docker-compose.yml o secretos k8s

# Probar
curl -v https://tower.example.com/

20.9 SSH con Certificados (Avanzado)

Autenticación de Certificado SSH

Nota: ¡Diferente de claves SSH! Esto usa certificados X.509.

#============================================#
# SSH CON CERTIFICADOS X.509 (AVANZADO)
#============================================#

# Requiere: openssh-server con parche X.509 o ssh-keysign

# Generar certificado para usuario SSH
openssl genpkey -algorithm RSA -out ssh-user.key -pkeyopt rsa_keygen_bits:2048
openssl req -new -key ssh-user.key -out ssh-user.csr -subj "/CN=user@example.com"
# Obtener firmado por CA

# Configurar sshd (experimental, no estándar RHEL)
# /etc/ssh/sshd_config
# X509KeyAlgorithm x509v3-rsa2048-sha256
# X509TrustAnchor /etc/ssh/ca.crt

# Enfoque estándar: Usar claves SSH, no X.509
# El soporte X.509 SSH es limitado en RHEL

Recomendación: Usar autenticación basada en claves SSH estándar para SSH, usar X.509 para otros servicios.


20.10 Monitorear Múltiples Servicios

Verificación de Certificados Multi-Servicio

#!/bin/bash
# check-all-services.sh
# Verificar certificados para todos los servicios

echo "=== Verificación de Certificados Multi-Servicio ==="

# Apache
echo "1. Apache (puerto 443):"
timeout 3 openssl s_client -connect localhost:443 </dev/null 2>&1 | grep -E "(subject=|issuer=)" | head -2

# NGINX (si está instalado)
echo "2. NGINX (puerto 8443 o personalizado):"
timeout 3 openssl s_client -connect localhost:8443 </dev/null 2>&1 | grep -E "(subject=|issuer=)" | head -2

# Postfix
echo "3. Postfix SMTPS (puerto 465):"
timeout 3 openssl s_client -connect localhost:465 </dev/null 2>&1 | grep -E "(subject=|issuer=)" | head -2

# LDAPS
echo "4. LDAP (puerto 636):"
timeout 3 openssl s_client -connect localhost:636 </dev/null 2>&1 | grep -E "(subject=|issuer=)" | head -2

# PostgreSQL
echo "5. PostgreSQL (puerto 5432):"
sudo -u postgres psql -c "SHOW ssl;" 2>/dev/null

# Cockpit
echo "6. Cockpit (puerto 9090):"
timeout 3 openssl s_client -connect localhost:9090 </dev/null 2>&1 | grep -E "(subject=|issuer=)" | head -2

# Rastreo de certmonger
echo ""
echo "7. Certificados rastreados por certmonger:"
sudo getcert list | grep -c "Request ID"
echo "total de certificados rastreados"

echo ""
echo "=== Verificación Completa ==="

20.11 Referencias Rápidas Específicas por Servicio

Cockpit

# Instalar: dnf install cockpit
# Ubicación cert: /etc/cockpit/ws-certs.d/
# Formato: Cert+clave combinados
# Recargar: systemctl restart cockpit.socket
# Probar: https://server:9090/

OpenVPN

# Instalar: dnf install openvpn (EPEL)
# Ubicación cert: /etc/openvpn/server/
# Archivos: ca.crt, server.crt, server.key
# Iniciar: systemctl start openvpn-server@server
# Probar: openvpn --config client.ovpn

strongSwan

# Instalar: dnf install strongswan
# Ubicación cert: /etc/strongswan/ipsec.d/
# Subdirectorios: cacerts/, certs/, private/
# Iniciar: systemctl start strongswan
# Probar: swanctl --list-sas

HAProxy

# Instalar: dnf install haproxy
# Formato cert: PEM combinado (cert+clave+cadena)
# Ubicación: /etc/haproxy/certs/
# Config: bind *:443 ssl crt /path/to/bundle.pem
# Probar: curl -v https://loadbalancer/

Registro de Contenedor

# Ejecutar: podman run -d -p 5000:5000 registry:2
# Certs: Montar como volúmenes (-v)
# Variables de entorno: REGISTRY_HTTP_TLS_CERTIFICATE
#                       REGISTRY_HTTP_TLS_KEY
# Probar: curl https://registry:5000/v2/_catalog

20.12 Certificados Comodín para Múltiples Servicios

Cuándo Usar Comodines

Escenario: Múltiples subdominios en el mismo servidor

web.example.com    → Apache
api.example.com    → NGINX
admin.example.com  → Cockpit
mail.example.com   → Postfix

Solución: Usar certificado comodín *.example.com

Generar Certificado Comodín

#============================================#
# CERTIFICADO COMODÍN
#============================================#

# Generar clave
openssl genpkey -algorithm RSA -out wildcard.key -pkeyopt rsa_keygen_bits:2048

# Generar CSR
openssl req -new -key wildcard.key -out wildcard.csr \
  -subj "/CN=*.example.com" \
  -addext "subjectAltName=DNS:*.example.com,DNS:example.com"

# Enviar a CA, recibir wildcard.crt

# Usar para múltiples servicios
sudo cp wildcard.crt /etc/pki/tls/certs/
sudo cp wildcard.key /etc/pki/tls/private/
sudo chmod 600 /etc/pki/tls/private/wildcard.key

# Configurar cada servicio para usarlo
# Apache: SSLCertificateFile /etc/pki/tls/certs/wildcard.crt
# NGINX: ssl_certificate /etc/pki/tls/certs/wildcard.crt
# Postfix: smtpd_tls_cert_file = /etc/pki/tls/certs/wildcard.crt

Pros:

  • ✅ Un certificado para múltiples subdominios
  • ✅ Gestión más fácil
  • ✅ Rentable (si se compra)

Contras:

  • ⚠️ Si se compromete, afecta todos los subdominios
  • ⚠️ No funciona para multi-nivel (..example.com)
  • ⚠️ Algunas políticas de seguridad prohíben comodines

20.13 Matriz de Certificados por Servicio

Requisitos de Certificado por Servicio

ServicioCN/SANCert ClienteRenovación AutoNotas Especiales
ApacheRequeridoOpcional (mTLS)certmongerMás común
NGINXRequeridoOpcional (mTLS)certmongerAlto rendimiento
PostfixRequeridoOpcionalcertmongerSMTP/SMTPS
OpenLDAPRequeridoOpcionalcertmongerDebe ser legible por usuario ldap
PostgreSQLRequeridoOpcionalManual o scriptOwnership usuario postgres
MySQLRequeridoOpcionalManual o scriptOwnership usuario mysql
FreeIPAAutomáticoN/AAutomáticoAuto-gestionado
CockpitRequeridoNocertmongerArchivo cert+clave combinado
OpenVPNRequeridoRequeridoManualPKI complejo
strongSwanRequeridoRequeridoManualEspecífico IPsec
HAProxyRequeridoNocertmongerFormato PEM combinado
RegistryRequeridoOpcionalManualEspecífico contenedor

20.14 Guía Rápida de Solución de Problemas

Solución de Problemas TLS Genérica de Servicio

#============================================#
# SOLUCIÓN DE PROBLEMAS TLS UNIVERSAL
#============================================#

# 1. Identificar servicio y puerto
ss -tlnp | grep <servicio>

# 2. Verificar si TLS está habilitado
# (comando específico del servicio)

# 3. Probar conexión TLS
openssl s_client -connect localhost:<puerto>
# O con STARTTLS:
openssl s_client -connect localhost:<puerto> -starttls <protocolo>

# 4. Verificar archivos de certificado
ls -lZ /path/to/certs/

# 5. Verificar ownership/permisos
# - Certificado: 644, propiedad del usuario del servicio
# - Clave: 600, propiedad del usuario del servicio

# 6. Verificar configuración
# (archivo de configuración específico del servicio)

# 7. Verificar logs
sudo journalctl -u <servicio> | grep -i tls
sudo tail -f /var/log/<servicio>/ | grep -i tls

# 8. Probar desde cliente remoto
openssl s_client -connect server.example.com:<puerto>

20.15 Gestión Centralizada de Certificados

Usar certmonger para Todos los Servicios

#============================================#
# ESTRATEGIA DE GESTIÓN CENTRALIZADA DE CERTIFICADOS
#============================================#

# Rastrear todos los certificados de servicio con certmonger

# Apache
sudo ipa-getcert request -f /etc/pki/tls/certs/apache.crt \
  -k /etc/pki/tls/private/apache.key \
  -K HTTP/$(hostname -f)@REALM \
  -C "systemctl reload httpd"

# NGINX
sudo ipa-getcert request -f /etc/pki/tls/certs/nginx.crt \
  -k /etc/pki/tls/private/nginx.key \
  -K HTTP/$(hostname -f)@REALM \
  -C "systemctl reload nginx"

# Postfix
sudo ipa-getcert request -f /etc/pki/tls/certs/postfix.crt \
  -k /etc/pki/tls/private/postfix.key \
  -K smtp/$(hostname -f)@REALM \
  -C "postfix reload"

# OpenLDAP
sudo ipa-getcert request -f /etc/openldap/certs/ldap.crt \
  -k /etc/openldap/certs/ldap.key \
  -K ldap/$(hostname -f)@REALM \
  -o ldap:ldap \
  -m 600 \
  -C "systemctl restart slapd"

# Monitorear todos
sudo getcert list

Beneficios:

  • ✅ Herramienta única para todos los servicios
  • ✅ Renovación automática
  • ✅ Monitoreo centralizado
  • ✅ Enfoque consistente

20.16 Conclusiones Clave

  1. Muchos servicios usan certificados más allá de servidores web
  2. Cada servicio tiene requisitos únicos - Verificar ownership, permisos
  3. certmonger funciona con la mayoría de servicios para automatización
  4. Certificados comodín pueden simplificar configuraciones multi-servicio
  5. Probar cada servicio independientemente
  6. Rastreo centralizado con certmonger recomendado
  7. Documentar configuraciones específicas de servicio

Tarjeta de Referencia Rápida

┌───────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA CERTIFICADOS OTROS SERVICIOS                │
├───────────────────────────────────────────────────────────────┤
│ Cockpit:     /etc/cockpit/ws-certs.d/NN-name.cert             │
│              (cert+clave combinados)                          │
│                                                               │
│ OpenVPN:     /etc/openvpn/server/{ca,server}.{crt,key}        │
│              PKI complejo con certs de cliente                │
│                                                               │
│ strongSwan:  /etc/strongswan/ipsec.d/{cacerts,certs,private}/ │
│              Configuración específica IPsec                   │
│                                                               │
│ HAProxy:     PEM combinado (cert+clave+cadena en un archivo)  │
│              /etc/haproxy/certs/bundle.pem                    │
│                                                               │
│ Registry:    Variables de entorno para contenedor             │
│              REGISTRY_HTTP_TLS_CERTIFICATE/KEY                │
│                                                               │
│ Genérico:    Verificar ownership, permisos, SELinux           │
│              Probar con: openssl s_client -connect :port      │
└───────────────────────────────────────────────────────────────┘

✅ Usar certmonger para automatización donde sea posible
✅ Cada servicio tiene requisitos únicos de formato/ubicación de archivo

Navegación del Capítulo

Capítulo 21: Mejores Prácticas para Certificados de Servicios

Crítico para Operaciones: Aprende las mejores prácticas que previenen el 90% de los problemas de certificados antes de que sucedan.


21.1 El Costo de la Mala Gestión de Certificados

Impactos del mundo real:

  • ❌ Certificado expirado → Sitio web caído (pérdida de ingresos)
  • ❌ Permisos incorrectos → Servicio falla al iniciar (tiempo de inactividad)
  • ❌ Sin respaldo → Fallo de CA significa reemisión manual (horas/días)
  • ❌ Nomenclatura pobre → Confusión durante incidente (respuesta retrasada)
  • ❌ Sin monitoreo → Expiración sorpresa (respuesta de emergencia)

Este capítulo previene estos problemas.


21.2 Mejores Prácticas de Organización de Archivos

Estructura de Directorio Estándar

/etc/pki/tls/
├── certs/                      # Archivos de certificado (públicos)
│   ├── service-name.crt        # Certificados reales
│   ├── service-name-chain.crt  # Con cadena intermedia
│   └── ca-bundle.crt           # Paquete CA
│
├── private/                    # Claves privadas (¡protegidas!)
│   └── service-name.key        # Claves privadas (modo 600)
│
├── csr/                        # Solicitudes de certificado (opcional)
│   └── service-name.csr        # CSRs para rastreo
│
└── backup/                     # Respaldos (opcional pero recomendado)
    └── YYYY-MM-DD/
        ├── service-name.crt
        └── service-name.key

Convenciones de Nomenclatura

Una buena nomenclatura previene confusión:

# ✅ BUENO - Claro, descriptivo
/etc/pki/tls/certs/web01-example-com.crt
/etc/pki/tls/certs/mail-smtp-example-com.crt
/etc/pki/tls/certs/ldap-primary-example-com.crt

# ❌ MALO - Poco claro, genérico
/etc/pki/tls/certs/cert1.crt
/etc/pki/tls/certs/new.crt
/etc/pki/tls/certs/temp.crt

Patrón de nomenclatura:

[servicio]-[hostname/función]-[dominio].crt
[servicio]-[hostname/función]-[dominio].key

Ejemplos:
apache-web01-example-com.crt
nginx-www-example-com.crt
postfix-mail-example-com.crt
ldap-dir01-example-com.crt
postgresql-db-primary-example-com.crt

Estándares de Permisos de Archivo

#============================================#
# CRÍTICO: Permisos Apropiados
#============================================#

# Certificados (públicos) - legibles por todos
/etc/pki/tls/certs/*.crt           → 644 (rw-r--r--)
/etc/pki/tls/certs/                → 755 (rwxr-xr-x)

# Claves privadas (¡secretas!) - solo legibles por propietario
/etc/pki/tls/private/*.key         → 600 (rw-------)
/etc/pki/tls/private/              → 711 (rwx--x--x)

# Claves específicas de servicio - propiedad del usuario del servicio
/etc/pki/tls/private/apache.key    → 600, owner: root o apache
/etc/pki/tls/private/postgres.key  → 600, owner: postgres

Script para establecer permisos:

#!/bin/bash
# set-cert-permissions.sh
# Establece permisos apropiados en archivos de certificado

CERT_DIR="/etc/pki/tls/certs"
KEY_DIR="/etc/pki/tls/private"

# Directorio de certificados
chmod 755 "$CERT_DIR"
chmod 644 "$CERT_DIR"/*.crt 2>/dev/null

# Directorio de claves privadas
chmod 711 "$KEY_DIR"
chmod 600 "$KEY_DIR"/*.key 2>/dev/null

# Verificar
echo "Permisos de certificados:"
ls -ld "$CERT_DIR" "$CERT_DIR"/*.crt 2>/dev/null

echo ""
echo "Permisos de claves privadas:"
ls -ld "$KEY_DIR" "$KEY_DIR"/*.key 2>/dev/null

# Verificar claves excesivamente permisivas
echo ""
echo "Verificando problemas de seguridad:"
find "$KEY_DIR" -type f -not -perm 600 -ls 2>/dev/null && \
  echo "⚠️ ADVERTENCIA: ¡Algunas claves tienen permisos incorrectos!" || \
  echo "✅ Todas las claves apropiadamente protegidas"

21.3 Gestión del Ciclo de Vida de Certificados

Cronograma de Renovación

Ciclo de Vida del Certificado (validez 365 días):

Día   0: Certificado emitido
Día  30: Primer recordatorio de renovación (quedan 335 días)
Día  60: Segundo recordatorio (quedan 305 días)
Día 300: Comienza ventana crítica de renovación (quedan 65 días)
Día 330: URGENTE - Renovación necesaria (quedan 35 días)
Día 350: CRÍTICO - Renovación atrasada (quedan 15 días)
Día 365: EXPIRADO - ¡Interrupción del servicio!

Acciones Recomendadas:
- Días 300-330: Planificar y ejecutar renovación
- Días 330-350: Renovación de emergencia si se perdió
- Días 350+: Respuesta a incidente, cert temporal

Estrategias de Renovación

Estrategia 1: Automatizada (Recomendado)

# Usando certmonger (RHEL)
sudo getcert request \
  -f /etc/pki/tls/certs/web01-example-com.crt \
  -k /etc/pki/tls/private/web01-example-com.key \
  -D web.example.com \
  -K host/web.example.com@REALM \
  -C "systemctl reload httpd"  # Auto-recargar servicio

# Renovación automática ocurre a 2/3 del tiempo de vida del cert
# Cert de 365 días → renueva en día 243 (quedan 122 días)

Estrategia 2: Renovación Manual Programada

# Tarea cron para verificación manual de renovación
# /etc/cron.weekly/check-certificates

#!/bin/bash
# Verificar certificados expirando en 60 días
find /etc/pki/tls/certs/ -name "*.crt" | while read cert; do
  if openssl x509 -in "$cert" -noout -checkend $((86400*60)); then
    echo "✅ $cert: OK"
  else
    echo "⚠️ $cert: ¡Expira dentro de 60 días!"
    # Enviar alerta
    mail -s "Certificado Expirando Pronto: $cert" admin@example.com
  fi
done

Estrategia 3: Recordatorios de Calendario

# Para entornos sin automatización
# Crear entradas de calendario:
# - 90 días antes de expiración: Comenzar renovación
# - 60 días antes: Verificar renovación en progreso
# - 30 días antes: Completar renovación
# - 7 días antes: Emergencia si no está hecho

21.4 Rastreo de Metadatos de Certificados

Inventario de Certificados

Mantener un inventario de certificados (hoja de cálculo o base de datos):

Service,Hostname,Certificate_Path,Key_Path,Issuer,Issue_Date,Expiry_Date,SANs,Owner,Notes
Apache,web01,/etc/pki/tls/certs/web01-example-com.crt,/etc/pki/tls/private/web01.key,Internal CA,2024-01-01,2025-01-01,"web01.example.com,www.example.com",Juan Pérez,Producción
NGINX,web02,/etc/pki/tls/certs/web02-example-com.crt,/etc/pki/tls/private/web02.key,Let's Encrypt,2024-06-15,2024-09-15,"web02.example.com",María López,Staging

Script para generar inventario:

#!/bin/bash
# generate-cert-inventory.sh
# Crea inventario de certificados desde el sistema

echo "Service,Hostname,Certificate_Path,Issuer,Issue_Date,Expiry_Date,Days_Remaining"

# Escanear ubicaciones comunes de certificados
for cert in /etc/pki/tls/certs/*.crt /etc/httpd/conf/ssl/*.crt /etc/nginx/ssl/*.crt; do
  [ -f "$cert" ] || continue

  subject=$(openssl x509 -in "$cert" -noout -subject 2>/dev/null | sed 's/subject=//')
  issuer=$(openssl x509 -in "$cert" -noout -issuer 2>/dev/null | sed 's/issuer=//')
  notbefore=$(openssl x509 -in "$cert" -noout -startdate 2>/dev/null | cut -d= -f2)
  notafter=$(openssl x509 -in "$cert" -noout -enddate 2>/dev/null | cut -d= -f2)

  # Calcular días restantes
  expiry_epoch=$(date -d "$notafter" +%s 2>/dev/null)
  now_epoch=$(date +%s)
  days_remaining=$(( ($expiry_epoch - $now_epoch) / 86400 ))

  # Determinar servicio desde la ruta
  service="Desconocido"
  [[ "$cert" =~ httpd ]] && service="Apache"
  [[ "$cert" =~ nginx ]] && service="NGINX"

  echo "$service,$(hostname),$cert,\"$issuer\",$notbefore,$notafter,$days_remaining"
done

21.5 Respaldo y Recuperación

Qué Respaldar

Archivos críticos para respaldar:
✅ Claves privadas (archivos .key)
✅ Certificados (archivos .crt)
✅ Certificados CA
✅ Cadenas de certificados
✅ CSRs (para referencia)
✅ Archivos de configuración (Apache ssl.conf, etc.)
⚠️ NO contraseñas o frases de contraseña (almacenar separadamente en bóveda)

Script de Respaldo

#!/bin/bash
# backup-certificates.sh
# Respalda todos los certificados y claves

BACKUP_DIR="/var/backups/certificates"
DATE=$(date +%Y-%m-%d)
BACKUP_PATH="$BACKUP_DIR/$DATE"

# Crear directorio de respaldo
mkdir -p "$BACKUP_PATH"

# Respaldar certificados
echo "Respaldando certificados..."
cp -a /etc/pki/tls/certs/*.crt "$BACKUP_PATH/" 2>/dev/null

# Respaldar claves privadas (¡cifradas!)
echo "Respaldando claves privadas..."
tar czf - /etc/pki/tls/private/*.key 2>/dev/null | \
  openssl enc -aes-256-cbc -salt -out "$BACKUP_PATH/keys.tar.gz.enc" -pass pass:CHANGEME

# Respaldar archivos de configuración
echo "Respaldando configuraciones..."
cp -a /etc/httpd/conf.d/ssl.conf "$BACKUP_PATH/" 2>/dev/null
cp -a /etc/nginx/nginx.conf "$BACKUP_PATH/" 2>/dev/null

# Crear inventario
ls -lh "$BACKUP_PATH"

# Establecer permisos
chmod 700 "$BACKUP_PATH"

echo "✅ Respaldo completo: $BACKUP_PATH"
echo "⚠️ ¡Recuerda cambiar la contraseña de cifrado!"

Procedimiento de Recuperación

#============================================#
# PROCEDIMIENTO DE RECUPERACIÓN DE CERTIFICADO
#============================================#

# 1. Detener servicio afectado
sudo systemctl stop httpd

# 2. Restaurar certificado
sudo cp /var/backups/certificates/2024-11-15/web.crt /etc/pki/tls/certs/

# 3. Restaurar clave privada (descifrar)
cd /var/backups/certificates/2024-11-15/
openssl enc -aes-256-cbc -d -in keys.tar.gz.enc -pass pass:CHANGEME | \
  sudo tar xzf - -C /

# 4. Establecer permisos
sudo chmod 600 /etc/pki/tls/private/*.key
sudo chmod 644 /etc/pki/tls/certs/*.crt

# 5. Verificar archivos
sudo openssl x509 -in /etc/pki/tls/certs/web01-example-com.crt -noout -text
sudo openssl rsa -in /etc/pki/tls/private/web01-example-com.key -check

# 6. Iniciar servicio
sudo systemctl start httpd

# 7. Probar
curl -v https://localhost/

21.6 Mejores Prácticas de Seguridad

Protección de Clave Privada

#============================================#
# LISTA DE VERIFICACIÓN SEGURIDAD CLAVE PRIVADA
#============================================#

✅ Permisos: 600 (o 400 para protección extra)
✅ Ownership: Solo root o usuario del servicio
✅ Ubicación: /etc/pki/tls/private/ (modo 711)
✅ SELinux: Contexto apropiado (cert_t)
✅ Respaldo: Cifrado en reposo
✅ Nunca: Enviar por email, pegar en tickets, commit a git
✅ Nunca: Compartir entre sistemas (generar nueva)
✅ Auditar: Registrar acceso con auditd

# Verificar seguridad
ls -lZ /etc/pki/tls/private/*.key
# -rw------- root root unconfined_u:object_r:cert_t:s0 server01-example-com.key

Mejores Prácticas de Generación de Claves

#============================================#
# GENERAR CLAVES SEGURAS
#============================================#

# RSA 2048 (mínimo para RHEL 8+)
openssl genpkey -algorithm RSA -out server01-example-com.key -pkeyopt rsa_keygen_bits:2048

# RSA 4096 (recomendado para certs de larga duración)
openssl genpkey -algorithm RSA -out server01-example-com.key -pkeyopt rsa_keygen_bits:4096

# EC P-256 (moderno, más pequeño, rápido)
openssl genpkey -algorithm EC -out server01-example-com.key -pkeyopt ec_paramgen_curve:P-256

# ¡Establecer permisos inmediatamente!
chmod 600 server.key

# ❌ NUNCA hacer esto:
# openssl genrsa -out server01-example-com.key 1024   # ¡Muy débil!
# chmod 644 server01-example-com.key                  # ¡Muy permisivo!

Validación de Certificado Antes de Despliegue

#!/bin/bash
# validate-certificate.sh
# Valida certificado antes de despliegue

CERT=$1
KEY=$2

echo "=== Validación de Certificado Pre-Despliegue ==="

# Verificación 1: Archivo de certificado existe y es legible
if [ ! -f "$CERT" ]; then
  echo "❌ Archivo de certificado no encontrado: $CERT"
  exit 1
fi

# Verificación 2: Clave privada existe y es legible
if [ ! -f "$KEY" ]; then
  echo "❌ Clave privada no encontrada: $KEY"
  exit 1
fi

# Verificación 3: Certificado es X.509 válido
if ! openssl x509 -in "$CERT" -noout 2>/dev/null; then
  echo "❌ Certificado X.509 inválido"
  exit 1
fi

# Verificación 4: Certificado no expirado
if ! openssl x509 -in "$CERT" -noout -checkend 0; then
  echo "❌ ¡El certificado está expirado!"
  exit 1
fi

# Verificación 5: Par certificado/clave coinciden
CERT_MOD=$(openssl x509 -noout -modulus -in "$CERT" | openssl md5)
KEY_MOD=$(openssl rsa -noout -modulus -in "$KEY" 2>/dev/null | openssl md5)

if [ "$CERT_MOD" != "$KEY_MOD" ]; then
  echo "❌ ¡Certificado y clave no coinciden!"
  exit 1
fi

# Verificación 6: SANs presentes (requerido para navegadores modernos)
if ! openssl x509 -in "$CERT" -noout -ext subjectAltName 2>/dev/null | grep -q "DNS:"; then
  echo "⚠️ ADVERTENCIA: No se encontraron Subject Alternative Names"
fi

# Verificación 7: Algoritmo de firma fuerte
SIG_ALG=$(openssl x509 -in "$CERT" -noout -text | grep "Signature Algorithm" | head -2)
if echo "$SIG_ALG" | grep -qi "sha1\|md5"; then
  echo "❌ Algoritmo de firma débil: $SIG_ALG"
  exit 1
fi

# Verificación 8: Tamaño de clave adecuado
KEY_SIZE=$(openssl x509 -in "$CERT" -noout -text | grep "Public-Key:" | grep -oP '\d+')
if [ "$KEY_SIZE" -lt 2048 ]; then
  echo "❌ Tamaño de clave muy pequeño: $KEY_SIZE bits (mínimo 2048)"
  exit 1
fi

echo ""
echo "✅ ¡Validación de certificado exitosa!"
echo "   Sujeto: $(openssl x509 -in "$CERT" -noout -subject)"
echo "   Emisor: $(openssl x509 -in "$CERT" -noout -issuer)"
echo "   Expira: $(openssl x509 -in "$CERT" -noout -enddate | cut -d= -f2)"
echo "   Tamaño Clave: $KEY_SIZE bits"

21.7 Coordinación Multi-Servicio

Cuando Múltiples Servicios Comparten Certificados

# Escenario: Balanceador de carga + múltiples servidores web

# Problema: Certificado en LB, servicios detrás necesitan mismo CN/SANs

# Solución 1: Usar mismo certificado en todos (si hostnames coinciden)
# web01, web02, web03 todos usan cert para: web.example.com

# Solución 2: Certificado comodín
# *.example.com funciona para web01.example.com, web02.example.com, etc.

# Solución 3: SANs comprehensivos
# Cert único con SANs: web.example.com, web01.example.com, web02.example.com

Flujo de Trabajo de Despliegue de Certificados

#============================================#
# DESPLIEGUE MULTI-SERVIDOR
#============================================#

# Paso 1: Generar certificado en nodo de gestión
openssl genpkey -algorithm RSA -out web.key -pkeyopt rsa_keygen_bits:2048
openssl req -new -key web.key -out web.csr \
  -subj "/CN=web.example.com" \
  -addext "subjectAltName=DNS:web.example.com,DNS:web01.example.com,DNS:web02.example.com"

# Paso 2: Obtener certificado de CA
# (enviar web.csr a CA, recibir web.crt)

# Paso 3: Validar localmente
./validate-certificate.sh web.crt web.key

# Paso 4: Distribuir de forma segura
for host in web01 web02 web03; do
  scp web.crt root@$host:/etc/pki/tls/certs/
  scp web.key root@$host:/etc/pki/tls/private/
  ssh root@$host "chmod 644 /etc/pki/tls/certs/web01-example-com.crt"
  ssh root@$host "chmod 600 /etc/pki/tls/private/web01-example-com.key"
done

# Paso 5: Recargar servicios
for host in web01 web02 web03; do
  ssh root@$host "systemctl reload httpd"
done

# Paso 6: Probar cada servidor
for host in web01 web02 web03; do
  echo "Probando $host..."
  curl -vk https://$host/ 2>&1 | grep "subject:"
done

21.8 Estándares de Documentación

Plantilla de Documentación de Certificado

## Certificado: web.example.com

### Información Básica
- **Servicio:** Apache (httpd)
- **Servidor:** web01.example.com
- **Ruta de Certificado:** `/etc/pki/tls/certs/web-example-com.crt`
- **Ruta de Clave:** `/etc/pki/tls/private/web-example-com.key`
- **Propietario:** Equipo Web (webadmin@example.com)

### Detalles del Certificado
- **Common Name (CN):** web.example.com
- **SANs:** web.example.com, www.example.com
- **Emisor:** CA Interna (ca.example.com)
- **Fecha de Emisión:** 2024-01-01
- **Fecha de Expiración:** 2025-01-01
- **Tipo de Clave:** RSA 2048

### Proceso de Renovación
- **Método:** certmonger automático
- **Ventana de Renovación:** 65 días antes de expirar
- **Post-Renovación:** `systemctl reload httpd`
- **Contacto:** webadmin@example.com

### Configuración de Servicio
- **Archivo de Config:** `/etc/httpd/conf.d/ssl.conf`
- **Servicio:** `httpd.service`
- **Comando de Reinicio:** `systemctl reload httpd`

### Solución de Problemas
- **Logs:** `/var/log/httpd/ssl_error_log`
- **Comando de Prueba:** `curl -v https://web.example.com/`
- **Problemas Comunes:** Ninguno reportado

### Historial de Cambios
- 2024-01-01: Despliegue inicial
- 2024-06-15: Agregado SAN www.example.com

21.9 Monitoreo y Alertas

Qué Monitorear

✅ Expiración de certificado (60, 30, 7 días antes)
✅ Validez de certificado (no expirado, aún no válido)
✅ Coincidencia de par certificado/clave
✅ Cadena de confianza de certificado
✅ Salud del servicio (¿está usando el cert?)
✅ Estado de rastreo de certmonger
✅ Éxito/fallo de renovación

Script Simple de Monitoreo

#!/bin/bash
# monitor-certificates.sh
# Monitoreo simple de certificados

WARN_DAYS=30
CRIT_DAYS=7
EMAIL="admin@example.com"

check_cert() {
  local cert=$1
  local name=$(basename "$cert")

  # Verificar si expira dentro del período de advertencia
  if ! openssl x509 -in "$cert" -noout -checkend $((86400*WARN_DAYS)); then
    if ! openssl x509 -in "$cert" -noout -checkend $((86400*CRIT_DAYS)); then
      echo "🚨 CRÍTICO: ¡$name expira dentro de $CRIT_DAYS días!"
      return 2
    else
      echo "⚠️ ADVERTENCIA: $name expira dentro de $WARN_DAYS días"
      return 1
    fi
  fi

  return 0
}

# Verificar todos los certificados
WARNINGS=0
CRITICALS=0

for cert in /etc/pki/tls/certs/*.crt; do
  [ -f "$cert" ] || continue
  check_cert "$cert"
  ret=$?
  [ $ret -eq 1 ] && ((WARNINGS++))
  [ $ret -eq 2 ] && ((CRITICALS++))
done

# Alertar si se encuentran problemas
if [ $CRITICALS -gt 0 ] || [ $WARNINGS -gt 0 ]; then
  echo "Problemas de certificados encontrados: $CRITICALS críticos, $WARNINGS advertencias" | \
    mail -s "Alerta de Certificados: $(hostname)" "$EMAIL"
fi

21.10 Procedimientos de Respuesta a Incidentes

Incidente de Expiración de Certificado

#============================================#
# EMERGENCIA DE CERTIFICADO EXPIRADO
#============================================#

# Paso 1: Evaluar impacto
systemctl status httpd
journalctl -xe | grep -i cert

# Paso 2: Solución rápida - Obtener cert temporal
# Opción A: Autofirmado (¡solo para interno!)
openssl req -x509 -nodes -days 30 -newkey rsa:2048 \
  -keyout /etc/pki/tls/private/temp-web01-example-com.key \
  -out /etc/pki/tls/certs/temp-web01-example-com.crt \
  -subj "/CN=$(hostname)"

# Opción B: Restaurar desde respaldo
cp /var/backups/certificates/latest/*.crt /etc/pki/tls/certs/
cp /var/backups/certificates/latest/*.key /etc/pki/tls/private/

# Paso 3: Actualizar configuración del servicio para usar cert temporal
# Editar /etc/httpd/conf.d/ssl.conf
# SSLCertificateFile /etc/pki/tls/certs/temp-web01-example-com.crt
# SSLCertificateKeyFile /etc/pki/tls/private/temp-web01-example-com.key

# Paso 4: Reiniciar servicio
systemctl restart httpd

# Paso 5: Obtener certificado apropiado LO ANTES POSIBLE
# Seguir proceso normal de solicitud de cert

# Paso 6: Documentar incidente
# Qué sucedió, por qué, cómo se arregló, prevención

21.11 Lista de Verificación de Mejores Prácticas

## Lista de Verificación de Gestión de Certificados

### Organización de Archivos
- [ ] Estructura de directorio estándar usada
- [ ] Convención de nomenclatura consistente
- [ ] Permisos de archivo apropiados (600 para claves, 644 para certs)
- [ ] Contextos SELinux correctos

### Gestión del Ciclo de Vida
- [ ] Proceso de renovación definido y documentado
- [ ] Recordatorios de renovación establecidos (60, 30, 7 días)
- [ ] Renovación automatizada si es posible (certmonger)
- [ ] Acciones post-renovación definidas

### Seguridad
- [ ] Claves privadas protegidas (permisos 600)
- [ ] Claves nunca compartidas/enviadas por email
- [ ] Algoritmo de clave fuerte (RSA 2048+ o EC P-256)
- [ ] Firma fuerte (SHA-256+)

### Respaldo
- [ ] Certificados respaldados
- [ ] Claves privadas respaldadas (cifradas)
- [ ] Respaldo probado y validado
- [ ] Procedimiento de restauración documentado

### Documentación
- [ ] Inventario de certificados mantenido
- [ ] Cada certificado documentado
- [ ] Procedimientos escritos
- [ ] Contactos listados

### Monitoreo
- [ ] Monitoreo de expiración habilitado
- [ ] Alertas configuradas
- [ ] Verificaciones de salud en lugar
- [ ] Plan de respuesta a incidentes listo

### Validación
- [ ] Validación pre-despliegue
- [ ] Pruebas post-despliegue
- [ ] Auditorías regulares programadas

21.12 Conclusiones Clave

  1. La organización previene confusión - Estructura y nomenclatura consistentes
  2. Los permisos son críticos - 600 para claves, 644 para certs
  3. Automatizar renovación - Usar certmonger cuando sea posible
  4. Respaldar todo - Pero cifrar claves privadas
  5. Documentar exhaustivamente - Tu yo futuro te lo agradecerá
  6. Monitorear proactivamente - No esperar a la expiración
  7. Validar antes de desplegar - Capturar problemas temprano
  8. Planificar para incidentes - Tener procedimientos de recuperación listos

Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ MEJORES PRÁCTICAS CERTIFICADOS DE SERVICIO                   │
├──────────────────────────────────────────────────────────────┤
│ Archivos:    /etc/pki/tls/certs/*.crt (644)                  │
│              /etc/pki/tls/private/*.key (600)                │
│ Nombres:     [servicio]-[host]-[dominio].[crt|key]           │
│ Renovación:  Automatizar con certmonger                      │
│ Respaldo:    Diario, cifrado, probado                        │
│ Monitoreo:   60, 30, 7 días antes de expirar                 │
│ Validar:     Antes de cada despliegue                        │
│ Documentar:  Todo, siempre                                   │
└──────────────────────────────────────────────────────────────┘

Navegación del Capítulo

Capítulo 22: Dominio de certmonger

Configúralo y Olvídalo: certmonger es la herramienta de automatización de certificados integrada en RHEL. Domínala y nunca renovarás un certificado manualmente otra vez.


22.1 ¿Qué es certmonger?

certmonger es un demonio de rastreo de certificados y renovación automática para RHEL.

Piénsalo como:

  • 📋 Rastreador de certificados - Monitorea fechas de expiración
  • 🔄 Renovador automático - Renueva antes de expirar
  • 🔗 Integrador de CA - Funciona con FreeIPA, CAs locales/internas y helpers de CA externa
  • ⚙️ Integración de servicios - Ejecuta comandos después de renovación

¿Por Qué certmonger?

Sin certmonger:

❌ Rastreo manual de fechas de expiración
❌ Recordatorios de calendario para renovar
❌ Generación manual de CSR
❌ Reinicio manual de servicio después de renovación
❌ Riesgo de perder renovaciones → interrupciones

Con certmonger:

✅ Rastreo automático
✅ Renovación automática
✅ Recarga automática de servicio
✅ Monitoreo centralizado
✅ ¡Sin intervención manual!

22.2 Instalación y Configuración

Todas las Versiones RHEL

#============================================#
# INSTALAR CERTMONGER
#============================================#

# Instalar
sudo dnf install certmonger -y

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

# Verificar
systemctl status certmonger
sudo getcert list  # Debería mostrar lista vacía inicialmente

22.3 Uso Básico

Solicitar un Certificado

#============================================#
# SOLICITUD BÁSICA DE CERTIFICADO
#============================================#

# Autofirmado (para pruebas)
sudo getcert request \
  -f /etc/pki/tls/certs/test.crt \
  -k /etc/pki/tls/private/test.key

# De FreeIPA
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/web.crt \
  -k /etc/pki/tls/private/web.key \
  -K HTTP/$(hostname -f)@REALM \
  -D $(hostname -f)

# Para certificados públicos de Let's Encrypt, usa certbot (Capítulo 24).
# certmonger es la opción nativa para IPA, CA local y flujos basados en helpers.

Verificar Estado

#============================================#
# VERIFICAR ESTADO DE CERTIFICADO
#============================================#

# Listar todos los certificados rastreados
sudo getcert list

# Verificar certificado específico por archivo
sudo getcert list -f /etc/pki/tls/certs/web.crt

# Verificar por ID de solicitud
sudo getcert list -i 20240101000000

# Salida verbosa
sudo getcert list -v

Valores de Estado:

  • MONITORING: ✅ Certificado emitido, rastreando expiración
  • SUBMITTING: 🔄 Enviando solicitud a CA
  • CA_UNREACHABLE: ❌ No se puede alcanzar servidor CA
  • CA_REJECTED: ❌ CA rechazó solicitud
  • NEED_KEY_GEN_PIN: ⏸️ Esperando PIN (HSM/token)
  • PRE_SAVE_COMMAND: 🔄 Ejecutando script pre-guardado
  • POST_SAVE_COMMAND: 🔄 Ejecutando script post-guardado

22.4 Opciones Avanzadas

Solicitud Completa con Todas las Opciones

#============================================#
# SOLICITUD COMPLETA CERTMONGER
#============================================#

sudo ipa-getcert request \
  -f /etc/pki/tls/certs/web.example.com.crt \              # Archivo de certificado
  -k /etc/pki/tls/private/web.example.com.key \            # Archivo de clave privada
  -K HTTP/web.example.com@EXAMPLE.COM \                    # Principal Kerberos
  -D web.example.com \                                     # Nombre DNS (SAN)
  -D www.example.com \                                     # SAN adicional
  -D api.example.com \                                     # Otro SAN
  -U id-kp-serverAuth \                                    # Uso de clave extendido
  -N CN=web.example.com,O=Example,C=US \                   # DN del sujeto
  -g 2048 \                                                # Tamaño de clave
  -G rsa \                                                 # Tipo de clave
  -T caIPAserviceCert \                                    # Perfil IPA
  -C "systemctl reload httpd" \                            # Comando post-guardado
  -B "systemctl stop httpd" \                              # Comando pre-guardado
  -v \                                                     # Verboso
  -w                                                       # Esperar completitud

# Verificar estado
sudo getcert list -f /etc/pki/tls/certs/web.example.com.crt

Opciones Clave Explicadas:

OpciónPropósitoEjemplo
-fRuta de archivo de certificado/etc/pki/tls/certs/web.crt
-kRuta de archivo de clave privada/etc/pki/tls/private/web.key
-KPrincipal KerberosHTTP/web.example.com@REALM
-DSAN DNSweb.example.com
-NDN del sujetoCN=web,O=Example
-CComando post-guardadosystemctl reload httpd
-BComando pre-guardadosystemctl stop httpd
-cNombre CAIPA o external-ca
-TPerfil de certificadocaIPAserviceCert
-gTamaño de clave2048 o 4096
-GTipo de claversa o ec

22.5 Trabajar con Diferentes CAs

FreeIPA (Recomendado para Interno)

#============================================#
# CERTMONGER + FREEIPA
#============================================#

# Prerrequisitos: Sistema inscrito a IPA
ipa-client-install

# Solicitar certificado
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/internal.crt \
  -k /etc/pki/tls/private/internal.key \
  -K HTTP/$(hostname -f)@REALM \
  -D $(hostname -f) \
  -C "systemctl reload httpd"

# certmonger automáticamente:
# ✅ Envía solicitud a CA IPA
# ✅ Obtiene certificado
# ✅ Guarda en archivo
# ✅ Ejecuta comando de recarga
# ✅ Rastrea expiración
# ✅ Renueva ~28 días antes de expirar

ACME público requiere certbot

#============================================#
# ACME PÚBLICO VS FLUJOS NATIVOS DE CERTMONGER
#============================================#

# Certificado público de Let's Encrypt:
# Usa certbot, no un perfil de CA falso en certmonger.
sudo certbot certonly --apache -d public.example.com

# Certificado nativo de FreeIPA / IdM:
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/internal.crt \
  -k /etc/pki/tls/private/internal.key \
  -K HTTP/$(hostname -f)@REALM \
  -D $(hostname -f) \
  -C "systemctl reload httpd"

CA Externa (Envío Manual)

#============================================#
# CERTMONGER CON CA EXTERNA
#============================================#

# Configurar helper de CA externa
sudo getcert add-ca -c external-ca \
  -e '/usr/local/bin/external-ca-submit.sh'

# Solicitar certificado
sudo getcert request \
  -c external-ca \
  -f /etc/pki/tls/certs/external.crt \
  -k /etc/pki/tls/private/external.key

# El script helper debe:
# 1. Leer CSR desde stdin
# 2. Enviar a CA externa
# 3. Retornar certificado en stdout

22.6 Gestionar Certificados Rastreados

Modificar Rastreo

#============================================#
# MODIFICAR RASTREO DE CERTIFICADO EXISTENTE
#============================================#

# Actualizar comando post-guardado sin rekey
sudo getcert stop-tracking -f /etc/pki/tls/certs/web.crt
sudo getcert start-tracking \
  -f /etc/pki/tls/certs/web.crt \
  -k /etc/pki/tls/private/web.key \
  -C "systemctl reload httpd"
# Vuelva a añadir -c, -K, -D, etc. si la entrada original los usaba

# Agregar SAN adicional
sudo getcert resubmit -f /etc/pki/tls/certs/web.crt \
  -D additional.example.com

# Dejar de rastrear (mantener certificado)
sudo getcert stop-tracking -f /etc/pki/tls/certs/web.crt

# Eliminar completamente
sudo getcert stop-tracking -f /etc/pki/tls/certs/web.crt -r

# Comenzar a rastrear certificado existente
sudo getcert start-tracking \
  -f /etc/pki/tls/certs/existing.crt \
  -k /etc/pki/tls/private/existing.key

Forzar Renovación

#============================================#
# FORZAR RENOVACIÓN INMEDIATA
#============================================#

# Por ruta de archivo
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt

# Por ID de solicitud
sudo getcert resubmit -i 20240101000000

# Esperar renovación
sudo getcert list -f /etc/pki/tls/certs/web.crt
# Esperar estado: MONITORING

22.7 Tiempo de Renovación

Entender Ventanas de Renovación

Ciclo de Vida del Certificado (365 días):

Día   0: Certificado emitido
      │
      │ [Operación normal]
      │
Día 243: Comienza ventana de renovación (certmonger intenta renovación)
      │ (2/3 del tiempo de vida del cert: 365 × 2/3 ≈ 243 días)
      │
      │ [Intentos de renovación cada 8 horas si CA disponible]
      │
Día 335: Advertencia si aún no renovado (quedan 30 días)
      │
Día 350: Crítico si aún no renovado (quedan 15 días)
      │
Día 365: El certificado expira → ¡INTERRUPCIÓN DEL SERVICIO si no se renueva!

Comportamiento Predeterminado:

  • La renovación comienza a 2/3 del tiempo de vida del certificado
  • Cert de 365 días → Renueva en día 243 (quedan 122 días)
  • Cert de 90 días → Renueva en día 60 (quedan 30 días)

22.8 Comandos Post-Guardado

Reload vs Restart

#============================================#
# ESTRATEGIAS DE COMANDO POST-GUARDADO
#============================================#

# PREFERIR: reload (sin tiempo de inactividad)
-C "systemctl reload httpd"
-C "systemctl reload nginx"
-C "postfix reload"

# A VECES NECESARIO: restart
-C "systemctl restart slapd"  # OpenLDAP requiere restart
-C "systemctl restart postgresql"  # PostgreSQL requiere restart

# MÚLTIPLES COMANDOS: Usar script
-C "/usr/local/bin/after-cert-renewal.sh"

# Ejemplo de script:
#!/bin/bash
# /usr/local/bin/after-cert-renewal.sh
systemctl reload httpd
systemctl reload nginx
systemctl reload postfix
logger "Certificados renovados vía certmonger"

22.9 Solución de Problemas certmonger

Problemas Comunes

Problema 1: CA_UNREACHABLE

# Síntoma
sudo getcert list
# status: CA_UNREACHABLE

# Diagnóstico
# Para FreeIPA:
ipa ping  # Verificar conectividad IPA
klist  # Verificar ticket Kerberos

# Solución
kinit -k host/$(hostname -f)@REALM  # Renovar ticket de host
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt

# Verificar servidor IPA
ssh ipa-server "sudo ipactl status"

Problema 2: CA_REJECTED

# Síntoma
sudo getcert list
# status: CA_REJECTED
# ca-error: Server at https://ipa.example.com/ipa/xml unwilling to issue certificate

# Causas comunes:
# 1. Principal de servicio no existe
ipa service-show HTTP/$(hostname -f)
# Si no se encuentra:
ipa service-add HTTP/$(hostname -f)

# 2. Host no inscrito
ipa host-show $(hostname -f)

# 3. Problema de permisos
# Verificar permisos IPA

# Reintentar
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt

Problema 3: Renovación No Está Ocurriendo

# Verificar que certmonger está ejecutándose
systemctl status certmonger

# Verificar estado del certificado
sudo getcert list -f /etc/pki/tls/certs/web.crt

# Verificar logs de certmonger
sudo journalctl -u certmonger -f

# Forzar renovación
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt

# Verificar ventana de renovación
# El certificado renueva a 2/3 del tiempo de vida
# Verificar fecha "expires" en salida de getcert list

22.10 IdM ACME vs Let’s Encrypt público

Mantén separados los flujos

#============================================#
# ELIGE LA HERRAMIENTA CORRECTA PARA LA CA CORRECTA
#============================================#

# Certificado público de Let's Encrypt:
# Usa certbot (ver Capítulo 24).
sudo certbot certonly --apache -d public.example.com -d www.public.example.com

# Certificado nativo de FreeIPA / IdM:
# Usa certmonger + ipa-getcert.
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/internal.example.com.crt \
  -k /etc/pki/tls/private/internal.example.com.key \
  -K HTTP/internal.example.com@REALM \
  -D internal.example.com \
  -C "systemctl reload httpd"

# Si IdM ACME está habilitado, su directorio ACME es tu servidor IPA,
# no Let's Encrypt:
sudo certbot certonly \
  --server https://ipa.example.com/acme/directory \
  -d host.example.com

Distinción importante:

  • Let’s Encrypt = CA ACME pública de internet
  • IdM/FreeIPA ACME = tu CA IPA interna exponiendo un endpoint ACME
  • certmonger = rastreador/renovador nativo de RHEL para IPA y flujos basados en helpers

22.11 Monitorear certmonger

Monitoreo de Estado

#============================================#
# MONITOREAR CERTMONGER
#============================================#

# Resumen de todos los certificados
sudo getcert list

# Contar certificados por estado
sudo getcert list | grep "status:" | sort | uniq -c

# Encontrar certificados expirando pronto (30 días)
for cert in $(sudo getcert list | grep "certificate:" | sed -n "s/.*location='\\([^']*\\)'.*/\\1/p"); do
  if ! openssl x509 -in "$cert" -noout -checkend $((86400*30)) 2>/dev/null; then
    echo "⚠️ Expira pronto: $cert"
  fi
done

# Verificar logs de certmonger
sudo journalctl -u certmonger --since today

# Observar actividad de renovación
sudo journalctl -u certmonger -f

# Verificar próximo tiempo de renovación
sudo getcert list | grep -A15 "Request ID" | grep "expires"

Script de Verificación de Salud

#!/bin/bash
# certmonger-health-check.sh

echo "=== Verificación de Salud certmonger ==="

# ¿certmonger ejecutándose?
if systemctl is-active --quiet certmonger; then
  echo "✅ certmonger está ejecutándose"
else
  echo "❌ ¡certmonger NO está ejecutándose!"
  exit 1
fi

# Contar certificados rastreados
TOTAL=$(sudo getcert list | grep -c "Request ID")
echo "📋 Rastreando $TOTAL certificados"

# Verificar desglose de estado
echo ""
echo "Desglose de estado:"
sudo getcert list | grep "status:" | sort | uniq -c

# Verificar problemas
PROBLEMS=$(sudo getcert list | grep "status:" | grep -v "MONITORING" | wc -l)
if [ $PROBLEMS -gt 0 ]; then
  echo ""
  echo "⚠️ $PROBLEMS certificados necesitan atención:"
  sudo getcert list | grep -B5 "status:" | grep -E "(Request ID|status:)" | grep -v "MONITORING"
fi

# Verificar advertencias de expiración
echo ""
echo "Certificados expirando en 30 días:"
sudo getcert list | grep -A10 "Request ID" | grep "expires:" | \
  while read line; do
    # Parsear y verificar expiración
    # (simplificado - script de producción parsearía fechas apropiadamente)
    echo "$line"
  done

22.12 Configuración de certmonger

Archivo de Configuración Principal

#============================================#
# CONFIGURACIÓN CERTMONGER
#============================================#

# Ubicación de configuración
/etc/certmonger/certmonger.conf

# Ubicación de base de datos (certificados rastreados)
/var/lib/certmonger/

# Listar CAs configuradas
sudo getcert list-cas

# Agregar CA personalizada
sudo getcert add-ca -c my-ca \
  -e '/usr/local/bin/my-ca-submit.sh'

# Eliminar CA
sudo getcert remove-ca -c my-ca

22.13 Mejores Prácticas

Mejores Prácticas de certmonger

✅ **Siempre usar comandos post-guardado** (flag -C) para recargar servicios
✅ **Rastrear todos los certificados de producción** con certmonger
✅ **Monitorear estado semanalmente** con `getcert list`
✅ **Probar renovación** antes de expirar con `resubmit`
✅ **Usar modo verboso** (-v) al resolver problemas
✅ **Configurar monitoreo** para estado CA_UNREACHABLE
✅ **Documentar IDs de solicitud** en tu inventario de certificados
✅ **Usar IPA/certmonger para certificados internos** y certbot para Let's Encrypt público
✅ **Mantener logs de certmonger** para pista de auditoría
✅ **Probar comandos post-guardado** independientemente antes de usar

Qué Rastrear con certmonger

# ✅ RASTREAR con certmonger:
- Certificados de servidor web (Apache, NGINX)
- Certificados de servidor de correo (Postfix, Dovecot)
- Certificados de servidor LDAP (OpenLDAP)
- Certificados de aplicación (APIs, microservicios)
- Certificados de servicio (cualquier servicio habilitado para TLS)

# ❌ NO rastrear con certmonger:
- Certificados raíz CA (gestionados separadamente)
- Certificados de cliente para usuarios (ciclo de vida diferente)
- Certificados de prueba/temporales
- Certificados que gestionas con otras herramientas (certbot)

22.14 certmonger vs certbot

¿Cuándo Usar Cuál?

Característicacertmongercertbot
Nativo RHEL✅ Sí (incluido)❌ No (EPEL requerido)
Soporte FreeIPA✅ Nativo❌ No
Let’s Encrypt ACME público❌ Usa certbot en su lugar✅ Sí (todas las versiones)
CA Interna✅ Excelente❌ No
Config Apache/NGINX⏸️ Manual✅ Automática
Integración Servicio✅ Comandos post-guardado⏸️ Limitada
Tiempo Renovación2/3 del tiempo de vida30 días antes
Soporte Red Hat✅ Sí❌ No (EPEL)

Recomendación:

  • Interno/Empresa: Usar certmonger + FreeIPA
  • Público/Simple: Usar certbot (pero saber que requiere EPEL)
  • Certificados públicos en cualquier versión RHEL: usar certbot para Let’s Encrypt

22.15 Escenarios Avanzados

Escenario 1: Renovación de Certificado de Alta Disponibilidad

# Múltiples servidores con mismo servicio

# Servidor 1:
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/shared-service.crt \
  -k /etc/pki/tls/private/shared-service.key \
  -K HTTP/service.example.com@REALM \
  -D service.example.com \
  -C "systemctl reload httpd"

# Servidor 2: Misma configuración
# Resultado: Cada servidor gestiona su propio cert independientemente
# O: Usar cert compartido (copiar archivos, no recomendado)

Escenario 2: Certificado Comodín

# Solicitar comodín de FreeIPA
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/wildcard.crt \
  -k /etc/pki/tls/private/wildcard.key \
  -K HTTP/*.example.com@REALM \
  -D *.example.com \
  -D example.com \
  -C "/usr/local/bin/reload-all-services.sh"

Escenario 3: Claves EC (Curva Elíptica)

# Solicitar con clave EC
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/ec-cert.crt \
  -k /etc/pki/tls/private/ec-cert.key \
  -K HTTP/$(hostname -f)@REALM \
  -G ec \
  -g nistp256  # o nistp384, nistp521

22.16 Conclusiones Clave

  1. certmonger es la automatización de certificados de RHEL
  2. Configúralo y olvídalo - Renovación automática
  3. Funciona mejor con FreeIPA, CAs internas y renovaciones basadas en helpers
  4. Comandos post-guardado recargan servicios automáticamente
  5. Rastrea expiración y renueva a 2/3 del tiempo de vida
  6. Estado MONITORING significa que todo está bien
  7. getcert list es tu herramienta principal de monitoreo

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA DOMINIO DE CERTMONGER                          │
├──────────────────────────────────────────────────────────────────┤
│ Instalar:        dnf install certmonger                          │
│ Iniciar:         systemctl enable --now certmonger               │
│                                                                  │
│ Solicitar:       ipa-getcert request -f cert -k key -K principal │
│ Listar:          getcert list                                    │
│ Estado:          getcert list -f /path/to/cert.crt               │
│ Reenviar:        ipa-getcert resubmit -f /path/to/cert.crt       │
│ Dejar rastrear:  getcert stop-tracking -f /path/to/cert.crt      │
│                                                                  │
│ Estado:          MONITORING = ✅ Bien                            │
│                  CA_UNREACHABLE = ❌ Verificar IPA/CA            │
│                  CA_REJECTED = ❌ Verificar principal/permisos   │
│                                                                  │
│ Logs:            journalctl -u certmonger -f                     │
│ Renovación:      Automática a 2/3 del tiempo de vida del cert    │
│ Post-save:       -C "systemctl reload <servicio>"                │
└──────────────────────────────────────────────────────────────────┘

✅ Herramienta nativa RHEL (soportada por Red Hat)
✅ Perfecta para integración FreeIPA
✅ Mejor encaje para FreeIPA y flujos de renovación con seguimiento

🧪 Laboratorio Práctico

Lab 11: Fundamentos de certmonger

Automatiza la renovación de certificados con certmonger

  • 📁 Ubicación: labs/es_ES/11-certmonger-basics/
  • ⏱️ Tiempo: 30-35 minutos
  • 🎯 Nivel: Intermedio

Navegación del Capítulo

Capítulo 23: Inmersión Profunda en Crypto-Policies

Característica Revolucionaria: Las crypto-policies de RHEL 8+ proporcionan configuración criptográfica en todo el sistema. Domina esto y controlarás la seguridad en todas las aplicaciones con un solo comando.


23.1 El Problema que crypto-policies Resuelve

Antes de Crypto-Policies (RHEL 7)

Configurar seguridad individualmente para CADA aplicación:

Apache:      /etc/httpd/conf.d/ssl.conf
             SSLProtocol, SSLCipherSuite

NGINX:       /etc/nginx/nginx.conf
             ssl_protocols, ssl_ciphers

Postfix:     /etc/postfix/main.cf
             smtpd_tls_protocols, smtpd_tls_mandatory_ciphers

OpenLDAP:    olcTLSProtocolMin, olcTLSCipherSuite

PostgreSQL:  ssl_min_protocol_version

OpenSSH:     /etc/ssh/sshd_config
             Ciphers, MACs, KexAlgorithms

... ¡y más de 20 aplicaciones!

Resultado: Seguridad inconsistente, pesadilla de configuración

Después de Crypto-Policies (RHEL 8/9/10)

✅ Establecer UNA política en todo el sistema
✅ Todas las aplicaciones cumplen automáticamente
✅ Seguridad consistente en todo el sistema
✅ Cambiar política en segundos, no horas

¡Cambio de juego para gestión empresarial!


23.2 Cómo Funcionan las Crypto-Policies

Arquitectura

┌──────────────────────────────────────────────────┐
│       update-crypto-policies --set DEFAULT       │
│            (Comando del administrador)           │
└───────────────────────┬──────────────────────────┘
                        │
                        ▼
┌──────────────────────────────────────────────────┐
│  /etc/crypto-policies/back-ends/                 │
│  (Archivos de configuración generados para cada  │
│  biblioteca)                                     │
│  ├─ opensslcnf.config                            │
│  ├─ gnutls.config                                │
│  ├─ nss.config                                   │
│  ├─ bind.config                                  │
│  └─ ... más ...                                  │
└───────────────────────┬──────────────────────────┘
                        │
            ┌───────────┼───────────┐
            ▼           ▼           ▼
         OpenSSL     GnuTLS        NSS
            ↓           ↓           ↓
         Apache      NGINX       Firefox
         Postfix     vsftpd      Thunderbird
         OpenSSH     wget        Java apps

Concepto Clave: ¡Las aplicaciones leen de archivos back-end, no directamente de la política!


23.3 Las Cuatro Políticas Principales

Comparación de Políticas

PolíticaVersiones TLSRSA MínSHA-13DESDH MínCaso de Uso
DEFAULT1.2, 1.320482048✅ Recomendado
LEGACY1.0+1024⚠️⚠️1024Solo compatibilidad
FUTURE1.2, 1.330723072Alta seguridad
FIPS1.2, 1.320482048Cumplimiento federal

Detalles de Política DEFAULT

# Seguridad y compatibilidad equilibradas
Protocolos:
  - TLS 1.2
  - TLS 1.3

Tamaños Mínimos de Clave:
  - RSA: 2048 bits
  - DH: 2048 bits
  - ECC: secp256r1 (P-256)

Cifrados Permitidos:
  - AES-128-GCM
  - AES-256-GCM
  - ChaCha20-Poly1305
  - AES-128-CBC
  - AES-256-CBC

Algoritmos de Firma:
  - SHA-256
  - SHA-384
  - SHA-512

Bloqueados:
  - TLS 1.0, 1.1
  - MD5
  - Firmas SHA-1
  - 3DES, RC4, DES
  - RSA < 2048 bits
  - Cifrados de exportación

23.4 Ver y Cambiar Políticas

Comandos Básicos

#============================================#
# OPERACIONES BÁSICAS CRYPTO-POLICY
#============================================#

# Ver política actual
update-crypto-policies --show
# Salida: DEFAULT

# Listar políticas disponibles
ls /usr/share/crypto-policies/policies/
# DEFAULT.pol  FUTURE.pol  LEGACY.pol  FIPS.pol

# Establecer política
sudo update-crypto-policies --set FUTURE

# ¡DEBES reiniciar servicios para que los cambios tengan efecto!
sudo systemctl restart httpd nginx postfix slapd

# O reiniciar (asegura que todo recoja los cambios)
sudo reboot

Qué Sucede Cuando Cambias la Política

#============================================#
# DETRÁS DE ESCENA
#============================================#

# Antes
update-crypto-policies --show
# DEFAULT

# Cambiar
sudo update-crypto-policies --set FUTURE

# Actualizaciones generadas:
ls -l /etc/crypto-policies/back-ends/
# -rw-r--r--. opensslcnf.config    ← ¡Actualizado!
# -rw-r--r--. gnutls.config        ← ¡Actualizado!
# -rw-r--r--. nss.config           ← ¡Actualizado!
# -rw-r--r--. bind.config          ← ¡Actualizado!
# ... todos los back-ends actualizados ...

# Ver configuración de OpenSSL
cat /etc/crypto-policies/back-ends/opensslcnf.config
# Muestra configuración real de OpenSSL aplicada

23.5 Subpolíticas (RHEL 9+)

Modificadores de Política

RHEL 9 introdujo subpolíticas - ¡afinar políticas existentes!

#============================================#
# SUBPOLÍTICAS CRYPTO-POLICY (RHEL 9+)
#============================================#

# Política base con modificador
sudo update-crypto-policies --set DEFAULT:NO-SHA1

# Múltiples modificadores
sudo update-crypto-policies --set DEFAULT:NO-SHA1:GOST

# Módulos de subpolítica disponibles
ls /usr/share/crypto-policies/policies/modules/
# AD-SUPPORT.pmod
# GOST.pmod
# NO-CAMELLIA.pmod
# NO-SHA1.pmod
# NO-ENFORCE-EMS.pmod
# ...y más

# Ver detalles del módulo
cat /usr/share/crypto-policies/policies/modules/NO-SHA1.pmod

Subpolíticas Comunes:

SubpolíticaEfectoCaso de Uso
NO-SHA1Deshabilitar completamente SHA-1Seguridad extra
AD-SUPPORTHabilitar compatibilidad ADMixto Windows/Linux
GOSTHabilitar algoritmos GOSTRequisitos rusos
NO-CAMELLIADeshabilitar cifrado CamelliaCumplimiento específico
NO-ENFORCE-EMSDeshabilitar Extended Master SecretCompatibilidad

23.6 Crear Módulos de Política Personalizados

Ejemplo de Módulo Personalizado

#============================================#
# CREAR MÓDULO DE POLÍTICA PERSONALIZADO
#============================================#

# Crear módulo personalizado
sudo vi /etc/crypto-policies/policies/modules/CUSTOM-SECURITY.pmod

# Contenido de ejemplo:
min_rsa_size = 4096
min_dh_size = 3072
min_dsa_size = 3072
sha1_in_certs = 0
arbitrary_dh_groups = 0
ssh_certs = 0

# Aplicar
sudo update-crypto-policies --set DEFAULT:CUSTOM-SECURITY

# Reiniciar servicios
sudo systemctl restart httpd nginx postfix

# Verificar
openssl ciphers -v | grep -E "RSA|DH"

23.7 Sobrescrituras por Aplicación

Cuándo Sobrescribir

A veces UNA aplicación necesita ajustes diferentes de la política del sistema:

Ejemplo: La aplicación legacy necesita TLS 1.1, pero el sistema usa DEFAULT

Sobrescritura de Apache

#============================================#
# SOBRESCRITURA CRYPTO-POLICY DE APACHE
#============================================#

# /etc/httpd/conf.d/ssl.conf

# Opción 1: Incluir crypto-policy, luego sobrescribir
Include /etc/crypto-policies/back-ends/httpd.config

# Luego agregar sobrescrituras:
SSLProtocol all -SSLv3  # Re-habilitar TLS 1.0/1.1

# Opción 2: Optar completamente por no usar
# No incluir archivo crypto-policy
# Configurar manualmente todo:
SSLProtocol TLSv1.1 TLSv1.2 TLSv1.3
SSLCipherSuite HIGH:!aNULL:!MD5

# ⚠️ Advertencia: Ahora gestionas TLS de Apache manualmente
# Los cambios de crypto-policy del sistema no afectarán Apache

Mejor Enfoque: ¡Crear módulo de política personalizado en lugar de sobrescrituras por app!


23.8 Probar Impacto de Política

Antes de Cambiar Política

#============================================#
# PROBAR IMPACTO DE CAMBIO DE POLÍTICA
#============================================#

# 1. Documentar estado actual
update-crypto-policies --show > /tmp/current-policy.txt
systemctl list-units --type=service --state=running > /tmp/running-services.txt

# 2. Probar aplicaciones
curl https://localhost/
psql -h localhost  # etc.

# 3. Cambiar política en sistema de prueba primero
sudo update-crypto-policies --set FUTURE

# 4. Reiniciar servicios
sudo systemctl restart httpd nginx postfix

# 5. Probar exhaustivamente
./test-all-services.sh

# 6. Si hay problemas: Revertir
sudo update-crypto-policies --set DEFAULT

# 7. Si exitoso: Documentar y desplegar a producción

23.9 Impacto de Política en Certificados

Qué Controlan las Políticas

Crypto-policies afectan:

  • ✅ Versiones de protocolo TLS permitidas
  • ✅ Suites de cifrado disponibles
  • ✅ Tamaños mínimos de clave aceptados
  • ✅ Algoritmos de firma permitidos
  • ✅ Parámetros Diffie-Hellman
  • ✅ Rigurosidad de validación de certificado

Crypto-policies NO afectan:

  • ❌ Qué certificados usar (aún configurado por servicio)
  • ❌ Ubicaciones de archivos de certificado
  • ❌ Almacén de confianza CA (eso es update-ca-trust)
  • ❌ Emisión de certificados

Matriz de Compatibilidad de Certificados

Tipo de CertificadoDEFAULTLEGACYFUTUREFIPS
RSA 1024 bit⚠️
RSA 2048 bit
RSA 3072 bit
RSA 4096 bit
EC P-256
EC P-384
Firma SHA-1⚠️
Firma SHA-256

23.10 Solución de Problemas Crypto-Policies

Problemas Comunes

Problema 1: La Aplicación Falla Después de Cambio de Política

# Síntoma
sudo update-crypto-policies --set FUTURE
sudo systemctl restart httpd
# httpd falla al iniciar

# Diagnóstico
sudo journalctl -xe -u httpd | grep -i cipher

# Causa común: La aplicación tiene cifrados débiles codificados

# Solución 1: Revertir política
sudo update-crypto-policies --set DEFAULT

# Solución 2: Actualizar configuración de aplicación
# Eliminar especificaciones de cifrado codificadas

# Solución 3: Crear módulo de política personalizado

Problema 2: “No Shared Cipher”

# Síntoma: Los clientes no pueden conectar

# Probar
openssl s_client -connect server:443

# Si muestra "no shared cipher":

# Verificar política
update-crypto-policies --show

# Probar capacidades del cliente
openssl s_client -connect server:443 -cipher 'ALL' -tls1_2

# Solución temporal (no recomendada a largo plazo):
sudo update-crypto-policies --set LEGACY

# Solución apropiada: Actualizar cliente para soportar TLS 1.2+ y cifrados modernos

Problema 3: La Política No Parece Aplicarse

# Verificar si la aplicación está sobrescribiendo la política

# Apache
grep -r "SSLProtocol\|SSLCipherSuite" /etc/httpd/
# Si se encuentra: La app está sobrescribiendo la política

# NGINX
grep -r "ssl_protocols\|ssl_ciphers" /etc/nginx/
# Si se encuentra: La app está sobrescribiendo la política

# Solución: Eliminar sobrescrituras, dejar que crypto-policy lo maneje
# O: Documentar por qué la sobrescritura es necesaria

23.11 Mejores Prácticas

Recomendaciones

✅ **Usar política DEFAULT** para la mayoría de entornos
✅ **Probar antes de desplegar** nuevas políticas
✅ **Documentar elecciones de política** y razones
✅ **Reiniciar servicios** después de cambios de política
✅ **Evitar sobrescrituras por app** cuando sea posible
✅ **Usar subpolíticas** (RHEL 9+) para ajuste fino
✅ **Monitorear problemas** de compatibilidad
✅ **Mantener LEGACY temporal** si se usa
✅ **Planificar migraciones** al cambiar políticas
✅ **Actualizar clientes** en lugar de debilitar política

Cuándo Usar Cada Política

DEFAULT:

  • ✅ La mayoría de entornos de producción
  • ✅ Seguridad/compatibilidad equilibrada
  • ✅ Punto de partida recomendado
  • ✅ Probada y mantenida por Red Hat

LEGACY:

  • ⚠️ ¡Solo temporal durante migraciones!
  • ⚠️ Soportar clientes muy antiguos
  • ⚠️ Probar problemas de compatibilidad
  • ❌ ¡Nunca a largo plazo!

FUTURE:

  • ✅ Entornos de alta seguridad
  • ✅ Todos los clientes son modernos
  • ✅ Quieres los ajustes más fuertes
  • ✅ Planificación para estándares futuros

FIPS:

  • ✅ Cumplimiento federal requerido
  • ✅ Contratos gubernamentales
  • ✅ Industrias reguladas
  • ✅ Requisitos de certificación

23.12 Inmersión Profunda en Política FIPS

Habilitar Modo FIPS

#============================================#
# HABILITAR MODO FIPS
#============================================#

# Verificar estado actual
fips-mode-setup --check
# FIPS mode is disabled.

# Habilitar modo FIPS
sudo fips-mode-setup --enable

# SE DEBE reiniciar
sudo reboot

# Verificar después de reiniciar
fips-mode-setup --check
# FIPS mode is enabled.

# Crypto-policy automáticamente establecida a FIPS
update-crypto-policies --show
# FIPS

Requisitos del Modo FIPS:

  • Debe habilitarse en instalación O con fips-mode-setup
  • Requiere reinicio
  • Afecta todo el sistema
  • Solo algoritmos aprobados por FIPS disponibles
  • Impacto en rendimiento (~10-20% más lento)

Especificaciones de Política FIPS

# Qué permite la política FIPS:
✅ TLS 1.2, 1.3
✅ RSA 2048+ bits
✅ AES-128, AES-256 (modo GCM)
✅ SHA-256, SHA-384, SHA-512
✅ Intercambio de clave ECDHE

# Qué bloquea FIPS:
❌ TLS 1.0, 1.1
❌ RSA < 2048 bits
❌ 3DES, RC4, DES
❌ MD5, SHA-1
❌ Algoritmos no aprobados
❌ Cifrados modo CBC (en algunos casos)

23.13 Monitoreo y Auditoría

Verificar Cumplimiento de Política

#============================================#
# VERIFICAR CUMPLIMIENTO CRYPTO-POLICY
#============================================#

# Política actual
update-crypto-policies --show

# ¿Qué aplicaciones usan crypto-policies?
ls -l /etc/crypto-policies/back-ends/

# Verificar que OpenSSL sigue la política
openssl ciphers -v | head -20

# Verificar configuración específica de aplicación
# Apache
cat /etc/crypto-policies/back-ends/httpd.config

# Probar conexión real
openssl s_client -connect localhost:443 -tls1_3

# Verificar que no haya sobrescrituras
grep -r "SSLProtocol\|SSLCipherSuite" /etc/httpd/ | grep -v crypto-policies
# Debería estar vacío o comentado

23.14 Flujo de Trabajo de Solución de Problemas

Enfoque Sistemático

¿La aplicación falla después de cambio de política?
    │
    ├─ Paso 1: Identificar error
    │   └─ Verificar logs: journalctl -xe
    │
    ├─ Paso 2: Verificar política activa
    │   └─ update-crypto-policies --show
    │
    ├─ Paso 3: Probar con LEGACY
    │   └─ sudo update-crypto-policies --set LEGACY
    │   └─ Si funciona → problema de cifrado/protocolo
    │
    ├─ Paso 4: Identificar incompatibilidad
    │   └─ openssl s_client -cipher 'ALL' -tls1
    │   └─ Encontrar qué necesita cliente/servidor
    │
    ├─ Paso 5: Elegir solución
    │   ├─ A) Actualizar cliente (mejor)
    │   ├─ B) Crear módulo personalizado (bueno)
    │   └─ C) Sobrescritura por app (último recurso)
    │
    └─ Paso 6: Documentar y desplegar
        └─ Por qué se necesita sobrescritura, plan para eliminar

23.15 Conclusiones Clave

  1. Crypto-policies son solo RHEL 8+ (no en RHEL 7)
  2. Política DEFAULT es recomendada para la mayoría de casos
  3. Los cambios requieren reinicios de servicio para tener efecto
  4. Afecta TODAS las aplicaciones crypto en todo el sistema
  5. Las subpolíticas proporcionan ajuste fino (RHEL 9+)
  6. Evitar sobrescrituras por app cuando sea posible
  7. Probar antes de desplegar nuevas políticas
  8. ¡LEGACY es solo temporal!

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA CRYPTO-POLICIES                            │
├──────────────────────────────────────────────────────────────┤
│ Disponible:     Solo RHEL 8, 9, 10 (no RHEL 7)               │
│                                                              │
│ Ver:            update-crypto-policies --show                │
│ Establecer:     sudo update-crypto-policies --set <POLICY>   │
│ Políticas:      DEFAULT, LEGACY, FUTURE, FIPS                │
│                                                              │
│ Subpolítica:    update-crypto-policies --set DEFAULT:NO-SHA1 │
│                 (solo RHEL 9+)                               │
│                                                              │
│ Back-ends:      /etc/crypto-policies/back-ends/              │
│ Módulos:        /usr/share/crypto-policies/policies/modules/ │
│                                                              │
│ Después cambio: systemctl restart <servicios>                │
│                 O reboot                                     │
│                                                              │
│ DEFAULT:        TLS 1.2+, RSA 2048+, Sin SHA-1               │
│ LEGACY:         TLS 1.0+, permite débiles (¡solo temporal!)  │
│ FUTURE:         TLS 1.2+, RSA 3072+, más estricto            │
│ FIPS:           Cumplimiento federal (requiere modo FIPS)    │
└──────────────────────────────────────────────────────────────┘

⚠️ RHEL 7 no tiene crypto-policies (solo config manual)
✅ DEFAULT funciona para 95% de entornos

🧪 Laboratorio Práctico

Lab 12: Crypto-Policies

Comprende y configura crypto-policies a nivel de sistema

  • 📁 Ubicación: labs/es_ES/12-crypto-policies/
  • ⏱️ Tiempo: 25-30 minutos
  • 🎯 Nivel: Intermedio

Navegación del Capítulo

Capítulo 24: Let’s Encrypt y certbot

Certificados Públicos Gratuitos: Let’s Encrypt proporciona certificados gratuitos y automatizados para sitios web públicos. Aprende cómo usarlo en RHEL con certbot.


24.1 ¿Qué es Let’s Encrypt?

Let’s Encrypt es una Autoridad Certificadora gratuita, automatizada y abierta.

Características Clave:

  • Certificados gratuitos (sin costo)
  • Emisión automatizada (vía protocolo ACME)
  • Renovación automática (cada 60-90 días)
  • Ampliamente confiable (en todos los navegadores principales)
  • Validación de dominio (certificados DV)

Limitaciones:

  • Solo dominios públicos (debe ser accesible por internet para validación)
  • Validez de 90 días (corta duración, requiere automatización)
  • Solo Validación de Dominio (no Organization o Extended Validation)
  • Sin comodín con HTTP-01 (requiere desafío DNS-01)

24.2 Let’s Encrypt en RHEL: ACME público y alternativas nativas

Método 1: certbot (Tradicional)

⚠️ CRÍTICO: EPEL Requerido

certbot NO está disponible en repositorios oficiales de RHEL.

Requiere EPEL (Extra Packages for Enterprise Linux), un repositorio mantenido por la comunidad que NO está oficialmente soportado por Red Hat.

Para Entornos de Producción Empresarial:

  • Considera FreeIPA con certmonger (Capítulo 19)
  • O CA comercial con certmonger (Capítulo 22)
  • O gestión manual de certificados

EPEL es adecuado para:

  • Entornos de desarrollo/prueba
  • Despliegues pequeños donde el riesgo de EPEL es aceptable
  • Situaciones donde certificados gratuitos superan preocupaciones de soporte

Herramienta certbot:

  • Automatización completa
  • Plugins Apache/NGINX
  • Configuración automática
  • Temporizadores de renovación
  • ⚠️ Requiere EPEL

Método 2: certmonger para CAs internas/privadas

Solución Nativa RHEL:

  • ✅ No se necesita EPEL
  • ✅ Soportado por Red Hat
  • ✅ Mejor encaje para flujos de FreeIPA / IdM y CA local
  • ⏸️ Config manual de servidor web (sin plugins Apache/NGINX)
  • ❌ No es un reemplazo directo de certbot para Let’s Encrypt público

Usaremos certbot para Let’s Encrypt público y certmonger para flujos internos nativos.


24.3 Instalación de certbot

RHEL 7

#============================================#
# INSTALAR CERTBOT EN RHEL 7 (¡REQUIERE EPEL!)
#============================================#

# ⚠️ ADVERTENCIA: Habilitando repositorio de terceros

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

# Verificar EPEL habilitado
yum repolist | grep epel

# Paso 2: Instalar certbot
sudo yum install certbot python2-certbot-apache python2-certbot-nginx -y

# Verificar
certbot --version

RHEL 8

#============================================#
# INSTALAR CERTBOT EN RHEL 8 (¡REQUIERE EPEL!)
#============================================#

# ⚠️ ADVERTENCIA: Habilitando repositorio de terceros

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

# O si tienes suscripción:
sudo dnf install epel-release -y

# Paso 2: Instalar certbot
sudo dnf install certbot python3-certbot-apache python3-certbot-nginx -y

# Verificar
certbot --version

RHEL 9/10

#============================================#
# INSTALAR CERTBOT EN RHEL 9/10 (¡REQUIERE EPEL!)
#============================================#

# ⚠️ ADVERTENCIA: Habilitando repositorio de terceros

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

# Paso 2: Instalar certbot
sudo dnf install certbot python3-certbot-apache python3-certbot-nginx -y

# Verificar
certbot --version

Recuerda: EPEL tiene soporte comunitario. Para producción empresarial, considera FreeIPA + certmonger (solución nativa RHEL).


24.4 Uso de certbot - Apache

Configuración Automática de Apache

#============================================#
# CERTBOT CON APACHE (¡AUTOMATIZADO!)
#============================================#

# Prerrequisitos:
# - Apache instalado y ejecutándose
# - Puerto 80 accesible desde internet
# - Dominio resuelve a este servidor
# - Repositorio EPEL habilitado

# Obtener certificado y auto-configurar Apache
sudo certbot --apache -d www.example.com -d example.com

# certbot hará:
# 1. Generar certificado de Let's Encrypt
# 2. Configurar automáticamente Apache SSL
# 3. Configurar redirección HTTP→HTTPS
# 4. Configurar renovación automática

# Prompts interactivos:
# - Dirección de email (para avisos de renovación)
# - Aceptar ToS
# - ¿Redirigir HTTP a HTTPS? (elegir sí)

# No interactivo (automatización):
sudo certbot --apache \
  -d www.example.com \
  -d example.com \
  --non-interactive \
  --agree-tos \
  --email admin@example.com \
  --redirect

# Ubicación del certificado:
# /etc/letsencrypt/live/www.example.com/fullchain.pem
# /etc/letsencrypt/live/www.example.com/privkey.pem

24.5 Uso de certbot - NGINX

Configuración Automática de NGINX

#============================================#
# CERTBOT CON NGINX (¡AUTOMATIZADO!)
#============================================#

# Prerrequisitos:
# - NGINX instalado y ejecutándose
# - Puerto 80 accesible
# - Dominio resuelve al servidor

# Obtener y configurar
sudo certbot --nginx -d api.example.com

# No interactivo
sudo certbot --nginx \
  -d api.example.com \
  --non-interactive \
  --agree-tos \
  --email admin@example.com \
  --redirect

# ¡certbot actualiza configuración de NGINX automáticamente!
# No se necesita configuración SSL manual

24.6 Modo Manual certbot (Standalone)

Sin Plugin de Servidor Web

#============================================#
# CERTBOT STANDALONE (SIN PLUGIN)
#============================================#

# Usar cuando:
# - El servidor web no es Apache/NGINX
# - Quieres control manual sobre configuración
# - Usas servidor web personalizado

# Obtener solo certificado (no configura servidor)
sudo certbot certonly --standalone \
  -d app.example.com \
  --non-interactive \
  --agree-tos \
  --email admin@example.com

# Certificado guardado en:
# /etc/letsencrypt/live/app.example.com/fullchain.pem
# /etc/letsencrypt/live/app.example.com/privkey.pem

# Configurar manualmente tu servicio para usarlo
# Ejemplo Apache:
# SSLCertificateFile /etc/letsencrypt/live/app.example.com/fullchain.pem
# SSLCertificateKeyFile /etc/letsencrypt/live/app.example.com/privkey.pem

24.7 Renovación

Renovación Automática

#============================================#
# RENOVACIÓN AUTOMÁTICA CERTBOT
#============================================#

# certbot configura automáticamente temporizador de renovación
systemctl list-timers | grep certbot
# Debería mostrar: certbot-renew.timer

# Ver detalles del temporizador
systemctl status certbot-renew.timer

# Probar renovación (simulación - no renueva realmente)
sudo certbot renew --dry-run

# Forzar renovación real (si es necesario)
sudo certbot renew --force-renewal

# Verificar expiración de certificado
sudo certbot certificates

# La renovación se ejecuta dos veces al día
# Renueva certificados expirando dentro de 30 días

Hooks de Renovación

#============================================#
# HOOKS DE RENOVACIÓN (COMANDOS DE DESPLIEGUE)
#============================================#

# Agregar hook para recargar servicio después de renovación
sudo certbot renew --deploy-hook "systemctl reload nginx"

# O crear script de hook
sudo vi /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh

#!/bin/bash
systemctl reload httpd
systemctl reload nginx
systemctl reload postfix

sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh

# Hooks en /etc/letsencrypt/renewal-hooks/:
# - pre/: Ejecutar antes de renovación
# - post/: Ejecutar después de renovación (incluso si falló)
# - deploy/: Ejecutar después solo de renovación exitosa

24.8 Certificados Comodín

Desafío DNS-01 Requerido

#============================================#
# CERTIFICADO COMODÍN (DESAFÍO DNS)
#============================================#

# Comodín requiere desafío DNS-01
# (no puede usar HTTP-01 para *.example.com)

# Desafío DNS manual
sudo certbot certonly --manual \
  --preferred-challenges dns \
  -d "*.example.com" \
  -d "example.com"

# certbot te pedirá que:
# 1. Crees registro TXT en DNS
# 2. Esperes a propagación
# 3. Presiones Enter para continuar

# Automatización DNS con plugins (si está disponible)
# sudo certbot certonly --dns-route53 -d "*.example.com"
# (requiere plugin de proveedor DNS)

24.9 Dónde encaja certmonger

Usa certmonger para flujos de CA interna o privada

#============================================#
# CERTMONGER PARA FLUJOS IPA / CA INTERNA
#============================================#

# Instalar certmonger (incluido en RHEL)
sudo dnf install certmonger -y
sudo systemctl enable --now certmonger

# Solicitar un certificado interno de FreeIPA / IdM
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/internal.example.com.crt \
  -k /etc/pki/tls/private/internal.example.com.key \
  -K HTTP/internal.example.com@REALM \
  -D internal.example.com \
  -C "systemctl reload httpd"

# Verificar estado
sudo getcert list

# Certmonger hace el seguimiento y la renovación del certificado interno

Mantén separados estos flujos:

Caso de usoHerramienta recomendada
Certificado público de internet de Let’s Encryptcertbot
Certificado interno de FreeIPA / IdMcertmonger con ipa-getcert
ACME contra tu propio endpoint IdM ACMEcertbot u otro cliente ACME

Importante: IdM ACME, cuando está habilitado, es tu propia CA FreeIPA / IdM exponiendo un endpoint ACME. No es Let’s Encrypt.


24.10 Solución de Problemas certbot

Problemas Comunes

Problema 1: Falló Validación de Desafío

# Síntoma
sudo certbot --apache -d example.com
# Error: Challenge validation failed

# Causas comunes:
# 1. Puerto 80 no accesible
curl http://example.com/.well-known/acme-challenge/test
# Debería ser accesible desde internet

# 2. Firewall bloqueando
sudo firewall-cmd --list-services | grep http

# 3. DNS no resolviendo
nslookup example.com

# 4. Otro servicio en puerto 80
ss -tlnp | grep :80

Problema 2: Falló Renovación

# Verificar logs de renovación
sudo cat /var/log/letsencrypt/letsencrypt.log

# Causas comunes:
# - Puerto 80 bloqueado
# - DNS cambió
# - Límite de tasa alcanzado

# Probar renovación manualmente
sudo certbot renew --dry-run

Problema 3: Errores de Permisos

# Corregir permisos de certbot
sudo chmod 0755 /etc/letsencrypt/{live,archive}
sudo chmod 0644 /etc/letsencrypt/live/*/fullchain.pem
sudo chmod 0600 /etc/letsencrypt/live/*/privkey.pem

24.11 Mejores Prácticas

Mejores Prácticas de certbot

✅ **Usar certbot solo para sitios públicos**
✅ **Asegurar puerto 80 accesible** (desafío HTTP-01)
✅ **Probar renovación regularmente** (certbot renew --dry-run)
✅ **Monitorear temporizador de renovación** (systemctl status certbot-renew.timer)
✅ **Configurar notificaciones por email** para fallos
✅ **Usar hooks de renovación** para recargar servicios
✅ **Respaldar /etc/letsencrypt/** directorio
✅ **Documentar dependencia de EPEL** en runbooks
✅ **Tener plan de respaldo** si EPEL no disponible
✅ **Para servicios internos, usar certmonger + FreeIPA/CA local**

Cuándo Usar certbot

✅ Buenos Casos de Uso:

  • Sitios web públicos
  • Entornos de desarrollo/staging
  • Despliegues pequeños
  • Proyectos sensibles al costo
  • Configuración HTTPS rápida

❌ Considerar Alternativas:

  • Producción empresarial (usar FreeIPA)
  • Servicios solo internos (usar FreeIPA)
  • Soporte de vendor estricto requerido (sin EPEL)
  • Entornos air-gapped (sin internet)
  • Cumplimiento requiriendo CA comercial

24.12 Alternativa: FreeIPA para Interno

Comparación

Para servicios INTERNOS:

# En lugar de Let's Encrypt (CA pública)
# Usar FreeIPA (CA interna)

# Ventajas de FreeIPA para interno:
✅ Sin dependencia de internet
✅ Soportado por Red Hat
✅ Funciona offline
✅ No se necesita EPEL
✅ Integrado con RHEL
✅ Perfiles de certificados
✅ Gestión centralizada

# Configuración:
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/internal.crt \
  -k /etc/pki/tls/private/internal.key \
  -K HTTP/$(hostname -f)@REALM \
  -C "systemctl reload httpd"

# Ver Capítulo 19 para detalles de FreeIPA

24.13 Migración de certbot a certmonger

Al mover servicios internos a FreeIPA / IdM

Si vas a reemplazar certificados públicos de Let’s Encrypt por PKI interna para servicios no públicos, mueve el servicio a FreeIPA / IdM en lugar de intentar hacer que certmonger hable directamente con Let’s Encrypt.

#============================================#
# MIGRAR CERTBOT → CERTMONGER PARA PKI INTERNA
#============================================#

# Paso 1: Inventariar los certificados gestionados por certbot
sudo certbot certificates

# Paso 2: Solicitar el certificado interno de reemplazo desde IPA
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/internal.example.com.crt \
  -k /etc/pki/tls/private/internal.example.com.key \
  -K HTTP/internal.example.com@REALM \
  -D internal.example.com \
  -C "systemctl reload httpd"

# Paso 3: Actualizar la configuración de Apache/NGINX
# Cambiar de /etc/letsencrypt/live/... a /etc/pki/tls/...

# Paso 4: Recargar y verificar
sudo systemctl reload httpd
sudo getcert list

# Paso 5: Deshabilitar renovaciones de certbot solo después de quitar todos los certificados públicos
sudo systemctl disable --now certbot-renew.timer

24.14 Límites de Tasa

Límites de Let’s Encrypt

Ten en cuenta los límites de tasa:

Tipo de LímiteValorPeríodo
Certificados por dominio50por semana
Certificados duplicados5por semana
Validaciones fallidas5por hora
Nuevas cuentas10por IP por 3 horas

Evitar alcanzar límites:

  • ✅ Usar –dry-run para pruebas
  • ✅ Usar entorno de staging primero
  • ✅ No solicitar mismo cert repetidamente
  • ✅ Planificar despliegues cuidadosamente

Entorno de Staging:

# Probar contra staging (no cuenta contra límites)
sudo certbot --apache \
  -d test.example.com \
  --test-cert  # Usa entorno de staging

# Cuando esté listo, obtener cert de producción:
sudo certbot --apache -d test.example.com

24.15 Ejemplos Completos

Ejemplo 1: Apache con certbot

#!/bin/bash
# setup-apache-letsencrypt.sh

DOMAIN="www.example.com"
EMAIL="admin@example.com"

echo "=== Configuración Apache + Let's Encrypt ==="
echo "⚠️ Requiere repositorio EPEL"

# 1. Instalar Apache
sudo dnf install -y httpd

# 2. Habilitar EPEL
sudo dnf install -y epel-release

# 3. Instalar certbot
sudo dnf install -y certbot python3-certbot-apache

# 4. Asegurar puerto 80 abierto
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload

# 5. Iniciar Apache
sudo systemctl enable --now httpd

# 6. Obtener certificado
sudo certbot --apache \
  -d "$DOMAIN" \
  --non-interactive \
  --agree-tos \
  --email "$EMAIL" \
  --redirect

# 7. Verificar
sudo certbot certificates

# 8. Probar
curl -I https://$DOMAIN/

echo "✅ ¡Apache + Let's Encrypt configurado!"
echo "⚠️ Recuerda: certbot requiere EPEL (soporte comunitario)"

Ejemplo 2: NGINX con certbot

#!/bin/bash
# setup-nginx-letsencrypt.sh

DOMAIN="api.example.com"
EMAIL="admin@example.com"

echo "=== Configuración NGINX + Let's Encrypt ==="

# 1. Instalar NGINX
sudo dnf install -y nginx

# 2. Instalar certbot
sudo dnf install -y epel-release
sudo dnf install -y certbot python3-certbot-nginx

# 3. Crear configuración básica de NGINX
sudo tee /etc/nginx/conf.d/$DOMAIN.conf << EOF
server {
    listen 80;
    server_name $DOMAIN;
    root /usr/share/nginx/html;
}
EOF

# 4. Iniciar NGINX
sudo systemctl enable --now nginx

# 5. Obtener certificado
sudo certbot --nginx \
  -d "$DOMAIN" \
  --non-interactive \
  --agree-tos \
  --email "$EMAIL"

# 6. ¡certbot actualiza configuración de NGINX automáticamente!

# 7. Verificar
curl -I https://$DOMAIN/

echo "✅ ¡NGINX + Let's Encrypt configurado!"

24.16 Respaldo y Restauración

Respaldar Certificados de Let’s Encrypt

#============================================#
# RESPALDAR CERTBOT/LETSENCRYPT
#============================================#

# Respaldar directorio completo de letsencrypt
sudo tar czf letsencrypt-backup-$(date +%Y%m%d).tar.gz \
  /etc/letsencrypt/

# Almacenar respaldo de forma segura (¡contiene claves privadas!)

# Restaurar
sudo tar xzf letsencrypt-backup-YYYYMMDD.tar.gz -C /

# Verificar
sudo certbot certificates

24.17 Conclusiones Clave

  1. Let’s Encrypt proporciona certificados gratuitos para dominios públicos
  2. certbot requiere EPEL en TODAS las versiones RHEL (no soportado oficialmente)
  3. certbot automatiza configuración de Apache/NGINX
  4. Validez de 90 días requiere renovación automática
  5. certmonger sigue siendo la opción nativa para flujos de FreeIPA y CA interna
  6. Para servicios internos: Usar FreeIPA en su lugar
  7. Probar con –dry-run para evitar límites de tasa
  8. Monitorear temporizador de renovación - verificar que esté ejecutándose

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA LET'S ENCRYPT & CERTBOT                    │
├──────────────────────────────────────────────────────────────┤
│ ⚠️ REQUIERE EPEL (repositorio comunitario, ¡no Red Hat!)     │
│                                                              │
│ Instalar:     dnf install epel-release                       │
│               dnf install certbot python3-certbot-apache     │
│                                                              │
│ Apache:       certbot --apache -d example.com                │
│ NGINX:        certbot --nginx -d example.com                 │
│ Standalone:   certbot certonly --standalone -d example.com   │
│                                                              │
│ Probar:       certbot renew --dry-run                        │
│ Renovar:      certbot renew (automático vía temporizador)    │
│ Listar:       certbot certificates                           │
│                                                              │
│ Certs:        /etc/letsencrypt/live/<domain>/                │
│               fullchain.pem, privkey.pem                     │
│                                                              │
│ Timer:        systemctl status certbot-renew.timer           │
│ Logs:         /var/log/letsencrypt/letsencrypt.log           │
│                                                              │
│ Alternativa:  certmonger + FreeIPA / CA interna              │
│               ipa-getcert request ...                        │
└──────────────────────────────────────────────────────────────┘

⚠️ certbot NO disponible en repos oficiales RHEL
⚠️ EPEL tiene soporte comunitario, no soportado por Red Hat
✅ Para empresa: Considerar FreeIPA + certmonger (Capítulo 19)
✅ Usa certmonger para renovaciones de FreeIPA / CA interna

🧪 Laboratorio Práctico

Lab 13: Let’s Encrypt y Certbot

Obtén y renueva automáticamente certificados de Let’s Encrypt

  • 📁 Ubicación: labs/es_ES/13-letsencrypt-certbot/
  • ⏱️ Tiempo: 30-40 minutos
  • 🎯 Nivel: Intermedio

Navegación del Capítulo

Capítulo 25: Automatización Ansible para Certificados

Escalar: Gestiona certificados en cientos de sistemas RHEL con Ansible. Automatiza despliegue, renovación y monitoreo a escala empresarial.


25.1 ¿Por Qué Ansible para Certificados?

Gestión Manual:

❌ SSH a 100 servidores individualmente
❌ Copiar certificados uno por uno
❌ Configurar servicios manualmente
❌ Rastrear renovaciones por servidor
❌ Esperar no haber perdido ninguno

Automatización Ansible:

✅ Desplegar certificados a 100 servidores en minutos
✅ Configuración consistente
✅ Idempotente (seguro ejecutar repetidamente)
✅ Control de versiones (Git)
✅ Auditable (quién cambió qué cuándo)
✅ Capaz de rollback

25.2 Prerrequisitos

Instalar Ansible en RHEL

#============================================#
# INSTALAR ANSIBLE
#============================================#

# RHEL 8/9/10
sudo dnf install ansible-core -y

# O desde repositorio Ansible para lo último
sudo dnf install epel-release  # Si usas EPEL
sudo dnf install ansible -y

# Verificar
ansible --version

# Instalar colección community.crypto (¡ESENCIAL!)
ansible-galaxy collection install community.crypto

25.3 Inventario Ansible para Gestión de Certificados

Ejemplo de Inventario

#============================================#
# inventory/hosts.ini
#============================================#

[webservers]
web01.example.com
web02.example.com
web03.example.com

[mailservers]
mail01.example.com

[databases]
db01.example.com
db02.example.com

[all:vars]
ansible_user=ansible
ansible_become=yes
ansible_python_interpreter=/usr/bin/python3

25.4 Generar Certificados con Ansible

Playbook: Generar Claves Privadas

#============================================#
# playbooks/generate-keys.yml
#============================================#

---
- name: Generar Claves Privadas para Servidores RHEL
  hosts: webservers
  become: yes

  tasks:
    - name: Instalar OpenSSL
      dnf:
        name: openssl
        state: present

    - name: Generar clave privada
      community.crypto.openssl_privatekey:
        path: "/etc/pki/tls/private/{{ inventory_hostname }}.key"
        size: 2048
        type: RSA
        mode: '0600'
        owner: root
        group: root

    - name: Verificar clave generada
      stat:
        path: "/etc/pki/tls/private/{{ inventory_hostname }}.key"
      register: key_file

    - name: Mostrar resultado
      debug:
        msg: "Clave generada: {{ key_file.stat.exists }}"

Playbook: Generar CSRs

#============================================#
# playbooks/generate-csrs.yml
#============================================#

---
- name: Generar Solicitudes de Firma de Certificado
  hosts: webservers
  become: yes

  tasks:
    - name: Generar CSR
      community.crypto.openssl_csr:
        path: "/tmp/{{ inventory_hostname }}.csr"
        privatekey_path: "/etc/pki/tls/private/{{ inventory_hostname }}.key"
        common_name: "{{ inventory_hostname }}"
        subject_alt_name:
          - "DNS:{{ inventory_hostname }}"
          - "DNS:{{ inventory_hostname_short }}"
        key_usage:
          - digitalSignature
          - keyEncipherment
        extended_key_usage:
          - serverAuth
        organization_name: "Example Company"
        country_name: "US"

    - name: Obtener CSR a nodo de control
      fetch:
        src: "/tmp/{{ inventory_hostname }}.csr"
        dest: "csrs/{{ inventory_hostname }}.csr"
        flat: yes

25.5 Desplegar Certificados con Ansible

Playbook: Desplegar Certificados a Apache

#============================================#
# playbooks/deploy-apache-certs.yml
#============================================#

---
- name: Desplegar Certificados a Servidores Apache
  hosts: webservers
  become: yes

  vars:
    cert_source_dir: "/path/to/certificates"

  tasks:
    - name: Instalar Apache y mod_ssl
      dnf:
        name:
          - httpd
          - mod_ssl
        state: present

    - name: Desplegar certificado
      copy:
        src: "{{ cert_source_dir }}/{{ inventory_hostname }}.crt"
        dest: "/etc/pki/tls/certs/{{ inventory_hostname }}.crt"
        mode: '0644'
        owner: root
        group: root
      notify: reload apache

    - name: Desplegar clave privada
      copy:
        src: "{{ cert_source_dir }}/{{ inventory_hostname }}.key"
        dest: "/etc/pki/tls/private/{{ inventory_hostname }}.key"
        mode: '0600'
        owner: root
        group: root
        no_log: yes  # No registrar clave privada
      notify: reload apache

    - name: Configurar Apache SSL
      template:
        src: templates/ssl.conf.j2
        dest: /etc/httpd/conf.d/ssl.conf
        mode: '0644'
      notify: reload apache

    - name: Asegurar que Apache está ejecutándose
      service:
        name: httpd
        state: started
        enabled: yes

  handlers:
    - name: reload apache
      service:
        name: httpd
        state: reloaded

25.6 Validación de Certificados con Ansible

Playbook: Validar Certificados

#============================================#
# playbooks/validate-certificates.yml
#============================================#

---
- name: Validar Certificados en Servidores RHEL
  hosts: all
  become: yes

  tasks:
    - name: Encontrar todos los certificados
      find:
        paths: /etc/pki/tls/certs/
        patterns: '*.crt'
      register: certificates

    - name: Verificar expiración de certificado
      community.crypto.x509_certificate_info:
        path: "{{ item.path }}"
      register: cert_info
      loop: "{{ certificates.files }}"
      loop_control:
        label: "{{ item.path }}"

    - name: Identificar certificados expirando (30 días)
      set_fact:
        expiring_certs: "{{ expiring_certs | default([]) + [item.item.path] }}"
      when:
        - (item.not_after | to_datetime('%Y%m%d%H%M%SZ')) - (ansible_date_time.iso8601 | to_datetime) < '30 days'
      loop: "{{ cert_info.results }}"
      loop_control:
        label: "{{ item.item.path }}"

    - name: Reportar certificados expirando
      debug:
        msg: "⚠️ Certificado expirando pronto: {{ item }}"
      loop: "{{ expiring_certs | default([]) }}"
      when: expiring_certs is defined

25.7 Gestión de certmonger con Ansible

Playbook: Configurar Rastreo certmonger

#============================================#
# playbooks/setup-certmonger.yml
#============================================#

---
- name: Configurar Rastreo certmonger
  hosts: webservers
  become: yes

  tasks:
    - name: Instalar certmonger
      dnf:
        name: certmonger
        state: present

    - name: Asegurar que certmonger está ejecutándose
      service:
        name: certmonger
        state: started
        enabled: yes

    - name: Solicitar certificado de FreeIPA
      command: >
        ipa-getcert request
        -f /etc/pki/tls/certs/{{ inventory_hostname }}.crt
        -k /etc/pki/tls/private/{{ inventory_hostname }}.key
        -K HTTP/{{ inventory_hostname }}@EXAMPLE.COM
        -D {{ inventory_hostname }}
        -C "systemctl reload httpd"
      args:
        creates: /etc/pki/tls/certs/{{ inventory_hostname }}.crt

    - name: Verificar estado de certmonger
      command: getcert list
      register: cert_status
      changed_when: false

    - name: Mostrar estado
      debug:
        var: cert_status.stdout_lines

25.8 Monitoreo de Certificados con Ansible

Playbook: Reporte de Expiración de Certificados

#============================================#
# playbooks/cert-expiration-report.yml
#============================================#

---
- name: Generar Reporte de Expiración de Certificados
  hosts: all
  become: yes
  gather_facts: yes

  tasks:
    - name: Obtener expiración de certificado para Apache
      shell: |
        if [ -f /etc/pki/tls/certs/{{ inventory_hostname }}.crt ]; then
          openssl x509 -in /etc/pki/tls/certs/{{ inventory_hostname }}.crt -noout -enddate | cut -d= -f2
        else
          echo "No se encontró certificado"
        fi
      register: cert_expiry
      changed_when: false

    - name: Calcular días hasta expiración
      set_fact:
        days_left: "{{ ((cert_expiry.stdout | to_datetime('%b %d %H:%M:%S %Y %Z')) - (ansible_date_time.iso8601 | to_datetime)).days }}"
      when: cert_expiry.stdout != "No se encontró certificado"

    - name: Agregar a reporte
      set_fact:
        cert_report: |
          {{ inventory_hostname }},{{ cert_expiry.stdout }},{{ days_left | default('N/A') }}
      delegate_to: localhost
      delegate_facts: yes

    - name: Guardar reporte
      copy:
        content: "{{ hostvars | dict2items | map(attribute='value.cert_report') | join('\n') }}"
        dest: "/tmp/cert-expiration-report.csv"
      delegate_to: localhost
      run_once: yes

25.9 Flujo de Trabajo Completo de Despliegue de Certificados

Automatización de Extremo a Extremo

#============================================#
# playbooks/full-cert-deployment.yml
#============================================#

---
- name: Despliegue Completo de Certificados
  hosts: webservers
  become: yes

  vars:
    cert_domain: "example.com"
    cert_base_path: "/etc/pki/tls"

  pre_tasks:
    - name: Recopilar hechos
      setup:

  tasks:
    # 1. Asegurar que existan directorios
    - name: Asegurar que existan directorios de certificados
      file:
        path: "{{ item }}"
        state: directory
        mode: '0755'
      loop:
        - "{{ cert_base_path }}/certs"
        - "{{ cert_base_path }}/private"

    # 2. Generar clave privada (si no existe)
    - name: Generar clave privada
      community.crypto.openssl_privatekey:
        path: "{{ cert_base_path }}/private/{{ inventory_hostname }}.key"
        size: 2048
        mode: '0600'

    # 3. Desplegar certificado (desde controlador)
    - name: Desplegar certificado
      copy:
        src: "files/certs/{{ inventory_hostname }}.crt"
        dest: "{{ cert_base_path }}/certs/{{ inventory_hostname }}.crt"
        mode: '0644'
      notify: reload httpd

    # 4. Desplegar paquete CA
    - name: Desplegar paquete CA
      copy:
        src: "files/ca-bundle.crt"
        dest: "{{ cert_base_path }}/certs/ca-bundle.crt"
        mode: '0644'

    # 5. Configurar Apache
    - name: Desplegar configuración SSL de Apache
      template:
        src: templates/apache-ssl.conf.j2
        dest: /etc/httpd/conf.d/ssl.conf
        mode: '0644'
      notify: reload httpd

    # 6. Validar configuración
    - name: Probar configuración de Apache
      command: apachectl configtest
      changed_when: false

    # 7. Asegurar firewall abierto
    - name: Abrir HTTPS en firewall
      firewalld:
        service: https
        permanent: yes
        state: enabled
        immediate: yes

    # 8. Asegurar que Apache está ejecutándose
    - name: Asegurar que Apache está ejecutándose
      service:
        name: httpd
        state: started
        enabled: yes

  handlers:
    - name: reload httpd
      service:
        name: httpd
        state: reloaded

25.10 Roles Ansible para Certificados

Crear Rol Reutilizable

#============================================#
# CREAR ROL ANSIBLE PARA CERTIFICADOS
#============================================#

# Crear estructura de rol
ansible-galaxy role init certificates

# Estructura de directorio:
certificates/
├── defaults/
│   └── main.yml          # Variables predeterminadas
├── files/
│   └── ca-bundle.crt     # Certificados CA
├── handlers/
│   └── main.yml          # Handlers de recarga de servicio
├── tasks/
│   └── main.yml          # Tareas principales
├── templates/
│   └── ssl.conf.j2       # Plantillas de configuración
└── vars/
    └── main.yml          # Variables

Ejemplo de Tareas de Rol

#============================================#
# roles/certificates/tasks/main.yml
#============================================#

---
- name: Instalar herramientas de gestión de certificados
  dnf:
    name:
      - openssl
      - certmonger
    state: present

- name: Asegurar directorios de certificados
  file:
    path: "{{ item }}"
    state: directory
    mode: '0755'
  loop:
    - /etc/pki/tls/certs
    - /etc/pki/tls/private

- name: Desplegar certificados
  include_tasks: deploy-cert.yml
  loop: "{{ certificates }}"
  loop_control:
    loop_var: cert

- name: Configurar rastreo certmonger
  include_tasks: setup-certmonger.yml
  when: use_certmonger | default(false)

Usar el Rol

#============================================#
# playbook.yml
#============================================#

---
- name: Desplegar Certificados
  hosts: webservers
  become: yes

  roles:
    - role: certificates
      vars:
        certificates:
          - name: "{{ inventory_hostname }}"
            service: httpd
            principal: "HTTP/{{ inventory_hostname }}@REALM"

25.11 Mejores Prácticas

Mejores Prácticas de Gestión de Certificados Ansible

✅ **Usar colección community.crypto** para tareas de certificados
✅ **Cifrar claves privadas con vault** (ansible-vault)
✅ **Usar no_log para datos sensibles** (claves, contraseñas)
✅ **Probar en staging primero** antes de producción
✅ **Usar handlers** para recargas de servicio (evitar reinicios innecesarios)
✅ **Hacer playbooks idempotentes** (seguros para ejecutar múltiples veces)
✅ **Control de versiones** playbooks en Git
✅ **Documentar variables** y requisitos
✅ **Etiquetar tareas** para ejecución selectiva
✅ **Usar roles** para reutilización

Consideraciones de Seguridad

# Cifrar claves privadas con ansible-vault
ansible-vault encrypt files/private-keys/*.key

# Usar no_log para tareas sensibles
- name: Desplegar clave privada
  copy:
    src: "{{ key_file }}"
    dest: "/etc/pki/tls/private/server.key"
  no_log: yes

# Usar vault para contraseñas
# group_vars/all/vault.yml (cifrado)
admin_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          ...

25.12 Ejemplos Completos

Ejemplo 1: Desplegar CA a Todos los Servidores

---
- name: Desplegar CA Corporativa a Todos los Servidores RHEL
  hosts: all
  become: yes

  tasks:
    - name: Copiar certificado CA
      copy:
        src: files/corporate-ca.crt
        dest: /etc/pki/ca-trust/source/anchors/corporate-ca.crt
        mode: '0644'

    - name: Actualizar confianza CA
      command: update-ca-trust extract
      changed_when: true

    - name: Verificar CA instalada
      command: trust list
      register: trust_list
      changed_when: false

    - name: Confirmar CA presente
      assert:
        that:
          - "'Corporate CA' in trust_list.stdout"
        fail_msg: "¡CA Corporativa no está en almacén de confianza!"

Ejemplo 2: Verificación Masiva de Renovación de Certificados

---
- name: Verificar Expiración de Certificados en Toda la Flota
  hosts: all
  become: yes

  tasks:
    - name: Verificar estado de certmonger
      command: getcert list
      register: certmonger_status
      changed_when: false
      failed_when: false

    - name: Verificar CA_UNREACHABLE
      set_fact:
        has_issue: true
      when: "'CA_UNREACHABLE' in certmonger_status.stdout"

    - name: Reportar problemas
      debug:
        msg: "⚠️ ¡{{ inventory_hostname }} tiene certificados CA_UNREACHABLE!"
      when: has_issue | default(false)

    - name: Crear reporte de problemas
      lineinfile:
        path: "/tmp/cert-problems.txt"
        line: "{{ inventory_hostname }}: CA_UNREACHABLE"
        create: yes
      delegate_to: localhost
      when: has_issue | default(false)

25.13 Conclusiones Clave

  1. Ansible habilita despliegue masivo de certificados
  2. Colección community.crypto esencial para tareas de certificados
  3. Usar ansible-vault para claves privadas
  4. Playbooks idempotentes son críticos
  5. Probar en staging antes de producción
  6. Combinar con certmonger para mejores resultados
  7. Versionar todo en Git

Tarjeta de Referencia Rápida

┌─────────────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA AUTOMATIZACIÓN CERTIFICADOS ANSIBLE               │
├─────────────────────────────────────────────────────────────────────┤
│ Instalar:        dnf install ansible-core                           │
│ Colección:       ansible-galaxy collection install community.crypto │
│                                                                     │
│ Generar clave:   community.crypto.openssl_privatekey                │
│ Generar CSR:     community.crypto.openssl_csr                       │
│ Info cert:       community.crypto.x509_certificate_info             │
│                                                                     │
│ Desplegar cert:  copy module (con mode: '0644')                     │
│ Desplegar key:   copy module (con mode: '0600', no_log: yes)        │
│                                                                     │
│ Vault:           ansible-vault encrypt <file>                       │
│                  ansible-vault decrypt <file>                       │
│                                                                     │
│ Ejecutar:        ansible-playbook playbook.yml                      │
│ Simulación:      ansible-playbook playbook.yml --check              │
│ Específico:      ansible-playbook playbook.yml --tags certs         │
└─────────────────────────────────────────────────────────────────────┘

✅ Usar colección community.crypto
✅ Cifrar claves privadas con ansible-vault
✅ Usar no_log para datos sensibles

🧪 Laboratorio Práctico

Lab 14: Automatización con Ansible

Automatiza la implementación de certificados con Ansible

  • 📁 Ubicación: labs/es_ES/14-ansible-automation/
  • ⏱️ Tiempo: 40-50 minutos
  • 🎯 Nivel: Avanzado

Navegación del Capítulo

Capítulo 26: Monitoreo y Alertas en RHEL

Prevenir Interrupciones: El monitoreo proactivo previene sorpresas de expiración de certificados. Aprende cómo monitorear certificados y configurar alertas en RHEL.


26.1 ¿Por Qué Monitorear Certificados?

Sin Monitoreo:

❌ El certificado expira
❌ El sitio web cae a las 2 AM
❌ Incidente de emergencia
❌ Pérdida de ingresos
❌ Daño a reputación
❌ Noche estresante para el equipo de operaciones

Con Monitoreo:

✅ Alerta 30 días antes de expirar
✅ Renovación planificada durante horario laboral
✅ Sin interrupciones
✅ Sin emergencias
✅ Clientes contentos
✅ Equipo de operaciones bien descansado

26.2 Qué Monitorear

Métricas de Certificados

## Métricas Críticas:

✅ **Fecha de expiración** (días hasta expirar)
✅ **Validez del certificado** (aún no válido, expirado)
✅ **Coincidencia par certificado/clave**
✅ **Validez de cadena de confianza**
✅ **Estado de certmonger** (si se usa)
✅ **Salud del servicio** (usando el certificado)
✅ **Éxito/fallo de renovación**

## Umbrales de Advertencia:

🟡 60 días: Primera advertencia
🟠 30 días: Segunda advertencia
🔴 15 días: Alerta crítica
🚨 7 días: Escalación de emergencia

26.3 Scripts Simples de Monitoreo

Verificación Básica de Expiración

#!/bin/bash
# check-cert-expiration.sh
# Verificador simple de expiración de certificados

WARN_DAYS=30
CRIT_DAYS=7

check_cert() {
  local cert=$1
  local name=$(basename "$cert")

  if [ ! -f "$cert" ]; then
    echo "❌ $name: Archivo no encontrado"
    return 2
  fi

  # Obtener fecha de expiración
  expiry=$(openssl x509 -in "$cert" -noout -enddate 2>/dev/null | cut -d= -f2)

  if [ -z "$expiry" ]; then
    echo "❌ $name: Certificado inválido"
    return 2
  fi

  # Calcular días restantes
  expiry_epoch=$(date -d "$expiry" +%s 2>/dev/null)
  now_epoch=$(date +%s)
  days_left=$(( ($expiry_epoch - $now_epoch) / 86400 ))

  # Verificar umbrales
  if [ $days_left -lt 0 ]; then
    echo "🚨 $name: ¡EXPIRADO hace $((- days_left)) días!"
    return 2
  elif [ $days_left -lt $CRIT_DAYS ]; then
    echo "🔴 $name: CRÍTICO - quedan $days_left días"
    return 2
  elif [ $days_left -lt $WARN_DAYS ]; then
    echo "🟡 $name: ADVERTENCIA - quedan $days_left días"
    return 1
  else
    echo "✅ $name: OK - quedan $days_left días"
    return 0
  fi
}

# Verificar todos los certificados
for cert in /etc/pki/tls/certs/*.crt; do
  check_cert "$cert"
done

Monitor de Estado de certmonger

#!/bin/bash
# monitor-certmonger.sh
# Monitorear estado de rastreo de certmonger

echo "=== Monitor de Estado certmonger ==="

# Verificar si certmonger está ejecutándose
if ! systemctl is-active --quiet certmonger; then
  echo "🚨 CRÍTICO: ¡certmonger no está ejecutándose!"
  systemctl status certmonger
  exit 2
fi

# Obtener estado de certmonger
STATUS_OUTPUT=$(sudo getcert list 2>&1)

# Contar certificados por estado
TOTAL=$(echo "$STATUS_OUTPUT" | grep -c "Request ID")
MONITORING=$(echo "$STATUS_OUTPUT" | grep -c "status: MONITORING")
UNREACHABLE=$(echo "$STATUS_OUTPUT" | grep -c "status: CA_UNREACHABLE")
REJECTED=$(echo "$STATUS_OUTPUT" | grep -c "status: CA_REJECTED")

echo "Total de certificados: $TOTAL"
echo "  MONITORING: $MONITORING ✅"
echo "  CA_UNREACHABLE: $UNREACHABLE $([ $UNREACHABLE -gt 0 ] && echo '⚠️')"
echo "  CA_REJECTED: $REJECTED $([ $REJECTED -gt 0 ] && echo '❌')"

# Alertar si hay problemas
if [ $UNREACHABLE -gt 0 ] || [ $REJECTED -gt 0 ]; then
  echo ""
  echo "🚨 SE REQUIERE ATENCIÓN:"
  sudo getcert list | grep -B5 "status: CA_" | grep -E "(Request ID|status:)"
  exit 1
fi

echo "✅ Todos los certificados OK"

26.4 Temporizador Systemd para Monitoreo

Crear Temporizador de Monitoreo

#============================================#
# CREAR TEMPORIZADOR SYSTEMD PARA MONITOREO
#============================================#

# Crear archivo de servicio
sudo tee /etc/systemd/system/cert-monitor.service << 'EOF'
[Unit]
Description=Certificate Expiration Monitor
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/check-cert-expiration.sh
StandardOutput=journal
StandardError=journal
EOF

# Crear archivo de temporizador (ejecutar diariamente)
sudo tee /etc/systemd/system/cert-monitor.timer << 'EOF'
[Unit]
Description=Daily Certificate Monitoring
Requires=cert-monitor.service

[Timer]
OnCalendar=daily
OnBootSec=15min
Persistent=true

[Install]
WantedBy=timers.target
EOF

# Instalar script de monitoreo
sudo cp check-cert-expiration.sh /usr/local/bin/
sudo chmod +x /usr/local/bin/check-cert-expiration.sh

# Habilitar temporizador
sudo systemctl daemon-reload
sudo systemctl enable cert-monitor.timer
sudo systemctl start cert-monitor.timer

# Verificar
systemctl list-timers | grep cert-monitor

# Probar manualmente
sudo systemctl start cert-monitor.service
sudo journalctl -u cert-monitor.service

26.5 Alertas por Email

Alertas Simples por Email

#!/bin/bash
# cert-monitor-with-email.sh
# Monitor de certificados con alertas por email

EMAIL="admin@example.com"
WARN_DAYS=30

ALERTS=""

for cert in /etc/pki/tls/certs/*.crt; do
  [ -f "$cert" ] || continue

  if ! openssl x509 -in "$cert" -noout -checkend $((86400*WARN_DAYS)) 2>/dev/null; then
    expiry=$(openssl x509 -in "$cert" -noout -enddate | cut -d= -f2)
    ALERTS="$ALERTS\nCertificado: $cert\nExpira: $expiry\n"
  fi
done

if [ -n "$ALERTS" ]; then
  echo -e "Advertencias de Expiración de Certificados:\n$ALERTS" | \
    mail -s "⚠️ Alerta de Expiración de Certificados - $(hostname)" "$EMAIL"
fi

26.6 Monitoreo Prometheus (Avanzado)

Exportador de Certificados

#============================================#
# MONITOREO CERTIFICADOS PROMETHEUS
#============================================#

# Instalar x509-certificate-exporter (ejemplo)
# https://github.com/enix/x509-certificate-exporter

# O usar colector textfile de Node Exporter

# Crear script colector de métricas
cat > /usr/local/bin/cert-metrics.sh << 'EOF'
#!/bin/bash
# Generar métricas Prometheus para certificados

METRICS_FILE="/var/lib/node_exporter/textfile_collector/certificates.prom"
mkdir -p $(dirname "$METRICS_FILE")

cat > "$METRICS_FILE" << PROM
# HELP certificate_expiry_days Días hasta expiración de certificado
# TYPE certificate_expiry_days gauge
PROM

for cert in /etc/pki/tls/certs/*.crt; do
  [ -f "$cert" ] || continue

  expiry=$(openssl x509 -in "$cert" -noout -enddate 2>/dev/null | cut -d= -f2)
  expiry_epoch=$(date -d "$expiry" +%s 2>/dev/null)
  now_epoch=$(date +%s)
  days_left=$(( ($expiry_epoch - $now_epoch) / 86400 ))

  echo "certificate_expiry_days{cert=\"$cert\",hostname=\"$(hostname)\"} $days_left" >> "$METRICS_FILE"
done
EOF

chmod +x /usr/local/bin/cert-metrics.sh

# Ejecutar vía cron
echo "*/5 * * * * /usr/local/bin/cert-metrics.sh" | sudo crontab -

Reglas de Alerta Prometheus

#============================================#
# prometheus-alerts.yml
#============================================#

groups:
  - name: certificates
    rules:
      - alert: CertificateExpiringSoon
        expr: certificate_expiry_days < 30
        for: 1h
        labels:
          severity: warning
        annotations:
          summary: "Certificado expirando en {{ $value }} días"
          description: "Certificado {{ $labels.cert }} en {{ $labels.hostname }} expira en {{ $value }} días"

      - alert: CertificateExpiryCritical
        expr: certificate_expiry_days < 7
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "¡Certificado expirando en {{ $value }} días!"
          description: "URGENTE: Certificado {{ $labels.cert }} en {{ $labels.hostname }} expira en {{ $value }} días!"

      - alert: CertificateExpired
        expr: certificate_expiry_days < 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "¡Certificado EXPIRADO!"
          description: "¡Certificado {{ $labels.cert }} en {{ $labels.hostname }} ha expirado!"

26.7 Logging Centralizado

Enviar Eventos de Certificados a Syslog

#============================================#
# REGISTRAR EVENTOS DE CERTIFICADOS
#============================================#

# certmonger registra en journal
sudo journalctl -u certmonger -f

# Reenviar a syslog central
# /etc/rsyslog.conf
*.* @@syslog-server.example.com:514

# O configurar logging específico de certmonger
# Monitorear renovaciones de certmonger
sudo journalctl -u certmonger --since today | grep -i "renewed\|failed"

26.8 Comparación de Herramientas de Monitoreo

Opciones para RHEL

HerramientaComplejidadCostoIntegraciónAlertas
Scripts simplesBajaGratisFácilEmail/syslog
Nagios/IcingaMediaGratisBuenaMúltiples
Prometheus + GrafanaMedia-AltaGratisExcelentePotente
ZabbixMediaGratisBuenaMúltiples
Comercial (Datadog, etc.)Baja$$$ExcelenteAvanzadas
Red Hat InsightsBajaSuscripciónNativaDashboard

Recomendación para RHEL:

  • Pequeño: Scripts simples + email
  • Mediano: Prometheus + Grafana
  • Empresa: Comercial o Red Hat Insights

26.9 Solución de Monitoreo Completa

Script de Monitoreo Comprehensivo

#!/bin/bash
# comprehensive-cert-monitor.sh
# Monitoreo completo de certificados para RHEL

WARN_DAYS=30
CRIT_DAYS=7
EMAIL="admin@example.com"
LOG_FILE="/var/log/cert-monitor.log"

log() {
  echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

send_alert() {
  local subject=$1
  local body=$2
  echo "$body" | mail -s "$subject" "$EMAIL"
  logger -t cert-monitor "$subject"
}

log "=== Iniciando Monitor de Certificados ==="

# Verificación 1: ¿certmonger ejecutándose?
if ! systemctl is-active --quiet certmonger; then
  send_alert "🚨 certmonger NO ejecutándose en $(hostname)" \
    "¡El servicio certmonger no está ejecutándose. Las renovaciones de certificados pueden fallar!"
fi

# Verificación 2: Estado de certmonger
UNREACHABLE=$(sudo getcert list | grep -c "CA_UNREACHABLE")
if [ $UNREACHABLE -gt 0 ]; then
  send_alert "⚠️ CA inalcanzable para $UNREACHABLE certificados en $(hostname)" \
    "$(sudo getcert list | grep -B5 'CA_UNREACHABLE')"
fi

# Verificación 3: Expiración de certificado
CRITICAL=0
WARNING=0

for cert in /etc/pki/tls/certs/*.crt; do
  [ -f "$cert" ] || continue

  expiry=$(openssl x509 -in "$cert" -noout -enddate 2>/dev/null | cut -d= -f2)
  [ -z "$expiry" ] && continue

  expiry_epoch=$(date -d "$expiry" +%s 2>/dev/null)
  now_epoch=$(date +%s)
  days_left=$(( ($expiry_epoch - $now_epoch) / 86400 ))

  if [ $days_left -lt 0 ]; then
    log "🚨 EXPIRADO: $cert"
    ((CRITICAL++))
  elif [ $days_left -lt $CRIT_DAYS ]; then
    log "🔴 CRÍTICO ($days_left días): $cert"
    ((CRITICAL++))
  elif [ $days_left -lt $WARN_DAYS ]; then
    log "🟡 ADVERTENCIA ($days_left días): $cert"
    ((WARNING++))
  else
    log "✅ OK ($days_left días): $cert"
  fi
done

# Enviar alerta resumen si hay problemas
if [ $CRITICAL -gt 0 ] || [ $WARNING -gt 0 ]; then
  SUMMARY="Crítico: $CRITICAL, Advertencia: $WARNING\n\n$(tail -20 $LOG_FILE)"
  send_alert "Alerta de Certificados: $(hostname)" "$SUMMARY"
fi

log "=== Monitor Completo: Crítico=$CRITICAL, Advertencia=$WARNING ==="

26.10 Monitoreo con Grafana

Ejemplo de Dashboard

{
  "dashboard": {
    "title": "Monitoreo de Certificados RHEL",
    "panels": [
      {
        "title": "Certificados Expirando Pronto",
        "targets": [
          {
            "expr": "certificate_expiry_days < 30"
          }
        ]
      },
      {
        "title": "Estado de certmonger",
        "targets": [
          {
            "expr": "certmonger_status != 'MONITORING'"
          }
        ]
      }
    ]
  }
}

26.11 Conclusiones Clave

  1. Monitorear proactivamente - No esperar a la expiración
  2. Advertencia de 30 días mínimo recomendada
  3. Estado de certmonger crítico si se usa automatización
  4. Múltiples canales de alerta (email, Slack, PagerDuty)
  5. Probar monitoreo - Asegurar que las alertas realmente te alcancen
  6. Registrar todo para pista de auditoría
  7. Automatizar remediación donde sea posible

Tarjeta de Referencia Rápida

┌────────────────── ────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA MONITOREO DE CERTIFICADOS                       │
├───────────────── ─────────────────────────────────────────────────┤
│ Ver expiración:  openssl x509 -in cert.crt -noout -checkend 86400 │
│ Días restantes:  openssl x509 -in cert.crt -noout -enddate        │
│                                                                   │
│ certmonger:      getcert list                                     │
│ Estado:          getcert list | grep "status:"                    │
│ Logs:            journalctl -u certmonger                         │
│                                                                   │
│ Niveles alerta:  60 días (info)                                   │
│                  30 días (advertencia)                            │
│                  7 días (crítico)                                 │
│                  0 días (¡emergencia!)                            │
│                                                                   │
│ Herramientas:    Scripts simples, Prometheus, Nagios, Zabbix      │
│ Nativo:          Rastreo integrado de certmonger                  │
└───────────────────────────────────────────────────────────────────┘

✅ Monitorear == ¡Sin Sorpresas!
✅ Automatizar monitoreo con temporizadores systemd o cron

Navegación del Capítulo

Capítulo 27: Metodología de Solución de Problemas de Certificados RHEL

Habilidad Crítica: Este capítulo te enseña un enfoque sistemático para resolver CUALQUIER problema de certificado en sistemas RHEL. Domina esta metodología y resolverás problemas en minutos en lugar de horas.


27.1 El Problema

Los problemas de certificados son frustrantes:

  • Los mensajes de error son crípticos
  • Las causas raíz están ocultas
  • Múltiples capas involucradas (OpenSSL, config de servicio, SELinux, crypto-policies)
  • Varía según versión de RHEL

La solución de problemas aleatoria no funciona. Necesitas un sistema.


27.2 El Enfoque Sistemático

Sigue esta metodología de 7 pasos para CADA problema de certificado:

Paso 1: Identificar Versión de RHEL y Entorno
Paso 2: Verificar Propiedades Básicas del Certificado
Paso 3: Verificar Cadena de Confianza y Validación CA
Paso 4: Verificar Configuración del Servicio
Paso 5: Verificar Ajustes a Nivel del Sistema
Paso 6: Probar Funcionalidad del Certificado
Paso 7: Revisar Logs y Detalles de Errores

Regla: Nunca saltar pasos. Cada uno proporciona información de diagnóstico crítica.


27.3 Paso 1: Identificar Versión de RHEL y Entorno

Por Qué Importa

El comportamiento de certificados difiere significativamente entre versiones de RHEL.

Verificaciones Rápidas

#============================================#
# VERIFICACIÓN DE VERSIÓN RHEL
#============================================#

# 1. Verificar versión de RHEL
cat /etc/redhat-release
# Salida ejemplo: Red Hat Enterprise Linux release 9.8 (Plow)

# 2. Verificar versión de OpenSSL
openssl version
# RHEL 7: OpenSSL 1.0.2k
# RHEL 8: OpenSSL 1.1.1k
# RHEL 9/10: OpenSSL 3.5.5

# 3. Verificar crypto-policy (RHEL 8+)
update-crypto-policies --show 2>/dev/null
# DEFAULT, LEGACY, FUTURE, o FIPS

# 4. Verificar modo FIPS
fips-mode-setup --check 2>/dev/null
# FIPS mode is enabled/disabled

# 5. Verificar estado de SELinux
getenforce
# Enforcing, Permissive, o Disabled

Qué Documentar

Crear una nota de solución de problemas con:

Versión RHEL: _______
Versión OpenSSL: _______
Crypto-Policy: _______ (si RHEL 8+)
Modo FIPS: _______
SELinux: _______
Servicio: _______ (Apache, NGINX, Postfix, etc.)

27.4 Paso 2: Verificar Propiedades Básicas del Certificado

Las Cinco Verificaciones Esenciales

#============================================#
# VERIFICACIÓN 1: Expiración del Certificado
#============================================#

# Ver fechas del certificado
openssl x509 -in /path/to/cert.crt -noout -dates

# Salida:
# notBefore=Jan 1 00:00:00 2024 GMT
# notAfter=Jan 1 23:59:59 2025 GMT   ← ¡Debe estar en el futuro!

# Verificación rápida si expiró
openssl x509 -in /path/to/cert.crt -noout -checkend 0
# Exit 0 = válido, Exit 1 = expirado

# Verificar expiración en X días
openssl x509 -in /path/to/cert.crt -noout -checkend $((86400*30))
# Verificar si expira en los próximos 30 días


#============================================#
# VERIFICACIÓN 2: Sujeto/Hostname del Certificado
#============================================#

# Ver sujeto (para quién es el certificado)
openssl x509 -in /path/to/cert.crt -noout -subject
# subject=CN=server.example.com

# Ver Subject Alternative Names (SANs) - ¡CRÍTICO!
openssl x509 -in /path/to/cert.crt -noout -ext subjectAltName
# X509v3 Subject Alternative Name:
#     DNS:server.example.com, DNS:www.example.com

# ⚠️ Los navegadores modernos REQUIEREN SANs (CN solo es insuficiente)


#============================================#
# VERIFICACIÓN 3: Coincidencia Par Certificado/Clave
#============================================#

# Obtener módulo del certificado
openssl x509 -noout -modulus -in /path/to/cert.crt | openssl md5

# Obtener módulo de la clave
openssl rsa -noout -modulus -in /path/to/cert.key | openssl md5

# ✅ Si los hashes MD5 coinciden → cert y clave están emparejados
# ❌ Si diferentes → ¡CLAVE INCORRECTA!


#============================================#
# VERIFICACIÓN 4: Emisor del Certificado
#============================================#

# Ver quién firmó este certificado
openssl x509 -in /path/to/cert.crt -noout -issuer
# issuer=C=US, O=Let's Encrypt, CN=R3

# ¿Autofirmado? (sujeto == emisor)
openssl x509 -in /path/to/cert.crt -noout -subject -issuer | sort | uniq -d
# Si la salida no está vacía → autofirmado


#============================================#
# VERIFICACIÓN 5: Algoritmo de Certificado y Tamaño de Clave
#============================================#

# Ver algoritmo de firma
openssl x509 -in /path/to/cert.crt -noout -text | grep "Signature Algorithm"
# Signature Algorithm: sha256WithRSAEncryption   ← Bueno
# Signature Algorithm: sha1WithRSAEncryption     ← Malo (obsoleto)

# Ver tamaño de clave pública
openssl x509 -in /path/to/cert.crt -noout -text | grep "Public-Key"
# Public-Key: (2048 bit)   ← Mínimo
# Public-Key: (4096 bit)   ← Mejor

# ⚠️ RHEL 8+ rechaza claves < 2048 bits por defecto
# ⚠️ RHEL 9+ rechaza firmas SHA-1 por defecto

Script de Validación Rápida

#!/bin/bash
# quick-cert-check.sh
CERT=$1

echo "=== Verificación Rápida de Certificado ==="
echo ""
echo "Archivo: $CERT"
echo ""

echo "1. Expiración:"
openssl x509 -in "$CERT" -noout -dates

echo ""
echo "2. Sujeto:"
openssl x509 -in "$CERT" -noout -subject

echo ""
echo "3. SANs:"
openssl x509 -in "$CERT" -noout -ext subjectAltName 2>/dev/null || echo "No se encontraron SANs"

echo ""
echo "4. Emisor:"
openssl x509 -in "$CERT" -noout -issuer

echo ""
echo "5. Algoritmo y Clave:"
openssl x509 -in "$CERT" -noout -text | grep -E "(Signature Algorithm|Public-Key)"

echo ""
echo "6. ¿Aún válido?"
if openssl x509 -in "$CERT" -noout -checkend 0 >/dev/null 2>&1; then
    echo "✅ El certificado es válido"
else
    echo "❌ ¡El certificado ha expirado!"
fi

Uso:

bash quick-cert-check.sh /etc/pki/tls/certs/server.crt

27.5 Paso 3: Verificar Cadena de Confianza y Validación CA

Entender la Cadena

CA Raíz (debe ser confiable para el sistema)
  └─ CA(s) Intermedia(s)
      └─ Certificado del Servidor (tu certificado)

Verificar Cadena de Confianza

#============================================#
# VERIFICAR CADENA COMPLETA DE CERTIFICADO
#============================================#

# Método 1: Verificar contra paquete CA del sistema
openssl verify /path/to/cert.crt
# /path/to/cert.crt: OK   ← ¡Bueno!
# error 20: unable to get local issuer certificate   ← ¡Falta CA!

# Método 2: Verificar con archivo CA específico
openssl verify -CAfile /etc/pki/tls/certs/ca-bundle.crt /path/to/cert.crt

# Método 3: Mostrar cadena completa
openssl s_client -connect server.example.com:443 -showcerts


#============================================#
# VERIFICAR SI CA ES CONFIABLE POR RHEL
#============================================#

# Listar todas las CAs confiables
trust list | grep -i "certificate-authority"

# Buscar CA específica
trust list | grep -i "Let's Encrypt"

# Verificar si archivo CA específico es confiable
trust list --filter=ca-anchors | grep -A5 "pkcs11"


#============================================#
# VER CADENA DE CERTIFICADO
#============================================#

# Extraer y ver cadena completa desde servidor
openssl s_client -connect server.example.com:443 -showcerts 2>/dev/null | \
  awk '/BEGIN CERT/,/END CERT/ {print}'

# Ver cadena desde archivo (si está en paquete)
openssl crl2pkcs7 -nocrl -certfile /path/to/chain.crt | \
  openssl pkcs7 -print_certs -text -noout


#============================================#
# VERIFICAR CERTIFICADOS INTERMEDIOS
#============================================#

# Problema común: ¡Falta certificado intermedio!
# Servidor debería enviar: [Cert Servidor] → [Intermedio] → [Raíz]
# Pero solo envía: [Cert Servidor]
# Resultado: ¡El cliente no puede validar cadena!

# Probar desde otra máquina
echo | openssl s_client -connect server.example.com:443 -servername server.example.com 2>&1 | \
  grep -E "(verify return code|Verify return code)"
# Verify return code: 0 (ok)   ← Bueno
# Verify return code: 21 (unable to verify the first certificate)   ← ¡Falta intermedio!

Problemas Comunes de Confianza

Código ErrorSignificadoSolución
0OK✅ Sin problemas
19Certificado autofirmado en cadenaAgregar CA al almacén de confianza
20No se puede obtener cert emisor localFalta CA o intermedio
21No se puede verificar primer certificadoFalta cert intermedio
27Certificado no confiableCA no en almacén de confianza del sistema

27.6 Paso 4: Verificar Configuración del Servicio

Verificaciones Específicas por Servicio

#============================================#
# APACHE (httpd)
#============================================#

# Verificar configuración SSL
sudo apachectl -t -D DUMP_VHOSTS | grep -A5 ":443"

# Ver rutas de cert SSL
sudo grep -r "SSLCertificateFile\|SSLCertificateKeyFile" /etc/httpd/

# Probar sintaxis de configuración
sudo apachectl configtest

# Verificar módulos SSL cargados
sudo httpd -M | grep ssl


#============================================#
# NGINX
#============================================#

# Probar configuración
sudo nginx -t

# Ver rutas SSL
sudo grep -r "ssl_certificate\|ssl_certificate_key" /etc/nginx/

# Verificar archivos de certificado referenciados
sudo nginx -T | grep "ssl_certificate"


#============================================#
# POSTFIX (Correo)
#============================================#

# Ver ajustes TLS
sudo postconf | grep -i tls

# Verificar rutas cert/clave
sudo postconf smtpd_tls_cert_file smtpd_tls_key_file

# Probar TLS
openssl s_client -connect localhost:25 -starttls smtp


#============================================#
# OPENLDAP
#============================================#

# Verificar ajustes TLS
sudo grep -i "TLSCert\|TLSKey" /etc/openldap/slapd.conf /etc/openldap/slapd.d/* 2>/dev/null

# Probar LDAPS
openssl s_client -connect localhost:636


#============================================#
# POSTGRESQL
#============================================#

# Verificar ajustes SSL
sudo -u postgres psql -c "SHOW ssl_cert_file; SHOW ssl_key_file;"

# Probar conexión SSL
psql "host=localhost sslmode=require"

Verificación de Permisos de Archivo

#============================================#
# VERIFICAR PERMISOS (¡CRÍTICO!)
#============================================#

# Archivos de certificado (públicos) deberían ser legibles
ls -l /etc/pki/tls/certs/*.crt
# -rw-r--r-- (644)   ← Bueno

# Archivos de clave (privados) deberían estar protegidos
ls -l /etc/pki/tls/private/*.key
# -rw------- (600) o -rw-r----- (640)   ← Bueno
# -rw-r--r-- (644)   ← ¡MALO! ¡Muy permisivo!

# Verificar ownership
ls -l /etc/pki/tls/private/*.key
# Debería ser propiedad del usuario del servicio o root

# Corregir permisos si es necesario
sudo chmod 600 /etc/pki/tls/private/server.key
sudo chown root:root /etc/pki/tls/private/server.key

27.7 Paso 5: Verificar Ajustes a Nivel del Sistema

Específico por Versión de RHEL

#============================================#
# RHEL 8/9/10: VERIFICAR CRYPTO-POLICIES
#============================================#

# Política actual
update-crypto-policies --show
# DEFAULT, LEGACY, FUTURE, o FIPS

# Si el servicio falla con "no shared cipher" o similar:
# Probar temporalmente con política LEGACY
sudo update-crypto-policies --set LEGACY
sudo systemctl restart <servicio>

# Probar si funciona ahora
# Si SÍ → incompatibilidad de cifrado/versión TLS
# Si NO → problema diferente

# Revertir a DEFAULT
sudo update-crypto-policies --set DEFAULT


#============================================#
# VERIFICAR MODO FIPS (Todas las Versiones)
#============================================#

fips-mode-setup --check
# FIPS mode is enabled.

# En modo FIPS, se aplican restricciones adicionales:
# - Solo algoritmos aprobados
# - Requisitos de clave más estrictos
# - Algunos cifrados deshabilitados


#============================================#
# VERIFICAR SELINUX (¡Crítico!)
#============================================#

# Estado de SELinux
getenforce
# Enforcing, Permissive, o Disabled

# Verificar denegaciones relacionadas con certificados
sudo ausearch -m avc -ts recent | grep -i cert

# Verificar contexto SELinux de archivos cert
ls -Z /etc/pki/tls/certs/server.crt
# system_u:object_r:cert_t:s0   ← Correcto

# Si está mal, reetiquetar
sudo restorecon -v /etc/pki/tls/certs/server.crt
sudo restorecon -v /etc/pki/tls/private/server.key


#============================================#
# VERIFICAR FIREWALL
#============================================#

# Verificar que el puerto del servicio está abierto
sudo firewall-cmd --list-all | grep -E "(https|443|ldaps|636)"

# Si no está abierto
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload

27.8 Paso 6: Probar Funcionalidad del Certificado

Pruebas de Conexión en Vivo

#============================================#
# PROBAR CONEXIÓN HTTPS/TLS
#============================================#

# Método 1: openssl s_client (más detallado)
openssl s_client -connect server.example.com:443 -servername server.example.com

# Buscar:
# - "Verify return code: 0 (ok)"   ← Bueno
# - Visualización de cadena de certificado
# - Cifrado negociado
# - Versión de protocolo (TLS 1.2/1.3)

# Método 2: curl (prueba rápida)
curl -v https://server.example.com/
# Buscar:
# * SSL connection using TLSv1.3
# * Server certificate:
# *  subject: CN=server.example.com
# *  issuer: CN=Let's Encrypt Authority

# Método 3: Probar con versión TLS específica
openssl s_client -connect server.example.com:443 -tls1_2
openssl s_client -connect server.example.com:443 -tls1_3


#============================================#
# PROBAR DESDE PERSPECTIVA DE CLIENTE
#============================================#

# Probar resolución DNS
nslookup server.example.com
# Debe resolver a IP correcta

# Probar conectividad de red
telnet server.example.com 443
nc -zv server.example.com 443

# Probar con diferentes clientes
curl --insecure https://server.example.com/   # Saltar verificación cert
wget --no-check-certificate https://server.example.com/

Pruebas de Validación de Certificado

#============================================#
# VALIDAR ASPECTOS ESPECÍFICOS
#============================================#

# Probar coincidencia de hostname
openssl s_client -connect server.example.com:443 -servername server.example.com 2>&1 | \
  grep "verify return"

# Probar con hostname incorrecto (debería fallar)
openssl s_client -connect server.example.com:443 -servername wrong.example.com 2>&1 | \
  grep "verify return"

# Probar expiración
openssl s_client -connect server.example.com:443 2>&1 | openssl x509 -noout -dates

# Probar fortaleza de cifrado
openssl s_client -connect server.example.com:443 -cipher 'HIGH:!aNULL:!MD5'

27.9 Paso 7: Revisar Logs y Detalles de Errores

Dónde Buscar

#============================================#
# LOGS DE SERVICIO
#============================================#

# Apache
sudo tail -f /var/log/httpd/error_log
sudo tail -f /var/log/httpd/ssl_error_log

# NGINX
sudo tail -f /var/log/nginx/error.log

# Postfix
sudo tail -f /var/log/maillog

# Journal del sistema (todos los servicios)
sudo journalctl -u httpd.service -f
sudo journalctl -u nginx.service -f
sudo journalctl -xe | grep -i cert


#============================================#
# LOGS DE CERTMONGER (Renovación Auto)
#============================================#

# Estado de certmonger
sudo getcert list

# Logs de certmonger
sudo journalctl -u certmonger.service -f

# Estado detallado para cert específico
sudo getcert list -i <request-id>


#============================================#
# DENEGACIONES SELINUX
#============================================#

# Denegaciones AVC recientes
sudo ausearch -m avc -ts recent

# Denegaciones relacionadas con certificados
sudo ausearch -m avc -ts today | grep -i cert


#============================================#
# ERRORES OPENSSL/TLS
#============================================#

# Comunes en logs:
# - "SSL_CTX_use_certificate:ca md too weak" → Algoritmo de firma débil
# - "unable to get local issuer certificate" → Falta CA
# - "certificate has expired" → Cert expirado
# - "certificate verify failed" → Fallo validación de cadena
# - "no shared cipher" → Desajuste de cifrado
# - "wrong version number" → Desajuste de protocolo

27.10 Árboles de Decisión

Diagrama de Flujo de Diagnóstico Rápido

Problema de Certificado
    │
    ├─ ¿El servicio no inicia?
    │   ├─ Verificar rutas de archivo en config
    │   ├─ Verificar permisos de archivo (600 para claves)
    │   ├─ Verificar coincidencia par cert/clave
    │   └─ Verificar contexto SELinux
    │
    ├─ ¿La conexión falla con "certificate verify failed"?
    │   ├─ Verificar confianza CA (Paso 3)
    │   ├─ Verificar certificados intermedios
    │   └─ Verificar crypto-policy (RHEL 8+)
    │
    ├─ ¿"Certificate has expired"?
    │   ├─ Verificar con: openssl x509 -noout -dates
    │   ├─ Verificar estado de certmonger
    │   └─ Renovar certificado
    │
    ├─ ¿"Hostname does not match"?
    │   ├─ Verificar SANs: openssl x509 -noout -ext subjectAltName
    │   ├─ Verificar resolución DNS
    │   └─ Verificar directiva server_name/ServerName
    │
    └─ ¿"No shared cipher" / "wrong version number"?
        ├─ Verificar crypto-policy (RHEL 8+)
        ├─ Verificar compatibilidad versión TLS
        └─ Probar con: openssl s_client -tls1_2

27.11 Kit de Herramientas de Solución de Problemas

Comandos Esenciales

# Tarjeta de referencia rápida para solución de problemas

# 1. IDENTIFICAR
cat /etc/redhat-release
openssl version
update-crypto-policies --show

# 2. VERIFICAR CERTIFICADO
openssl x509 -in cert.crt -noout -text
openssl x509 -in cert.crt -noout -dates
openssl x509 -in cert.crt -noout -subject

# 3. VERIFICAR CONFIANZA
openssl verify cert.crt
trust list | grep -i "authority"

# 4. PROBAR CONEXIÓN
openssl s_client -connect host:443 -servername host
curl -v https://host/

# 5. VERIFICAR PERMISOS
ls -lZ /etc/pki/tls/certs/cert.crt
ls -lZ /etc/pki/tls/private/key.key

# 6. VERIFICAR LOGS
sudo journalctl -xe | grep -i cert
sudo tail -f /var/log/httpd/ssl_error_log

Crear Tu Lista de Verificación de Solución de Problemas

## Lista de Verificación de Problemas de Certificado

### Entorno
- [ ] Versión RHEL: _______
- [ ] Versión OpenSSL: _______
- [ ] Crypto-Policy (RHEL 8+): _______
- [ ] Modo FIPS: _______
- [ ] SELinux: _______
- [ ] Servicio: _______

### Verificaciones de Certificado
- [ ] Fecha de expiración del certificado
- [ ] Sujeto/hostname coincide
- [ ] SANs presentes y correctos
- [ ] Par certificado/clave coincide
- [ ] Algoritmo de firma (SHA-256 o superior; sin SHA-1 ni MD5)
- [ ] Tamaño de clave (>= 2048 bits)

### Cadena de Confianza
- [ ] Certificado valida con paquete CA del sistema
- [ ] Certificados intermedios presentes
- [ ] CA raíz confiable para el sistema

### Configuración de Servicio
- [ ] Rutas de archivo correctas en config
- [ ] Permisos de archivo correctos (600 para claves)
- [ ] Contextos SELinux correctos
- [ ] Sintaxis de config de servicio válida

### Ajustes del Sistema
- [ ] Crypto-policy compatible (RHEL 8+)
- [ ] Requisitos FIPS cumplidos (si aplica)
- [ ] Firewall permite conexiones
- [ ] Sin denegaciones SELinux

### Pruebas
- [ ] Prueba de conexión con openssl s_client
- [ ] Prueba de conexión con curl
- [ ] Verificación de hostname pasa

### Logs
- [ ] Logs de servicio revisados
- [ ] Journal del sistema verificado
- [ ] Log de auditoría SELinux verificado

27.12 Conclusiones Clave

  1. Siempre seguir la metodología de 7 pasos - no saltar pasos
  2. Verificar versión RHEL primero - el comportamiento varía significativamente
  3. Verificar propiedades básicas del certificado antes de solución de problemas compleja
  4. Problemas de cadena de confianza son el problema más común
  5. Permisos de archivo causan muchos fallos “misteriosos”
  6. Crypto-policies (RHEL 8+) afectan todo
  7. SELinux puede bloquear acceso a certificados
  8. Los logs cuentan la historia - siempre verificarlos

27.13 Escenarios de Práctica

Ver próximos capítulos para solución de problemas detallada de:

  • Capítulo 28: Errores Comunes de Certificados en RHEL
  • Capítulo 29: Solución de Problemas Específica por Servicio
  • Capítulo 30: Solución de Problemas de certmonger
  • Capítulo 31: Solución de Problemas de Crypto-Policy
  • Capítulo 32: Análisis de Informes SOS
  • Capítulo 33: Procedimientos de Emergencia

Referencia Rápida

┌───────────────────────────────────────────────────────────────────┐
│ MÉTODO DE SOLUCIÓN DE PROBLEMAS DE 7 PASOS                        │
├───────────────────────────────────────────────────────────────────┤
│ 1. Identificar: Versión RHEL, OpenSSL, crypto-policy              │
│ 2. Verificar: Expiración, hostname, coincidencia clave, algoritmo │
│ 3. Confianza: Validación CA, cadena, intermedios                  │
│ 4. Config: Archivos servicio, rutas, permisos                     │
│ 5. Sistema: Crypto-policy, FIPS, SELinux, firewall                │
│ 6. Probar: Conexiones en vivo, curl, openssl s_client             │
│ 7. Logs: Logs servicio, journal, auditoría SELinux                │
└───────────────────────────────────────────────────────────────────┘

🧪 Laboratorio Práctico

Lab 15: Escenarios de Solución de Problemas

Practicar el diagnóstico y la corrección de un problema de certificado expirado (un escenario implementado)

  • 📁 Ubicación: labs/es_ES/15-troubleshooting-scenarios/
  • ⏱️ Tiempo: 15-20 minutos
  • 🎯 Nivel: Avanzado

Navegación del Capítulo

Capítulo 28: Errores Comunes de Certificados en RHEL

Aprende del Dolor de Otros: Este capítulo cataloga los errores de certificados más comunes en RHEL, organizados por tipo y versión. ¡Cuando encuentres un error, busca aquí primero!


28.1 Usar Este Capítulo

Cómo usar esta guía de solución de problemas:

  1. ¿Ves un error? Busca en este capítulo el mensaje de error
  2. ¿El servicio no inicia? Verifica Sección 28.3 (Errores de Configuración)
  3. ¿La conexión falla? Verifica Sección 28.4 (Errores de Validación)
  4. ¿Después de actualización RHEL? Verifica Sección 28.7 (Específico por Versión)
  5. ¿No estás seguro? Usa la metodología del Capítulo 27

28.2 Errores Más Comunes (Top 10)

Tabla de Referencia Rápida

#ErrorCausa ComúnSolución Rápida
1Certificado expiradoOlvidó renovarRenovar certificado
2unable to get local issuerFalta CA en almacén confianzaAgregar CA a /etc/pki/ca-trust/source/anchors/
3certificate verify failedCadena incompletaInstalar certs intermedios
4Permission deniedPermisos de archivo incorrectoschmod 600 en archivo de clave
5hostname does not matchDesajuste CN/SANReemitir con SANs correctos
6no shared cipherIncompatibilidad de cifradoVerificar crypto-policy (RHEL 8+)
7ca md too weakFirma SHA-1 (RHEL 9+)Reemitir con SHA-256+
8wrong version numberDesajuste versión TLSVerificar soporte TLS del cliente
9CA_UNREACHABLEcertmonger no puede alcanzar IPAVerificar conectividad IPA
10SELinux denying accessContexto SELinux incorrectorestorecon en archivos cert

28.3 Errores de Configuración

Error: “SSLCertificateFile: file does not exist or is empty”

Servicios: Apache

Síntoma:

AH00526: Syntax error on line 100 of /etc/httpd/conf.d/ssl.conf:
SSLCertificateFile: file '/etc/pki/tls/certs/server.crt' does not exist or is empty

Diagnóstico:

ls -l /etc/pki/tls/certs/server.crt
# ls: cannot access '/etc/pki/tls/certs/server.crt': No such file or directory

Soluciones:

# Solución 1: Corregir ruta en configuración
sudo vi /etc/httpd/conf.d/ssl.conf
# Corregir la ruta SSLCertificateFile

# Solución 2: Instalar certificado en ubicación esperada
sudo cp server.crt /etc/pki/tls/certs/

# Solución 3: Restaurar desde respaldo
sudo cp /var/backups/certificates/latest/server.crt /etc/pki/tls/certs/

Error: “Private key does not match this certificate”

Servicios: Apache, NGINX, Postfix

Síntoma:

SSL Library Error: error:0B080074:x509 certificate routines:
X509_check_private_key:key values mismatch

Diagnóstico:

# Verificar si cert y clave coinciden
CERT_MOD=$(openssl x509 -noout -modulus -in /etc/pki/tls/certs/server.crt | openssl md5)
KEY_MOD=$(openssl rsa -noout -modulus -in /etc/pki/tls/private/server.key | openssl md5)

echo "Cert: $CERT_MOD"
echo "Key:  $KEY_MOD"
# Si diferentes → ¡desajuste!

Causa: El certificado fue emitido para una clave privada diferente

Solución:

# Regenerar CSR con la clave CORRECTA
openssl req -new -key /etc/pki/tls/private/server.key -out server.csr \
  -subj "/CN=server.example.com"

# Enviar CSR a CA, obtener nuevo certificado
# Instalar nuevo certificado

Error: “Permission denied” en Clave Privada

Servicios: Todos

Síntoma:

Permission denied: Can't open PEM file '/etc/pki/tls/private/server.key'

Diagnóstico:

ls -l /etc/pki/tls/private/server.key
# -rw-r--r--. 1 root root  ← ¡Muy permisivo!

# Verificar si usuario del servicio puede leerlo
sudo -u apache cat /etc/pki/tls/private/server.key >/dev/null
# Permission denied

Solución:

# Establecer permisos correctos
sudo chmod 600 /etc/pki/tls/private/server.key
sudo chown apache:apache /etc/pki/tls/private/server.key

# Para servicios que necesitan ownership específico:
# OpenLDAP:
sudo chown ldap:ldap /etc/openldap/certs/ldap.key

# PostgreSQL:
sudo chown postgres:postgres /var/lib/pgsql/data/server.key

# MySQL:
sudo chown mysql:mysql /etc/mysql/certs/server.key

28.4 Errores de Validación

Error: “certificate verify failed”

Servicios: Todos

Error Completo:

SSL_connect: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed

Causas Comunes:

Causa 1: Certificado autofirmado no confiable

# Diagnóstico
openssl verify /etc/pki/tls/certs/server.crt
# error 18: self signed certificate

# Solución: Agregar al almacén de confianza
sudo cp server.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

Causa 2: Falta certificado CA

# Diagnóstico
openssl verify /etc/pki/tls/certs/server.crt
# error 20: unable to get local issuer certificate

# Solución: Agregar certificado CA
sudo cp ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

Causa 3: Falta certificado intermedio

# Diagnóstico
openssl s_client -connect server.example.com:443 -showcerts
# Verify return code: 21 (unable to verify the first certificate)

# Solución: Incluir intermedio en archivo cert
cat server.crt intermediate.crt > /etc/pki/tls/certs/server-chain.crt
# Actualizar configuración de servicio para usar server-chain.crt

Error: “certificate has expired”

Servicios: Todos

Síntoma:

SSL_connect: error:14090086:SSL routines:ssl3_get_server_certificate:certificate has expired

Diagnóstico:

# Verificar expiración
openssl x509 -in /etc/pki/tls/certs/server.crt -noout -dates
# notAfter=Jan 15 23:59:59 2024 GMT  ← ¡En el pasado!

Soluciones:

# Solución 1: Si rastreo con certmonger
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/server.crt

# Solución 2: Renovación manual
# Generar nuevo CSR, enviar a CA, instalar nuevo cert

# Solución 3: Emergencia - autofirmado temporal
sudo /usr/local/bin/emergency-self-signed-cert.sh $(hostname -f)
# Ver Capítulo 33 para procedimientos de emergencia

Error: “hostname (or IP address) does not match certificate”

Servicios: Todos (especialmente navegadores)

Error Completo:

SSL: certificate subject name 'server.example.com' does not match target host name 'www.example.com'

Diagnóstico:

# Verificar CN y SANs del certificado
openssl x509 -in /etc/pki/tls/certs/server.crt -noout -subject -ext subjectAltName

# Salida:
# subject=CN=server.example.com
# X509v3 Subject Alternative Name:
#     DNS:server.example.com
#
# Problema: Accediendo www.example.com pero cert solo tiene server.example.com

Solución:

# Reemitir certificado con SANs correctos
openssl req -new -key server.key -out server.csr \
  -subj "/CN=www.example.com" \
  -addext "subjectAltName=DNS:www.example.com,DNS:server.example.com,DNS:example.com"

# O usar comodín: *.example.com

28.5 Errores de Cadena de Confianza

Error: “unable to get local issuer certificate”

Código de Error: 20

Síntoma:

openssl verify /etc/pki/tls/certs/server.crt
# error 20 at 0 depth lookup: unable to get local issuer certificate

Causa: La CA que firmó el certificado no está en el almacén de confianza del sistema

Solución:

# Obtener certificado CA (de CA o extraer de cadena)
# Agregar al almacén de confianza
sudo cp issuing-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

# Verificar
openssl verify /etc/pki/tls/certs/server.crt
# /etc/pki/tls/certs/server.crt: OK

Error: “unable to verify the first certificate”

Código de Error: 21

Síntoma:

openssl s_client -connect server.example.com:443
# Verify return code: 21 (unable to verify the first certificate)

Causa: El servidor envía certificado sin intermedio(s)

Diagnóstico:

# Contar certificados en cadena
openssl s_client -connect server.example.com:443 -showcerts 2>&1 | \
  grep -c "BEGIN CERTIFICATE"
# Si muestra 1: Solo cert servidor (¡falta intermedio!)
# Debería mostrar 2+: Servidor + intermedio(s)

Solución:

# Crear paquete de certificado con intermedio
cat server.crt intermediate.crt > /etc/pki/tls/certs/server-bundle.crt

# Actualizar configuración de servicio
# Apache:
SSLCertificateFile /etc/pki/tls/certs/server-bundle.crt

# O usar SSLCertificateChainFile (Apache):
SSLCertificateChainFile /etc/pki/tls/certs/intermediate.crt

# NGINX:
ssl_certificate /etc/pki/tls/certs/server-bundle.crt;

# Recargar servicio

28.6 Errores de Crypto-Policy (RHEL 8/9/10)

Error: “no shared cipher”

Servicios: Todos (RHEL 8/9/10)

Síntoma:

SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

Diagnóstico:

# Verificar política actual
update-crypto-policies --show
# DEFAULT

# Probar conexión mostrando cifrados
openssl s_client -connect server:443 -cipher 'ALL'

# Verificar qué cifrados están disponibles bajo política actual
openssl ciphers -v | head -20

Causas Comunes y Soluciones:

Causa 1: Cliente muy antiguo (necesita TLS 1.0)

# Prueba temporal con LEGACY
sudo update-crypto-policies --set LEGACY
sudo systemctl restart httpd

# Si funciona → problema de compatibilidad de cliente
# Solución apropiada: Actualizar cliente o crear módulo de política personalizado

Causa 2: Crypto-policy del servidor muy estricta

# Si usas política FUTURE con clientes antiguos
update-crypto-policies --show
# FUTURE

# Temporal: Usar DEFAULT
sudo update-crypto-policies --set DEFAULT
sudo systemctl restart services

Error: “SSL routines:tls_post_process_client_hello:no shared cipher”

Servicios: Todos (RHEL 9+)

Síntoma: El cliente no puede negociar cifrado con el servidor

Solución:

# RHEL 9: Verificar si cliente usa cifrados muy antiguos
# Puede necesitar política LEGACY temporalmente

# Verificar configuración del servidor para sobrescrituras
grep -r "SSLCipherSuite\|ssl_ciphers" /etc/httpd/ /etc/nginx/

# Si se encuentran cifrados codificados, eliminarlos
# Dejar que crypto-policy lo maneje

28.7 Errores Específicos por Versión RHEL

Errores Específicos RHEL 7

Error: “dh key too small”

SSL routines:ssl3_check_cert_and_algorithm:dh key too small

Causa: Parámetros DH predeterminados muy pequeños para clientes modernos

Solución:

# Generar parámetros DH más fuertes
openssl dhparam -out /etc/pki/tls/dhparams.pem 2048

# Apache: Agregar a ssl.conf
SSLOpenSSLConfCmd DHParameters "/etc/pki/tls/dhparams.pem"

# NGINX: Agregar a config
ssl_dhparam /etc/pki/tls/dhparams.pem;

Errores Específicos RHEL 8/9/10

Error: “ca md too weak” (RHEL 9+)

error 3 at 0 depth lookup: CA md too weak

Causa: El certificado tiene firma SHA-1 (bloqueada en RHEL 9+)

Diagnóstico:

openssl x509 -in server.crt -noout -text | grep "Signature Algorithm"
# Signature Algorithm: sha1WithRSAEncryption  ← ¡Problema!

Solución:

# Reemitir certificado con SHA-256 o mejor
# No hay solución alternativa - SHA-1 está bloqueado por seguridad

# Solicitar nuevo certificado
openssl req -new -key server.key -out server.csr -sha256 \
  -subj "/CN=server.example.com"

Error: “Provider ‘legacy’ could not be loaded” (RHEL 9+)

openssl: error while loading shared libraries: Provider 'legacy' could not be loaded

Causa: Intentando usar algoritmo legacy sin proveedor

Solución:

# Usar proveedor legacy explícitamente
openssl md5 -provider legacy file.txt

# O actualizar para usar algoritmo moderno
openssl sha256 file.txt

28.8 Errores SELinux

Error: SELinux impide el acceso al certificado

Síntoma:

audit: type=1400 audit(timestamp): avc: denied { read } for pid=1234 comm="httpd"
name="server.key" dev="sda1" ino=12345 scontext=system_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0

Diagnóstico:

# Verificar denegaciones AVC
sudo ausearch -m avc -ts recent | grep cert

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

Solución:

# Corregir contexto SELinux
sudo restorecon -Rv /etc/pki/tls/

# Verificar
ls -Z /etc/pki/tls/certs/server.crt
# system_u:object_r:cert_t:s0  ← Correcto

# Si aún hay problemas, verificar si SELinux está bloqueando
sudo ausearch -m avc -ts recent

# Generar política si es necesario
sudo ausearch -m avc -ts recent | audit2allow -M mycert
sudo semodule -i mycert.pp

28.9 Errores de certmonger

Error: CA_UNREACHABLE

Síntoma:

sudo getcert list
# status: CA_UNREACHABLE

Diagnóstico:

# Verificar conectividad IPA
ipa ping

# Verificar ticket Kerberos
klist

# Verificar servicios IPA
ssh ipa-server "sudo ipactl status"

Soluciones:

# Solución 1: Renovar ticket Kerberos
kinit -k host/$(hostname -f)@REALM

# Solución 2: Verificar conectividad de red
ping ipa.example.com

# Solución 3: Reiniciar certmonger
sudo systemctl restart certmonger

# Solución 4: Reenviar solicitud
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/server.crt

Error: CA_REJECTED

Síntoma:

sudo getcert list
# status: CA_REJECTED
# ca-error: Server unwilling to issue certificate

Causas Comunes:

Causa 1: Principal de servicio no existe

# Verificar si principal existe
ipa service-show HTTP/$(hostname -f)

# Si no se encuentra, agregarlo
ipa service-add HTTP/$(hostname -f)

# Reenviar
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/server.crt

Causa 2: Host no inscrito a IPA

# Verificar inscripción
ipa host-show $(hostname -f)

# Si no inscrito
sudo ipa-client-install

28.10 Errores de Claves GPG/PGP Heredadas

Error: “skipped PGP-2 keys” al Importar

Herramienta: GnuPG (gpg)

Síntoma:

$ gpg --allow-old-cipher-algos --import keyfile.asc
gpg: Total number processed: 2
gpg:     skipped PGP-2 keys: 2

La clave es rechazada silenciosamente — incluso con --allow-old-cipher-algos.

Causa: El archivo de clave contiene claves OpenPGP versión 3 (era PGP 2.x). GnuPG moderno (2.2+) rechaza completamente la importación de paquetes de clave v3. Estas claves típicamente usan RSA con firmas MD5, ambos criptográficamente obsoletos.

Diagnóstico — Inspeccionar los paquetes de clave:

gpg --list-packets keyfile.asc

Salida de ejemplo:

# off=0 ctb=95 tag=5 hlen=3 plen=930
:key packet: [obsolete version 3]
# off=933 ctb=b4 tag=13 hlen=2 plen=27
:user ID packet: "User Name <user@example.org>"
# off=962 ctb=89 tag=2 hlen=3 plen=277
:signature packet: algo 1, keyid A1B2C3D4E5F60789
        version 3, created 1034280585, md5len 5, sigclass 0x10
        digest algo 1, begin of digest a1 26
        data: [2047 bits]

Los indicadores críticos son:

  • :key packet: [obsolete version 3] — formato v3, rechazado por GnuPG moderno
  • algo 1 — RSA (cifrar o firmar)
  • digest algo 1 — MD5 (criptográficamente roto)
  • version 3 en la firma — formato de firma antiguo
  • sigclass 0x10 — certificación genérica de un ID de usuario

Solución: No hay forma de “actualizar” una clave v3. Debe generar una clave moderna nueva y retirar la antigua:

# 1. Generar una clave moderna (Ed25519 + Curve25519)
gpg --full-generate-key
#    Elegir: (9) ECC (firmar y cifrar)
#    Curva:  ed25519 (firma), cv25519 (cifrado)

# 2. Verificar la nueva clave
gpg --list-keys --keyid-format long

# 3. Si aún controla la clave antigua, firmar cruzado para continuidad de confianza
gpg --default-key OLDKEYID --sign-key NEWKEYID

# 4. Generar un certificado de revocación para la clave antigua
gpg --output revoke-old.asc --gen-revoke OLDKEYID

# 5. Publicar la nueva clave
gpg --send-keys NEWKEYID

# 6. Revocar la clave antigua
gpg --import revoke-old.asc
gpg --send-keys OLDKEYID

Después de la migración, actualice todos los sistemas que hacen referencia a la clave antigua (CI/CD, firma de paquetes, cifrado de correo electrónico).


Entendiendo la Salida de gpg --list-packets

Al depurar problemas de claves GPG, gpg --list-packets muestra la estructura de paquetes OpenPGP en bruto. Aquí hay una referencia completa para interpretar la salida.

Campos del Encabezado de Paquete

Cada línea de paquete comienza con:

# off=0 ctb=95 tag=5 hlen=3 plen=930
CampoSignificado
offDesplazamiento en bytes en el archivo (posición de inicio de este paquete)
ctbCipher Type Byte (byte de encabezado en hex, codifica formato + tag)
tagTipo de paquete (decodificado — ver tabla abajo)
hlenLongitud del encabezado en bytes
plenLongitud del contenido en bytes

Tags de Paquete (tag=)

TagTipo de Paquete
1Clave de Sesión Cifrada con Clave Pública
2Firma
3Clave de Sesión Cifrada con Clave Simétrica
4Firma One-Pass
5Clave Pública
6Clave Secreta
7Subclave Secreta
8Datos Comprimidos
9Datos Cifrados Simétricamente
10Marcador
11Datos Literales
12Confianza
13ID de Usuario
14Subclave Pública
17Atributo de Usuario
18Datos Cifrados + Protección de Integridad
19Código de Detección de Modificación

IDs de Algoritmo de Clave Pública (algo)

IDAlgoritmo
1RSA (cifrar o firmar)
2RSA (solo cifrar)
3RSA (solo firmar)
16Elgamal (solo cifrar)
17DSA
18ECDH
19ECDSA
21Diffie-Hellman
22EdDSA (Ed25519, etc.)

IDs de Algoritmo de Digest (Hash) (digest algo)

IDAlgoritmoEstado
1MD5Roto — no usar
2SHA-1Obsoleto — bloqueado en RHEL 9+
3RIPEMD-160Heredado
8SHA-256Recomendado
9SHA-384Fuerte
10SHA-512Fuerte
11SHA-224Aceptable

Clases de Firma (sigclass)

CódigoSignificado
0x00Firma de documento binario
0x01Firma de texto canónico
0x02Firma independiente
0x10Certificación genérica de clave
0x11Certificación de persona
0x12Certificación casual
0x13Certificación positiva
0x18Vinculación de subclave
0x19Vinculación de clave primaria
0x1FFirma directa de clave
0x20Revocación de clave
0x28Revocación de subclave
0x30Revocación de certificación
0x40Marca de tiempo
0x50Confirmación de terceros

Versiones de Paquete de Clave

VersiónEraEstado
3PGP 2.x (1990s)Obsoleto — usa MD5 internamente, rechazado por GnuPG moderno
4OpenPGP RFC 4880 (2007)Estándar actual
5Borrador (crypto-refresh)Emergente

Campos del Paquete de Firma

Para una firma como:

:signature packet: algo 1, keyid A1B2C3D4E5F60789
        version 3, created 1034280585, md5len 5, sigclass 0x10
        digest algo 1, begin of digest a1 26
        data: [2047 bits]
CampoSignificado
algo 1Algoritmo de clave pública utilizado (RSA)
keyidIdentificador corto de la clave firmante
version 3Versión del formato de firma (v3 = heredado)
createdMarca de tiempo Unix de creación de firma
md5lenLongitud del prefijo MD5 (artefacto heredado v3)
sigclass 0x10Tipo de firma (certificación genérica de clave)
digest algo 1Algoritmo de hash (MD5)
begin of digestPrimeros 2 bytes del hash (para verificación rápida)
data: [2047 bits]Datos de firma RSA (~clave de 2048 bits)

28.11 Errores de Firma RPM Después de Actualización RHEL

Error: “Certificate invalid: policy violation — SHA1 is not considered secure”

Herramientas: RPM, DNF

Síntoma:

Tras actualizar a RHEL 9+ o RHEL 10, los comandos RPM muestran errores de verificación de firma para paquetes de terceros:

$ rpm -qa
error: Verifying a signature using certificate
  D4E7A923F10B82C6459831AE5F6C0D9BA47E31D2
  (Third-Party Vendor (Release signing) <security@vendor.example.com>):
  1. Certificate 5F6C0D9BA47E31D2 invalid: policy violation
      because: No binding signature at time 2024-08-12T10:44:42Z
      because: Policy rejected non-revocation signature
               (PositiveCertification) requiring second pre-image resistance
      because: SHA1 is not considered secure
  2. Certificate 5F6C0D9BA47E31D2 invalid: policy violation
      because: No binding signature at time 2026-04-16T19:46:38Z
      because: Policy rejected non-revocation signature
               (PositiveCertification) requiring second pre-image resistance
      because: SHA1 is not considered secure

Los comandos RPM siguen funcionando, pero generan salida de error excesiva por cada paquete firmado con la clave afectada.

Causa: Las claves GPG de firma de terceros que usan SHA-1 en sus firmas de vinculación (autocertificaciones) son rechazadas por las crypto-policies de RHEL 9+ (SHA-1 bloqueado por defecto) y RHEL 10 (soporte de SHA-1 eliminado por completo). Los paquetes instalados antes de la actualización conservan en la base de datos RPM sus firmas antiguas con SHA-1.

Diagnóstico:

# Listar todas las claves GPG importadas en la base de datos RPM
rpm -q gpg-pubkey --qf '%{NAME}-%{VERSION}-%{RELEASE}\t%{SUMMARY}\n'

Solución:

# 1. Eliminar la clave de firma antigua de terceros
#    El ID de certificado 5F6C0D9BA47E31D2 corresponde a la versión a47e31d2 en RPM
rpm -e --allmatches gpg-pubkey-a47e31d2-6142699d

# 2. Importar la clave actualizada del proveedor
rpm --import https://vendor.example.com/keys/signing.asc

# 3. Comprobar que los errores han desaparecido
rpm -qa > /dev/null

Correspondencia de ID de clave: El ID de certificado del error (p. ej., 5F6C0D9BA47E31D2) corresponde a la versión del gpg-pubkey de RPM en hexadecimal minúscula (a47e31d2). Si rpm -e indica «not installed», liste todas las claves con rpm -q gpg-pubkey --qf '...' para encontrar la cadena exacta versión-release.


28.12 Corrupción de Base de Datos RPM Después de Actualización RHEL

Error: “Malformed MPI” / “non-conformant OpenPGP implementation”

Herramientas: RPM

Síntoma:

Tras actualizar a RHEL 9+ o RHEL 10, RPM informa de una firma corrupta en cada consulta a la base de datos:

error: rpmdbNextIterator: skipping h#       9
Header RSA signature: BAD (header tag 268: invalid OpenPGP signature:
  Parsing an OpenPGP packet:
  Failed to parse Signature Packet
      because: Signature appears to be created by a non-conformant
               OpenPGP implementation, see
               <https://github.com/rpm-software-management/rpm/issues/2351>.
      because: Malformed MPI: leading bit is not set: expected bit 8 to
               be set in   110010 (32))
Header SHA256 digest: OK
Header SHA1 digest: OK

Causa: Algunos paquetes de terceros se firmaron con implementaciones OpenPGP no estándar que producen valores MPI (entero de precisión múltiple) mal formados en las firmas RSA. El RPM más antiguo de RHEL 7/8 toleraba estos casos, pero el analizador basado en Sequoia-PGP de RHEL 9+/10 los rechaza.

Diagnóstico:

# Identificar el paquete defectuoso usando el número de cabecera del error (h# 9)
rpm -q --nosignature --querybynumber 9

Solución:

# 1. Hacer copia de seguridad de la base de datos RPM
tar zcvf /var/preserve/rpmdb-$(date +"%d%m%Y").tar.gz /usr/lib/sysimage/rpm/
# Nota: en RHEL 8/9, la base de datos está en /var/lib/rpm/

# 2. Identificar el paquete dañado
rpm -q --nosignature --querybynumber <NUMBER_FROM_ERROR>

# 3. Eliminar el paquete con la firma rota
rpm -e --nosignature --nodigest <package-name>
# Si la eliminación falla, eliminar solo la entrada de la base de datos:
rpm -e --justdb --nodeps <package-name>

# 4. Reconstruir la base de datos RPM
rpm --rebuilddb

# 5. Comprobar que los errores se han resuelto
rpm -qa > /dev/null

# 6. Reinstalar desde un repositorio actualizado
dnf install <package-name>

Nota: En RHEL 10, la base de datos RPM está en /usr/lib/sysimage/rpm/. En RHEL 8/9, está en /var/lib/rpm/.

Referencia: El issue #2351 de RPM documenta el análisis MPI más estricto introducido con el backend Sequoia-PGP.


Escenario combinado: ambos errores tras la actualización

Al actualizar de RHEL 7/8 a RHEL 9+/10, ambos errores suelen aparecer a la vez. Resuélvalos en este orden:

  1. Eliminar las claves de firma antiguas con SHA-1 e importar las claves actualizadas del proveedor
  2. Reconstruir la base de datos RPM con rpm --rebuilddb
  3. Si persisten errores de MPI mal formado, identifique los paquetes afectados por el número de cabecera (rpm -q --nosignature --querybynumber <N>), elimínelos y reinstálelos desde repositorios actualizados

28.13 Errores de Navegador/Cliente

Error: “NET::ERR_CERT_COMMON_NAME_INVALID”

Síntoma: El navegador muestra “Tu conexión no es privada”

Causa: El hostname no coincide con CN o SANs del certificado

Diagnóstico:

# Verificar qué estás accediendo
echo "Accediendo: www.example.com"

# Verificar SANs del certificado
openssl s_client -connect www.example.com:443 2>&1 | \
  openssl x509 -noout -ext subjectAltName
# X509v3 Subject Alternative Name:
#     DNS:server.example.com  ← ¡No incluye www.example.com!

Solución:

# Reemitir certificado con SANs correctos
openssl req -new -key server.key -out server.csr \
  -subj "/CN=www.example.com" \
  -addext "subjectAltName=DNS:www.example.com,DNS:server.example.com,DNS:example.com"

Error: “NET::ERR_CERT_AUTHORITY_INVALID”

Síntoma: El navegador no confía en el certificado

Causa: La CA no está en el almacén de confianza del navegador (autofirmada o CA interna)

Para CA Interna:

# Distribuir certificado CA a clientes
# Los usuarios necesitan instalar CA en su navegador

# O agregar a confianza del sistema (clientes Linux)
sudo cp corporate-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

Para Autofirmado (Solo Pruebas):

# ¡No usar autofirmado en producción!
# Obtener certificado apropiado de CA

28.14 Errores de Firewall/Red

Error: Connection Timeout

Síntoma: No se puede conectar al puerto HTTPS

Diagnóstico:

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

# Verificar firewall
sudo firewall-cmd --list-services | grep https

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

# Probar remotamente
telnet server.example.com 443

Solución:

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

# Verificar
sudo firewall-cmd --list-all

28.15 Diccionario de Mensajes de Error

Tabla de Búsqueda Rápida

Mensaje de ErrorCódigo ErrorCausaCapítulo
“certificate has expired”-Cert expirado28.4
“unable to get local issuer”20Falta CA28.4
“unable to verify first cert”21Falta intermedio28.4
“self signed certificate”18Autofirmado no confiable28.4
“certificate verify failed”-Validación general28.4
“ca md too weak”3Firma SHA-128.7
“no shared cipher”-Desajuste de cifrado28.6
“wrong version number”-Desajuste versión TLS28.6
“Permission denied”-Permisos de archivo28.3
“key values mismatch”-Cert/clave no emparejan28.3
“hostname does not match”-Desajuste CN/SAN28.4
“CA_UNREACHABLE”-certmonger no alcanza IPA28.9
“CA_REJECTED”-IPA rechazó solicitud28.9
“skipped PGP-2 keys”-Importación GPG clave v3 rechazada28.10
“SHA1 is not considered secure”-Clave GPG de terceros usa SHA-128.11
“Malformed MPI”-Firma OpenPGP no conforme28.12

28.16 Comandos de Diagnóstico Rápido

Comandos Universales de Solución de Problemas

#============================================#
# EJECUTAR ESTOS PARA CUALQUIER ERROR DE CERTIFICADO
#============================================#

# 1. Verificar versión RHEL
cat /etc/redhat-release

# 2. Verificar archivo de certificado
openssl x509 -in /path/to/cert.crt -noout -text

# 3. Verificar expiración
openssl x509 -in /path/to/cert.crt -noout -dates

# 4. Verificar confianza
openssl verify /path/to/cert.crt

# 5. Verificar permisos
ls -lZ /path/to/cert.crt
ls -lZ /path/to/key.key

# 6. Verificar coincidencia cert/clave
openssl x509 -noout -modulus -in cert.crt | openssl md5
openssl rsa -noout -modulus -in key.key | openssl md5

# 7. Probar conexión
openssl s_client -connect server:443

# 8. Verificar logs
sudo journalctl -xe | grep -i cert
sudo tail -f /var/log/httpd/ssl_error_log

# 9. Verificar SELinux
sudo ausearch -m avc -ts recent | grep cert

# 10. Verificar crypto-policy (RHEL 8+)
update-crypto-policies --show

28.17 Diagrama de Flujo de Resolución de Errores

Ocurrió Error de Certificado
    │
    ├─ ¿El servicio no inicia?
    │   ├─ Verificar sintaxis de config
    │   ├─ Verificar rutas de archivo
    │   ├─ Verificar permisos (600 para claves)
    │   └─ Verificar contexto SELinux
    │
    ├─ ¿La conexión falla?
    │   ├─ Verificar firewall
    │   ├─ Verificar servicio escuchando
    │   ├─ Probar con openssl s_client
    │   └─ Verificar enrutamiento de red
    │
    ├─ ¿Error de validación de certificado?
    │   ├─ Verificar expiración
    │   ├─ Verificar cadena de confianza
    │   ├─ Verificar coincidencia de hostname
    │   └─ Verificar certs intermedios
    │
    ├─ ¿Error de cifrado/protocolo?
    │   ├─ Verificar crypto-policy (RHEL 8+)
    │   ├─ Verificar versiones TLS
    │   └─ Probar con versión TLS diferente
    │
    └─ ¿Error de certmonger?
        ├─ CA_UNREACHABLE → Verificar conectividad IPA
        ├─ CA_REJECTED → Verificar que principal existe
        └─ Ver Capítulo 30

28.18 Conclusiones Clave

  1. La mayoría de errores son predecibles - Patrones comunes
  2. Siempre verificar expiración primero - Causa #1 de problemas
  3. Los permisos importan - 600 para claves, 644 para certs
  4. Cadena de confianza crítica - Falta CA o intermedio
  5. La versión RHEL importa - Errores diferentes por versión
  6. crypto-policies afectan todo (RHEL 8+)
  7. SELinux puede bloquear - Verificar contextos
  8. Referencia Capítulo 27 para enfoque sistemático

Tarjeta de Referencia Rápida

┌─────────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA ERRORES COMUNES DE CERTIFICADOS               │
├─────────────────────────────────────────────────────────────────┤
│ Expirado:          Ver: openssl x509 -noout -dates              │
│                    Solución: Renovar certificado                │
│                                                                 │
│ Confianza:         Ver: openssl verify cert.crt                 │
│                    Solución: Agregar CA a /etc/pki/ca-trust/... │
│                                                                 │
│ Hostname:          Ver: openssl x509 -noout -ext subjectAltName │
│                    Solución: Reemitir con SANs correctos        │
│                                                                 │
│ Permisos:          Ver: ls -lZ cert.crt key.key                 │
│                    Solución: chmod 600 key.key                  │
│                                                                 │
│ Coincidencia:      Ver: Comparar MD5 de módulo                  │
│                    Solución: Regenerar CSR con clave correcta   │
│                                                                 │
│ No shared cipher:  Ver: update-crypto-policies --show           │
│                    Solución: Actualizar política o cliente      │
│                                                                 │
│ SELinux:           Ver: ausearch -m avc | grep cert             │
│                    Solución: restorecon -Rv /etc/pki/tls/       │
└─────────────────────────────────────────────────────────────────┘

Siempre comenzar con: Capítulo 27 (metodología de 7 pasos)

Navegación del Capítulo

Capítulo 29: Solución de Problemas Específica por Servicio

Servicio por Servicio: Cada servicio RHEL tiene requisitos únicos de certificados y modos de fallo. Este capítulo proporciona solución de problemas dirigida para cada servicio principal.


29.1 Solución de Problemas de Apache httpd

Apache No Inicia

Pasos de Diagnóstico:

#============================================#
# SOLUCIÓN DE PROBLEMAS CERTIFICADOS APACHE
#============================================#

# Paso 1: Verificar estado de Apache
systemctl status httpd
sudo journalctl -xe -u httpd

# Paso 2: Probar configuración
sudo apachectl configtest
# Buscar errores relacionados con SSL

# Paso 3: Verificar si mod_ssl está cargado
sudo httpd -M | grep ssl
# Debería mostrar: ssl_module (shared)

# Paso 4: Verificar archivos de certificado
ls -l /etc/pki/tls/certs/*.crt
ls -l /etc/pki/tls/private/*.key

# Paso 5: Verificar permisos
ls -l /etc/pki/tls/private/server.key
# Debería ser: -rw------- (600)

# Paso 6: Verificar coincidencia cert/clave
CERT_MOD=$(openssl x509 -noout -modulus -in /etc/pki/tls/certs/server.crt | openssl md5)
KEY_MOD=$(openssl rsa -noout -modulus -in /etc/pki/tls/private/server.key | openssl md5)
[ "$CERT_MOD" = "$KEY_MOD" ] && echo "✅ Coincide" || echo "❌ ¡Desajuste!"

# Paso 7: Verificar SELinux
sudo ausearch -m avc -ts recent | grep httpd | grep cert

Errores SSL Comunes de Apache

ErrorCausaSolución
“SSLCertificateFile: file does not exist”Ruta incorrectaCorregir ruta en ssl.conf
“key values mismatch”Cert/clave no emparejanRegenerar con clave correcta
“unable to load certificate”Problema formato archivoAsegurar formato PEM
“Syntax error” en ssl.confError de tipeo en configEjecutar apachectl configtest
“unable to verify certificate”Problema de cadenaAgregar cert intermedio

29.2 Solución de Problemas de NGINX

Problemas SSL/TLS de NGINX

Pasos de Diagnóstico:

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

# Paso 1: Probar configuración
sudo nginx -t

# Paso 2: Mostrar configuración completa
sudo nginx -T | grep ssl_certificate

# Paso 3: Verificar archivos de certificado
ls -l /etc/pki/tls/certs/nginx.crt
ls -l /etc/pki/tls/private/nginx.key

# Paso 4: Verificar par cert/clave
openssl x509 -noout -modulus -in /etc/pki/tls/certs/nginx.crt | openssl md5
openssl rsa -noout -modulus -in /etc/pki/tls/private/nginx.key | openssl md5

# Paso 5: Verificar log de errores de NGINX
sudo tail -50 /var/log/nginx/error.log | grep -i ssl

# Paso 6: Verificar si NGINX está ejecutándose
systemctl status nginx
ss -tlnp | grep nginx

Errores SSL Comunes de NGINX

ErrorCausaSolución
“SSL: error:0200100D”Permission denied en clavechmod 600 en clave
“no "ssl" is defined”Falta ssl en listenAgregar listen 443 ssl;
“cannot load certificate”Archivo no encontradoVerificar ruta
“PEM_read_bio:no start line”Formato incorrectoAsegurar formato PEM
“nginx: [emerg] bind() failed”Puerto en usoVerificar qué está en puerto 443

29.3 Solución de Problemas de Postfix

Problemas TLS de Postfix

Pasos de Diagnóstico:

#============================================#
# SOLUCIÓN DE PROBLEMAS TLS POSTFIX
#============================================#

# Paso 1: Verificar configuración TLS de Postfix
sudo postconf | grep -i tls

# Paso 2: Ver ajustes específicos
sudo postconf smtpd_tls_cert_file smtpd_tls_key_file

# Paso 3: Probar configuración
sudo postfix check

# Paso 4: Verificar archivos de certificado
ls -l $(sudo postconf -h smtpd_tls_cert_file)
ls -l $(sudo postconf -h smtpd_tls_key_file)

# Paso 5: Probar SMTP TLS
openssl s_client -starttls smtp -connect localhost:25

# Paso 6: Verificar logs de correo
sudo tail -f /var/log/maillog | grep -i tls

# Paso 7: Verificar si se ofrece STARTTLS
telnet localhost 25
# Escribir: EHLO test
# Debería mostrar: 250-STARTTLS

Errores TLS Comunes de Postfix

ErrorCausaSolución
“SSL_accept error”Problema cert/claveVerificar par cert/clave
“TLS is required but not available”TLS no habilitadoEstablecer security_level = may
“no shared cipher”Desajuste de cifradoVerificar crypto-policy
“certificate verify failed”Problema de cadenaInstalar intermedio
“Permission denied”Permisos de clavechmod 600 en clave

29.4 Solución de Problemas de OpenLDAP

Problemas LDAPS

Pasos de Diagnóstico:

#============================================#
# SOLUCIÓN DE PROBLEMAS TLS OPENLDAP
#============================================#

# Paso 1: Verificar si slapd escucha en 636
ss -tlnp | grep 636

# Paso 2: Verificar configuración TLS
sudo slapcat -b "cn=config" | grep -i tls

# Paso 3: Verificar archivos de certificado
ls -l /etc/openldap/certs/ldap.{crt,key}

# Paso 4: Verificar ownership
# ¡CRÍTICO: Debe ser propiedad del usuario ldap!
ls -l /etc/openldap/certs/
# Debería mostrar: ldap:ldap

# Paso 5: Probar conexión LDAPS
openssl s_client -connect localhost:636

# Paso 6: Probar con ldapsearch
ldapsearch -H ldaps://localhost:636 -x -b "" -s base

# Paso 7: Verificar logs de slapd
sudo journalctl -u slapd | grep -i tls

Errores TLS Comunes de OpenLDAP

ErrorCausaSolución
“TLS: can’t accept”Clave no legiblechown ldap:ldap en clave
“TLS: hostname does not match”Desajuste CN/SANReemitir con hostname correcto
“certificate verify failed”CA no confiableAgregar CA al almacén de confianza
“Permission denied”Ownership incorrectochown ldap:ldap
“TLS engine not initialized”TLS no configuradoAgregar directivas TLS

29.5 Solución de Problemas de PostgreSQL

Problemas SSL de PostgreSQL

Pasos de Diagnóstico:

#============================================#
# SOLUCIÓN DE PROBLEMAS SSL POSTGRESQL
#============================================#

# Paso 1: Verificar si SSL está habilitado
sudo -u postgres psql -c "SHOW ssl;"

# Paso 2: Ver ajustes SSL
sudo -u postgres psql -c "SHOW ssl_cert_file; SHOW ssl_key_file;"

# Paso 3: Verificar archivos de certificado
ls -l /var/lib/pgsql/data/server.{crt,key}

# Paso 4: Verificar ownership
# Debe ser propiedad del usuario postgres
ls -l /var/lib/pgsql/data/server.key
# -rw------- postgres postgres

# Paso 5: Probar conexión SSL
psql "host=localhost sslmode=require"

# Paso 6: Verificar logs de PostgreSQL
sudo tail -f /var/lib/pgsql/data/log/postgresql-*.log | grep -i ssl

# Paso 7: Verificar permisos
sudo -u postgres stat /var/lib/pgsql/data/server.key

Errores SSL Comunes de PostgreSQL

ErrorCausaSolución
“could not load server certificate”Permission deniedchown postgres:postgres, chmod 600
“private key file has wrong permissions”Muy permisivochmod 600 en clave
“SSL connection has been closed unexpectedly”Problema de confianzaVerificar confianza CA del cliente
“SSL is not enabled”SSL off en configEstablecer ssl = on

29.6 Solución de Problemas de MySQL/MariaDB

Problemas SSL de Base de Datos

Pasos de Diagnóstico:

#============================================#
# SOLUCIÓN DE PROBLEMAS SSL MYSQL/MARIADB
#============================================#

# Paso 1: Verificar si SSL está disponible
mysql -u root -p -e "SHOW VARIABLES LIKE 'have_ssl';"
# Debería mostrar: YES

# Paso 2: Ver variables SSL
mysql -u root -p -e "SHOW VARIABLES LIKE '%ssl%';"

# Paso 3: Verificar archivos de certificado
ls -l /etc/mysql/certs/{ca,server}.{crt,key}

# Paso 4: Verificar ownership
# Debe ser legible por usuario mysql
ls -l /etc/mysql/certs/
# mysql:mysql

# Paso 5: Probar conexión SSL
mysql --ssl-mode=REQUIRED -h localhost -u root -p

# Paso 6: Verificar estado de conexión
mysql -u root -p -e "STATUS" | grep SSL

# Paso 7: Verificar log de errores
sudo tail -f /var/log/mariadb/mariadb.log | grep -i ssl

29.7 Problemas entre Servicios

El Certificado Funciona en Un Servicio, Falla en Otro

Escenario: El mismo certificado funciona en Apache pero falla en Postfix

Diagnóstico:

# Apache funciona
curl -v https://localhost/
# ✅ OK

# Postfix falla
openssl s_client -starttls smtp -connect localhost:25
# ❌ Error

# ¿Por qué? ¡Requisitos diferentes!

Causas Comunes:

Causa 1: Ownership de archivo

  • Apache: Se ejecuta como root (puede leer claves propiedad de root)
  • Postfix: Se ejecuta como postfix (necesita clave legible)
  • OpenLDAP: Se ejecuta como ldap (necesita clave propiedad de ldap)

Causa 2: Ubicaciones de archivo

  • Apache: /etc/pki/tls/
  • PostgreSQL: /var/lib/pgsql/data/
  • OpenLDAP: /etc/openldap/certs/

Causa 3: Requisitos de formato

  • La mayoría de servicios: Archivos cert y clave separados
  • HAProxy: Archivo PEM combinado
  • Cockpit: Cert+clave combinados

29.8 Kit de Herramientas de Solución de Problemas

Comandos de Prueba Específicos por Servicio

#============================================#
# PROBAR CADA SERVICIO
#============================================#

# Apache HTTPS
curl -v https://localhost/
openssl s_client -connect localhost:443

# NGINX HTTPS
curl -v https://localhost:8443/  # Si puerto personalizado
openssl s_client -connect localhost:443

# Postfix SMTP
openssl s_client -starttls smtp -connect localhost:25
openssl s_client -connect localhost:465  # SMTPS

# Dovecot IMAP
openssl s_client -connect localhost:993  # IMAPS
openssl s_client -connect localhost:995  # POP3S

# OpenLDAP
openssl s_client -connect localhost:636  # LDAPS
ldapsearch -H ldaps://localhost:636 -x -b ""

# PostgreSQL
psql "host=localhost sslmode=require"

# MySQL/MariaDB
mysql --ssl-mode=REQUIRED -h localhost -u root -p

# Cockpit
openssl s_client -connect localhost:9090

29.9 Conclusiones Clave

  1. Cada servicio tiene requisitos únicos - Ownership, ubicación, formato
  2. Siempre verificar logs específicos del servicio primero
  3. Probar con comandos específicos del servicio (no solo openssl)
  4. Permisos críticos - Usuarios diferentes para servicios diferentes
  5. Las ubicaciones de archivo importan - Rutas dependientes del servicio
  6. Sintaxis de configuración varía por servicio
  7. Referencia capítulos de servicio (Cap 14-21) para config detallada

Tarjeta de Referencia Rápida

┌─────────────────────────────────────────────────────────────┐
│ SOLUCIÓN DE PROBLEMAS ESPECÍFICO POR SERVICIO               │
├─────────────────────────────────────────────────────────────┤
│ Apache:      apachectl configtest                           │
│              tail -f /var/log/httpd/ssl_error_log           │
│                                                             │
│ NGINX:       nginx -t                                       │
│              tail -f /var/log/nginx/error.log               │
│                                                             │
│ Postfix:     postfix check                                  │
│              tail -f /var/log/maillog | grep TLS            │
│                                                             │
│ OpenLDAP:    slapcat -b "cn=config" | grep TLS              │
│              journalctl -u slapd | grep TLS                 │
│              chown ldap:ldap (¡CRÍTICO!)                    │
│                                                             │
│ PostgreSQL:  psql -c "SHOW ssl;"                            │
│              chown postgres:postgres (¡CRÍTICO!)            │
│                                                             │
│ MySQL:       mysql -e "SHOW VARIABLES LIKE '%ssl%';"        │
│              chown mysql:mysql (¡CRÍTICO!)                  │
└─────────────────────────────────────────────────────────────┘

⚠️ ¡El ownership de archivo es específico del servicio!
✅ Siempre verificar logs para cada servicio

Navegación del Capítulo

Capítulo 30: Solución de Problemas de certmonger

Problemas de Automatización: certmonger es la herramienta de automatización de certificados de RHEL. Cuando falla, los certificados no se renuevan. Este capítulo te enseña a diagnosticar y solucionar problemas de certmonger rápidamente.


30.1 Valores de Estado de certmonger

Entender Mensajes de Estado

EstadoSignificadoAcción Requerida
MONITORING✅ Todo bien - cert emitido, rastreando expiraciónNinguna
SUBMITTING🔄 Solicitando cert de CAEsperar (usualmente segundos)
CA_UNREACHABLE❌ No se puede contactar servidor CACorregir conectividad
CA_REJECTED❌ CA rechazó solicitudCorregir principal/permisos
NEED_KEY_GEN_PIN⏸️ Esperando PIN (HSM)Proporcionar PIN
NEED_GUIDANCE⚠️ Necesita intervención manualVerificar detalles de solicitud
PRE_SAVE_COMMAND🔄 Ejecutando script pre-guardadoEsperar
POST_SAVE_COMMAND🔄 Ejecutando script post-guardadoEsperar
NEWLY_ADDED🆕 Recién agregado, aún no procesadoEsperar

30.2 Solución de Problemas de CA_UNREACHABLE

¡Problema Más Común de certmonger!

Síntoma:

sudo getcert list
# status: CA_UNREACHABLE

Pasos de Diagnóstico

#============================================#
# DIAGNOSTICAR CA_UNREACHABLE
#============================================#

# Paso 1: ¿Qué CA estamos intentando alcanzar?
sudo getcert list -v | grep "CA:"
# CA: IPA

# Paso 2: ¿Podemos alcanzar IPA?
ipa ping
# Pong!  ← Bueno
# ipa: ERROR: cannot connect to 'https://ipa.example.com/ipa/xml'  ← ¡Malo!

# Paso 3: Verificar ticket Kerberos
klist
# Ticket cache: FILE:/tmp/krb5cc_0
# Valid starting     Expires            Service principal
# ...

# Paso 4: Verificar si ticket expiró
klist | grep "host/"
# Si no hay ticket de host o expiró → ¡Problema!

# Paso 5: Verificar estado del servidor IPA
ssh ipa.example.com "sudo ipactl status"

# Paso 6: Verificar red
ping ipa.example.com
curl -k https://ipa.example.com/ipa/config/ca.crt

# Paso 7: Verificar DNS
nslookup ipa.example.com

Soluciones para CA_UNREACHABLE

Solución 1: Renovar Ticket Kerberos

# Obtener nuevo ticket de host
sudo kinit -k host/$(hostname -f)@REALM

# Verificar
klist

# Reintentar solicitud de cert
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt

Solución 2: Verificar Servidor IPA

# En servidor IPA
sudo ipactl status

# Si servicios caídos
sudo ipactl restart

# Verificar servicio específico
sudo systemctl status pki-tomcatd@pki-tomcat  # Servicio CA

Solución 3: Red/Firewall

# Probar conectividad IPA
curl -vk https://ipa.example.com/ipa/xml

# Verificar firewall en servidor IPA
ssh ipa.example.com "sudo firewall-cmd --list-services | grep https"

# Verificar rutas
traceroute ipa.example.com

Solución 4: Reiniciar certmonger

sudo systemctl restart certmonger

# Esperar un momento
sleep 10

# Verificar estado
sudo getcert list

30.3 Solución de Problemas de CA_REJECTED

Cuando CA Rechaza la Solicitud

Síntoma:

sudo getcert list -v
# status: CA_REJECTED
# ca-error: Server at https://ipa.example.com/ipa/xml unwilling to issue certificate

Pasos de Diagnóstico

#============================================#
# DIAGNOSTICAR CA_REJECTED
#============================================#

# Paso 1: Verificar detalles de error
sudo getcert list -v -f /etc/pki/tls/certs/web.crt
# Mirar campo 'ca-error'

# Paso 2: ¿Existe el principal de servicio?
ipa service-show HTTP/$(hostname -f)
# Si error: Service not found

# Paso 3: ¿Está el host inscrito?
ipa host-show $(hostname -f)

# Paso 4: Verificar que el perfil de certificado existe
sudo getcert list -v | grep "profile:"
ipa certprofile-show caIPAserviceCert

# Paso 5: Verificar detalles de solicitud
sudo getcert list -v | grep -A30 "Request ID"

Soluciones para CA_REJECTED

Solución 1: Crear Principal de Servicio

# Agregar principal de servicio faltante
ipa service-add HTTP/$(hostname -f)

# Agregar SAN (si es necesario)
ipa service-mod HTTP/$(hostname -f) --addattr=cn=web.example.com

# Reintentar
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt

Solución 2: Corregir Entrada de Host

# Re-inscribir a IPA si es necesario
sudo ipa-client-install --force-join

# Verificar
ipa host-show $(hostname -f)

Solución 3: Verificar Permisos

# Verificar si tienes permiso para solicitar certs
ipa permission-find --name="Request Certificate"

# Verificar ACLs
ipa aci-find --name="*cert*"

# Puede necesitar que admin de IPA otorgue permisos

30.4 Fallos de Renovación

El Certificado No Se Renueva

Síntoma: Certificado acercándose a expiración pero no se renueva

Diagnóstico:

#============================================#
# DIAGNOSTICAR FALLO DE RENOVACIÓN
#============================================#

# Paso 1: Verificar estado actual
sudo getcert list -f /etc/pki/tls/certs/web.crt

# Paso 2: ¿Cuándo debería renovarse?
# certmonger renueva a 2/3 del tiempo de vida del cert
# Cert de 365 días → renueva en día 243 (122 días antes de expirar)

# Paso 3: Verificar logs de certmonger
sudo journalctl -u certmonger --since "7 days ago" | grep -i renew

# Paso 4: Forzar intento de renovación
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt

# Paso 5: Observar logs en tiempo real
sudo journalctl -u certmonger -f

Problemas Comunes de Renovación

Problema 1: Comando post-guardado falla

# Verificar comando post-guardado
sudo getcert list -f /etc/pki/tls/certs/web.crt | grep "post-save"
# post-save command: systemctl reload httpd

# Probar comando manualmente
sudo systemctl reload httpd
# Si falla → corregir el comando

# Actualizar comando (recrear entrada de rastreo; no usar getcert rekey)
sudo getcert stop-tracking -f /etc/pki/tls/certs/web.crt
sudo getcert start-tracking \
  -f /etc/pki/tls/certs/web.crt \
  -k /etc/pki/tls/private/web.key \
  -C "systemctl reload httpd"

Problema 2: Servidor IPA caído durante ventana de renovación

# certmonger reintentará
# Verificar calendario de reintentos en logs
sudo journalctl -u certmonger | grep "will try again"

# Reintento manual
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt

30.5 Problemas de Rastreo

El Certificado No Está Siendo Rastreado

Síntoma: El certificado expira porque certmonger no lo estaba rastreando

Solución:

#============================================#
# COMENZAR A RASTREAR CERTIFICADO EXISTENTE
#============================================#

sudo getcert start-tracking \
  -f /etc/pki/tls/certs/existing.crt \
  -k /etc/pki/tls/private/existing.key \
  -c IPA \
  -K HTTP/$(hostname -f)@REALM

Rastreo Duplicado

Síntoma: Mismo certificado rastreado múltiples veces

Diagnóstico:

# Listar todos los certs rastreados
sudo getcert list | grep -E "(Request ID|certificate:)" | \
  awk -F"'" '/certificate:/{cert=$2} /Request ID/{print cert, $2}'

# Buscar duplicados

Solución:

# Eliminar rastreo duplicado
sudo getcert stop-tracking -i <duplicate-request-id>

# Mantener solo una entrada de rastreo por certificado

30.6 Problemas de Configuración

CA Incorrecta Configurada

Síntoma: certmonger intentando alcanzar CA incorrecta

Diagnóstico:

# Verificar CA configurada
sudo getcert list -v | grep "CA:"

# Listar CAs disponibles
sudo getcert list-cas

Solución:

# Dejar de rastrear con CA incorrecta
sudo getcert stop-tracking -f /etc/pki/tls/certs/web.crt

# Re-solicitar con CA correcta
sudo ipa-getcert request \
  -c IPA \  # Especificar CA correcta
  -f /etc/pki/tls/certs/web.crt \
  -k /etc/pki/tls/private/web.key \
  -K HTTP/$(hostname -f)@REALM

30.7 Corrupción de Base de Datos de certmonger

Problema Raro pero Serio

Síntoma: certmonger completamente roto, todos los certs muestran errores

Diagnóstico:

# Verificar base de datos
ls -l /var/lib/certmonger/

# Verificar corrupción
sudo journalctl -u certmonger | grep -i corrupt

Solución (Opción Nuclear):

# PRECAUCIÓN: ¡Esto elimina todo el rastreo!

# Paso 1: Respaldar estado actual
sudo tar czf certmonger-backup-$(date +%Y%m%d).tar.gz \
  /var/lib/certmonger/ \
  /etc/pki/tls/

# Paso 2: Documentar rastreo actual
sudo getcert list > /tmp/certmonger-list-backup.txt

# Paso 3: Detener certmonger
sudo systemctl stop certmonger

# Paso 4: Eliminar base de datos
sudo rm -rf /var/lib/certmonger/cas/*
sudo rm -rf /var/lib/certmonger/requests/*

# Paso 5: Iniciar certmonger
sudo systemctl start certmonger

# Paso 6: Re-agregar certificados (desde documentación de respaldo)
# Volver a solicitar manualmente cada certificado

30.8 Depurar certmonger

Habilitar Logging de Depuración

#============================================#
# MODO DEBUG DE CERTMONGER
#============================================#

# Editar archivo de servicio
sudo systemctl edit certmonger

# Agregar:
[Service]
Environment="G_MESSAGES_DEBUG=all"

# Recargar y reiniciar
sudo systemctl daemon-reload
sudo systemctl restart certmonger

# Observar logs detallados
sudo journalctl -u certmonger -f

# Deshabilitar debug después de la solución de problemas
sudo systemctl revert certmonger
sudo systemctl restart certmonger

Prueba Manual de Solicitud de Cert

#============================================#
# PROBAR SOLICITUD DE CERTIFICADO MANUALMENTE
#============================================#

# Enviar solicitud y observar
sudo ipa-getcert request \
  -f /tmp/test.crt \
  -k /tmp/test.key \
  -K HTTP/$(hostname -f)@REALM \
  -v  # Verboso

# Observar en otra terminal
sudo journalctl -u certmonger -f

# Si exitoso, eliminar prueba
sudo getcert stop-tracking -f /tmp/test.crt -r
rm -f /tmp/test.{crt,key}

30.9 Escenarios Comunes

Escenario 1: Todos los Certificados Muestran CA_UNREACHABLE

Causa Probable: Servidor IPA caído o problema de red

Solución Rápida:

# Verificar IPA
ipa ping

# Si está caído, corregir IPA primero
ssh ipa-server "sudo ipactl start"

# Si problema de red, corregir red

# Reiniciar certmonger
sudo systemctl restart certmonger

Escenario 2: Un Certificado Atascado

Diagnóstico:

# Verificar certificado específico
sudo getcert list -f /etc/pki/tls/certs/problem.crt

# Intentar reenviar
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/problem.crt

# Si aún atascado, recrear solicitud
sudo getcert stop-tracking -f /etc/pki/tls/certs/problem.crt
sudo ipa-getcert request \
  -f /etc/pki/tls/certs/problem.crt \
  -k /etc/pki/tls/private/problem.key \
  -K HTTP/$(hostname -f)@REALM \
  -D $(hostname -f)

Escenario 3: Certificado Renovado pero Servicio No Recargado

Síntoma: Nuevo cert existe pero servicio aún usa el antiguo

Causa: Comando post-guardado falló o no está configurado

Solución:

# Verificar comando post-guardado
sudo getcert list -f /etc/pki/tls/certs/web.crt | grep "post-save"

# Si falta, agregarlo (recrear entrada de rastreo; no usar getcert rekey)
sudo getcert stop-tracking -f /etc/pki/tls/certs/web.crt
sudo getcert start-tracking \
  -f /etc/pki/tls/certs/web.crt \
  -k /etc/pki/tls/private/web.key \
  -C "systemctl reload httpd"

# Probar que comando post-guardado funciona
sudo systemctl reload httpd

# Forzar renovación para probar
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt

30.10 Conclusiones Clave

  1. CA_UNREACHABLE es el problema más común - Verificar conectividad IPA
  2. CA_REJECTED significa problema de principal - Crear principal de servicio
  3. Estado MONITORING significa que todo está bien
  4. Comandos post-guardado críticos - Probarlos independientemente
  5. Logs de certmonger en journal - Usar journalctl -u certmonger
  6. Reintentar con resubmit - A menudo corrige problemas transitorios
  7. Verificar tickets Kerberos - Tickets expirados causan problemas

Tarjeta de Referencia Rápida

┌────────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA SOLUCIÓN DE PROBLEMAS CERTMONGER             │
├────────────────────────────────────────────────────────────────┤
│ Estado:           getcert list                                 │
│ Verboso:          getcert list -v                              │
│ Específico:       getcert list -f /path/to/cert.crt            │
│ Logs:             journalctl -u certmonger -f                  │
│                                                                │
│ Reenviar:         ipa-getcert resubmit -f /path/to/cert.crt    │
│ Dejar rastrear:   getcert stop-tracking -f /path/to/cert.crt   │
│ Iniciar rastreo:  getcert start-tracking -f cert -k key        │
│                                                                │
│ CA_UNREACHABLE:   Verificar: ipa ping, klist                   │
│                   Solución: kinit -k host/$(hostname -f)@REALM │
│                                                                │
│ CA_REJECTED:      Verificar: ipa service-show SERVICE/host     │
│                   Solución: ipa service-add SERVICE/host       │
│                                                                │
│ Debug:            systemctl edit certmonger                    │
│                   Environment="G_MESSAGES_DEBUG=all"           │
└────────────────────────────────────────────────────────────────┘

✅ MONITORING = ¡Todo bien!
❌ CA_UNREACHABLE = Verificar conectividad IPA
❌ CA_REJECTED = Verificar principal de servicio

Navegación del Capítulo

Capítulo 31: Solución de Problemas de Crypto-Policy

Solo RHEL 8/9/10: Las crypto-policies son poderosas pero pueden causar problemas de compatibilidad. Aprende cómo diagnosticar y solucionar problemas de crypto-policy.


31.1 Resumen de Crypto-Policy

Disponible: Solo RHEL 8, 9, 10 (NO RHEL 7)

Verificación Rápida:

# Verificar si crypto-policies está disponible
which update-crypto-policies

# Si se encuentra: RHEL 8/9/10
# Si no se encuentra: RHEL 7 (sin crypto-policies)

# Política actual
update-crypto-policies --show

31.2 Problemas Comunes de Crypto-Policy

Problema 1: La Aplicación Falla Después de Cambio de Política

Síntoma: El servicio funcionaba, luego cambiaste crypto-policy, ahora falla

Escenario:

# Antes
update-crypto-policies --show
# DEFAULT

# Lo cambiaste
sudo update-crypto-policies --set FUTURE
sudo systemctl restart httpd

# Ahora httpd no inicia o los clientes no pueden conectar

Diagnóstico:

#============================================#
# DIAGNOSTICAR IMPACTO DE CAMBIO DE POLÍTICA
#============================================#

# Paso 1: Verificar qué cambió
cat /etc/crypto-policies/back-ends/opensslcnf.config

# Paso 2: Verificar logs
sudo journalctl -xe -u httpd | grep -i cipher

# Paso 3: Probar conexión
openssl s_client -connect localhost:443

# Paso 4: Verificar si app sobrescribe política
grep -r "SSLProtocol\|SSLCipherSuite" /etc/httpd/

Solución:

# Solución 1: Revertir política
sudo update-crypto-policies --set DEFAULT
sudo systemctl restart httpd

# Solución 2: Corregir configuración de aplicación
# Eliminar especificaciones de cifrado codificadas
# Dejar que crypto-policy lo maneje

# Solución 3: Crear módulo de política personalizado (RHEL 9+)
# Ver Capítulo 23 para detalles

Problema 2: “no shared cipher”

Síntoma: Los clientes no pueden conectar después de cambio de política

Error Completo:

SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
no shared cipher

Diagnóstico:

#============================================#
# DIAGNOSTICAR DESAJUSTE DE CIFRADO
#============================================#

# Paso 1: Verificar política actual
update-crypto-policies --show
# FUTURE  ← ¡Muy estricta!

# Paso 2: ¿Qué cifrados están disponibles?
openssl ciphers -v | head -20

# Paso 3: Probar capacidades del cliente
openssl s_client -connect server:443 -cipher 'ALL'

# Paso 4: ¿El cliente es muy antiguo?
# Cliente antiguo podría solo soportar cifrados débiles bloqueados por política FUTURE

Soluciones:

# Solución 1: Usar política menos estricta (¡temporal!)
sudo update-crypto-policies --set DEFAULT
sudo systemctl restart services

# Solución 2: Actualizar cliente para soportar cifrados modernos

# Solución 3: Crear módulo de política personalizado
# Permitir cifrado específico para compatibilidad

Problema 3: Cliente TLS 1.0/1.1 No Puede Conectar

Síntoma: Clientes antiguos fallan al conectar a servidor RHEL 8+

Error:

SSL routines:ssl3_read_bytes:tlsv1 alert protocol version
wrong version number

Diagnóstico:

# Verificar política
update-crypto-policies --show
# DEFAULT  ← Bloquea TLS 1.0/1.1

# Probar si TLS 1.0 funciona
openssl s_client -connect server:443 -tls1
# Debería fallar con política DEFAULT

# Probar si TLS 1.2 funciona
openssl s_client -connect server:443 -tls1_2
# Debería funcionar

Soluciones:

# Solución 1: Política LEGACY temporal (¡NO recomendado!)
sudo update-crypto-policies --set LEGACY
sudo systemctl restart services
# Ahora TLS 1.0/1.1 permitido

# Solución 2: Actualizar cliente para soportar TLS 1.2+
# Esta es la solución APROPIADA

# Solución 3: Sobrescritura por aplicación (último recurso)
# Ejemplo Apache:
# SSLProtocol all -SSLv3  # Re-habilita TLS 1.0/1.1

Problema 4: Servicio Sobrescribiendo Crypto-Policy

Síntoma: Los cambios de política no afectan al servicio

Diagnóstico:

#============================================#
# VERIFICAR SOBRESCRITURAS DE POLÍTICA
#============================================#

# Apache
grep -r "SSLProtocol\|SSLCipherSuite" /etc/httpd/

# NGINX
grep -r "ssl_protocols\|ssl_ciphers" /etc/nginx/

# Postfix
sudo postconf | grep -E "smtp.*_tls_protocols|smtp.*_tls_ciphers"

# ¡Si se encuentra → El servicio está sobrescribiendo la política!

Solución:

# Eliminar sobrescrituras de archivos de configuración
# Dejar que crypto-policy maneje ajustes TLS

# Apache: Eliminar o comentar
# #SSLProtocol all -SSLv3
# #SSLCipherSuite ...

# NGINX: Eliminar
# #ssl_protocols ...
# #ssl_ciphers ...

# Reiniciar servicio
sudo systemctl restart httpd

31.3 Crypto-Policy No Aplicada

Política Establecida Pero Sin Efecto

Síntomas:

  • Política cambiada pero servicios aún usan ajustes antiguos
  • Cifrados débiles aún aceptados

Diagnóstico:

#============================================#
# VERIFICAR QUE LA POLÍTICA ESTÁ ACTIVA
#============================================#

# Paso 1: Confirmar política establecida
update-crypto-policies --show

# Paso 2: Verificar cuándo se actualizó última vez la política
ls -l /etc/crypto-policies/back-ends/

# Paso 3: Verificar si servicios se reiniciaron
systemctl status httpd nginx postfix | grep "Active:"
# ¡Los servicios DEBEN reiniciarse después de cambio de política!

# Paso 4: Probar cifrados reales en uso
openssl s_client -connect localhost:443 | grep "Cipher"

Solución:

# Reiniciar TODOS los servicios
sudo systemctl restart httpd nginx postfix slapd

# O reiniciar (asegura que todo recoja los cambios)
sudo reboot

# Verificar después de reiniciar
openssl s_client -connect localhost:443

31.4 Problemas de Política FIPS

Fallos de Política FIPS

Síntoma: Los servicios fallan en modo FIPS

Diagnóstico:

#============================================#
# DIAGNOSTICAR PROBLEMAS FIPS
#============================================#

# Paso 1: Verificar modo FIPS habilitado
fips-mode-setup --check

# Paso 2: Verificar crypto-policy
update-crypto-policies --show
# Debería mostrar: FIPS

# Paso 3: Verificar algoritmos no-FIPS
# Culpables comunes: MD5, SHA-1, cifrados débiles

# Paso 4: Probar con proveedor FIPS
openssl list -providers | grep fips

Problemas FIPS Comunes:

# Problema: La aplicación usa MD5 (no aprobado por FIPS)
# Error: "digital envelope routines:EVP_DigestInit_ex:disabled for fips"

# Solución: Actualizar aplicación para usar SHA-256

# Problema: El certificado tiene firma SHA-1
# Error: "ca md too weak"

# Solución: Reemitir certificado con SHA-256 o mejor

31.5 Pruebas de Compatibilidad de Política

Antes de Cambiar Política

#!/bin/bash
# test-crypto-policy-change.sh
# Probar cambio de crypto-policy antes de producción

NEW_POLICY=$1  # DEFAULT, LEGACY, FUTURE, o FIPS

if [ -z "$NEW_POLICY" ]; then
  echo "Uso: $0 <policy>"
  exit 1
fi

echo "=== Probando Cambio de Crypto-Policy a $NEW_POLICY ==="

# Guardar política actual
CURRENT=$(update-crypto-policies --show)
echo "Política actual: $CURRENT"

# Cambiar política
echo "Cambiando a $NEW_POLICY..."
sudo update-crypto-policies --set "$NEW_POLICY"

# Reiniciar servicios
echo "Reiniciando servicios..."
sudo systemctl restart httpd nginx postfix 2>/dev/null

# Esperar a que servicios inicien
sleep 3

# Probar cada servicio
echo ""
echo "Probando servicios:"

# Apache
if systemctl is-active --quiet httpd; then
  curl -ks https://localhost/ >/dev/null && \
    echo "✅ Apache: OK" || echo "❌ Apache: FALLÓ"
else
  echo "❌ Apache: No ejecutándose"
fi

# NGINX
if systemctl is-active --quiet nginx; then
  curl -ks https://localhost:8443/ >/dev/null && \
    echo "✅ NGINX: OK" || echo "❌ NGINX: FALLÓ"
else
  echo "⚠️ NGINX: No instalado"
fi

# Postfix
if systemctl is-active --quiet postfix; then
  timeout 3 openssl s_client -starttls smtp -connect localhost:25 </dev/null &>/dev/null && \
    echo "✅ Postfix: OK" || echo "❌ Postfix: FALLÓ"
else
  echo "⚠️ Postfix: No instalado"
fi

# Preguntar si mantener o revertir
echo ""
read -p "¿Mantener política $NEW_POLICY? (y/n): " KEEP

if [ "$KEEP" != "y" ]; then
  echo "Revirtiendo a $CURRENT..."
  sudo update-crypto-policies --set "$CURRENT"
  sudo systemctl restart httpd nginx postfix 2>/dev/null
  echo "✅ Revertido"
else
  echo "✅ Manteniendo política $NEW_POLICY"
fi

31.6 Flujo de Trabajo de Solución de Problemas

Enfoque Sistemático

¿Problema de Crypto-Policy?
    │
    ├─ Paso 1: Identificar política actual
    │   └─ update-crypto-policies --show
    │
    ├─ Paso 2: Verificar si política cambió recientemente
    │   └─ Verificar /var/log/messages para "crypto-policies"
    │
    ├─ Paso 3: Probar con política diferente
    │   └─ sudo update-crypto-policies --set LEGACY
    │   └─ Si funciona → política era muy estricta
    │
    ├─ Paso 4: Identificar incompatibilidad
    │   └─ openssl s_client -cipher 'ALL' -tls1
    │   └─ Encontrar qué necesita cliente/servidor
    │
    ├─ Paso 5: Elegir solución
    │   ├─ A) Actualizar cliente (mejor)
    │   ├─ B) Crear módulo personalizado (bueno)
    │   ├─ C) Usar política menos estricta (aceptable)
    │   └─ D) Sobrescritura por app (último recurso)
    │
    └─ Paso 6: Probar y documentar
        └─ Verificar que la solución funciona
        └─ Documentar por qué se necesitó el cambio

31.7 Depurar Aplicación de Crypto-Policy

Verificar que la Política Está Aplicada

#============================================#
# VERIFICAR APLICACIÓN DE CRYPTO-POLICY
#============================================#

# Paso 1: Verificar política
update-crypto-policies --show

# Paso 2: Verificar que archivos back-end se actualizaron
ls -l /etc/crypto-policies/back-ends/
# Los archivos deberían estar modificados recientemente

# Paso 3: Ver configuración de OpenSSL
cat /etc/crypto-policies/back-ends/opensslcnf.config

# Paso 4: Probar disponibilidad real de cifrado
openssl ciphers -v | grep -E "TLS|SSL"

# Paso 5: Probar conexión
openssl s_client -connect localhost:443
# Buscar: Protocol version, Cipher

# Paso 6: Verificar si servicio se reinició desde cambio de política
systemctl status httpd | grep "Active:"
# Debería mostrar tiempo de activación reciente

31.8 Escenarios Comunes

Escenario 1: Aplicación Legacy Después de Actualización a RHEL 8

Problema: La app funcionaba en RHEL 7, falla en RHEL 8

Causa Raíz: RHEL 7 no tenía crypto-policies, RHEL 8 DEFAULT bloquea TLS 1.0/1.1

Solución:

# Solución rápida (¡temporal!):
sudo update-crypto-policies --set LEGACY

# Solución apropiada:
# Actualizar aplicación para soportar TLS 1.2+

# Documentar excepción
echo "Aplicación X requiere política LEGACY debido a requisito TLS 1.0" > \
  /etc/crypto-policies/POLICY-EXCEPTION.txt

Escenario 2: No Se Puede Conectar a Windows Server 2008

Problema: RHEL 9 no puede conectar a servidor Windows antiguo

Causa: Windows Server 2008 solo soporta TLS 1.0

Soluciones:

# Opción 1: Actualizar Windows (mejor)

# Opción 2: Política LEGACY (temporal)
sudo update-crypto-policies --set LEGACY

# Opción 3: Módulo de política personalizado para este caso específico
# Ver Capítulo 23

31.9 Conclusiones Clave

  1. Crypto-policies son solo RHEL 8+ (no RHEL 7)
  2. Los servicios DEBEN reiniciarse después de cambio de política
  3. Los cambios de política son en todo el sistema - Afectan todo
  4. DEFAULT es recomendada para la mayoría de entornos
  5. LEGACY debería ser solo temporal
  6. Probar antes de desplegar nuevas políticas
  7. Actualizar clientes en lugar de debilitar política

Tarjeta de Referencia Rápida

┌───────────────────────────────────────────────────────────────┐
│ SOLUCIÓN DE PROBLEMAS CRYPTO-POLICY                           │
├───────────────────────────────────────────────────────────────┤
│ Verificar:       update-crypto-policies --show                │
│ Establecer:      sudo update-crypto-policies --set <POLICY>   │
│ Revertir:        sudo update-crypto-policies --set DEFAULT    │
│                                                               │
│ Back-ends:       /etc/crypto-policies/back-ends/              │
│ OpenSSL:         cat .../back-ends/opensslcnf.config          │
│                                                               │
│ Probar:          openssl ciphers -v                           │
│                  openssl s_client -connect :443               │
│                                                               │
│ Después cambio:  sudo systemctl restart <todos-servicios>     │
│                  O: sudo reboot                               │
│                                                               │
│ Debug:           grep -r "SSLProtocol\|ssl_protocols" /etc/   │
│                  (buscar sobrescrituras)                      │
└───────────────────────────────────────────────────────────────┘

⚠️ RHEL 7 no tiene crypto-policies
✅ Siempre reiniciar servicios después de cambio de política
✅ DEFAULT funciona para 95% de los casos

Navegación del Capítulo

Capítulo 32: Análisis de Informes SOS

Esencial para Soporte: Los informes SOS son la herramienta de diagnóstico del sistema de RHEL. Aprende cómo extraer información de certificados de informes SOS para solución de problemas.


32.1 ¿Qué es un Informe SOS?

sosreport es la herramienta de recopilación de datos de diagnóstico de Red Hat.

Contiene:

  • ✅ Archivos de configuración del sistema
  • ✅ Archivos de log
  • ✅ Salidas de comandos
  • ✅ Listas de paquetes
  • ✅ Información de certificados
  • ✅ Ajustes de seguridad
  • ❌ Claves privadas (¡excluidas por seguridad!)

Casos de Uso:

  • Abrir casos de soporte Red Hat
  • Análisis post-incidente
  • Auditorías pre-migración
  • Verificaciones de cumplimiento de seguridad

32.2 Generar un Informe SOS

Generación Básica de Informe SOS

#============================================#
# GENERAR INFORME SOS
#============================================#

# Instalar sos (usualmente pre-instalado)
sudo dnf install sos -y

# Generar informe
sudo sos report

# Prompts interactivos:
# - ID de caso (opcional)
# - Descripción
# - Confirmar

# Salida:
# /var/tmp/sosreport-hostname-YYYYMMDDHHMMSS.tar.xz

# Extraer
tar xf /var/tmp/sosreport-*.tar.xz
cd sosreport-*/

Informe SOS Enfocado en Certificados

#============================================#
# INFORME SOS CON ENFOQUE EN CERTIFICADOS
#============================================#

# Generar con plugins específicos
sudo sos report \
  --batch \
  --enable-plugins crypto,openssl,certmonger,freeipa \
  --case-id "CASE12345"

# O especificar qué incluir
sudo sos report \
  --batch \
  -o crypto \
  -o openssl \
  -o certmonger \
  -o pki

32.3 Encontrar Información de Certificados en SOS

Ubicaciones Clave en Informe SOS

#============================================#
# ARCHIVOS RELACIONADOS CON CERTIFICADOS EN INFORME SOS
#============================================#

# Después de extraer sosreport-*.tar.xz:
cd sosreport-*/

# Archivos de certificado (¡solo públicos, sin claves privadas!)
ls -la etc/pki/tls/certs/
ls -la etc/pki/ca-trust/source/anchors/

# Rastreo de certmonger
cat sos_commands/certmonger/getcert_list

# Versión de OpenSSL
cat sos_commands/crypto/openssl_version

# Crypto-policy (RHEL 8+)
cat sos_commands/crypto/update-crypto-policies_--show

# Almacén de confianza
ls -la etc/pki/ca-trust/extracted/

# Configuraciones de servicios
cat etc/httpd/conf.d/ssl.conf
cat etc/nginx/nginx.conf
cat etc/postfix/main.cf | grep tls

# Verificación de expiración de certificado
cat sos_commands/crypto/openssl_x509_-in_*

# Información del sistema
cat etc/redhat-release
cat sos_commands/kernel/uname_-a

32.4 Analizar Problemas de Certificados desde SOS

Análisis de Expiración de Certificados

#============================================#
# VERIFICAR EXPIRACIÓN DE CERTIFICADOS EN SOS
#============================================#

# Navegar a directorio de informe SOS
cd sosreport-hostname-*/

# Encontrar todas las salidas de inspección de certificados
find sos_commands/crypto/ -name "*x509*" -type f

# Verificar cada certificado
for cert_output in sos_commands/crypto/openssl_x509_*.txt; do
  echo "=== $cert_output ==="
  grep -E "(Subject:|Not After)" "$cert_output"
  echo ""
done

# O extraer fechas de expiración
grep -r "Not After" sos_commands/crypto/ | sort

Análisis de Estado de certmonger

#============================================#
# ANALIZAR CERTMONGER DESDE SOS
#============================================#

# Salida de lista de certmonger
cat sos_commands/certmonger/getcert_list

# Buscar:
# - status: CA_UNREACHABLE  ← ¡Problema!
# - status: CA_REJECTED     ← ¡Problema!
# - expires: <date>         ← Verificar si pronto

# Contar certificados por estado
grep "status:" sos_commands/certmonger/getcert_list | sort | uniq -c

# Encontrar certificados problemáticos
grep -B10 "CA_UNREACHABLE\|CA_REJECTED" sos_commands/certmonger/getcert_list

Análisis de Crypto-Policy (RHEL 8+)

#============================================#
# VERIFICAR CRYPTO-POLICY EN SOS
#============================================#

# Política actual
cat sos_commands/crypto/update-crypto-policies_--show

# Verificar sobrescrituras
grep -r "SSLProtocol\|SSLCipherSuite" etc/httpd/
grep -r "ssl_protocols\|ssl_ciphers" etc/nginx/
grep -r "tls_protocols" etc/postfix/main.cf

# Si se encuentran sobrescrituras: Documentar que servicio opta por no usar crypto-policy

32.5 Hallazgos Comunes en Informes SOS

Hallazgo 1: Certificados Expirados

En Informe SOS:

# Verificar expiraciones de certificados
grep "Not After" sos_commands/crypto/* | \
  while read line; do
    # Parsear y verificar si expiró
    echo "$line"
  done

Señales de Alerta:

  • Certificados expirados antes de generación del informe SOS
  • Certificados expirando dentro de 30 días
  • Múltiples certificados expirados

Hallazgo 2: Problemas de certmonger

En Informe SOS:

# Verificar estado de certmonger
cat sos_commands/certmonger/getcert_list | grep -A15 "Request ID"

# Problemas comunes:
# - Múltiples CA_UNREACHABLE (problema conectividad IPA)
# - CA_REJECTED (problema permisos/principal)
# - Fechas de expiración antiguas sin renovación (certmonger no funcionando)

Hallazgo 3: Certificados Intermedios Faltantes

En Informe SOS:

# Verificar cadena de certificado
# Si configuración de servicio apunta a cert sin intermedio:
grep "SSLCertificateFile" etc/httpd/conf.d/ssl.conf
# /etc/pki/tls/certs/server.crt  ← Verificar si esto incluye cadena

# Verificar certificado real
openssl x509 -in etc/pki/tls/certs/server.crt -noout -text
# Buscar: Issuer (si no es conocido, necesita intermedio)

32.6 Lista de Verificación de Informe SOS para Certificados

Análisis Sistemático

## Lista de Verificación Análisis de Certificados en Informe SOS

### Información del Sistema
- [ ] Versión RHEL (`cat etc/redhat-release`)
- [ ] Versión OpenSSL (`cat sos_commands/crypto/openssl_version`)
- [ ] Crypto-policy (`cat sos_commands/crypto/update-crypto-policies*`)
- [ ] Modo FIPS (`grep FIPS sos_commands/crypto/*`)

### Archivos de Certificado
- [ ] Listar certificados (`ls etc/pki/tls/certs/`)
- [ ] Verificar permisos (`ls -la etc/pki/tls/private/`)
- [ ] Verificar ownership
- [ ] Verificar contextos SELinux (`ls -Z etc/pki/tls/`)

### Validez de Certificado
- [ ] Verificar expiraciones (`grep "Not After" sos_commands/crypto/*`)
- [ ] Identificar certificados expirados
- [ ] Identificar certificados expirando pronto (< 30 días)
- [ ] Verificar algoritmos de firma (SHA-1 = problema en RHEL 9+)

### Estado de certmonger (si se usa)
- [ ] ¿certmonger ejecutándose? (`cat sos_commands/systemd/systemctl_list-units`)
- [ ] Certificados rastreados (`cat sos_commands/certmonger/getcert_list`)
- [ ] ¿Algún CA_UNREACHABLE o CA_REJECTED?
- [ ] ¿Calendario de renovación apropiado?

### Configuraciones de Servicios
- [ ] Config SSL Apache (`cat etc/httpd/conf.d/ssl.conf`)
- [ ] Config SSL NGINX (`cat etc/nginx/nginx.conf`)
- [ ] Config TLS Postfix (`grep tls etc/postfix/main.cf`)
- [ ] Config TLS OpenLDAP
- [ ] ¿Rutas de certificado correctas?

### Almacén de Confianza
- [ ] CAs personalizadas (`ls etc/pki/ca-trust/source/anchors/`)
- [ ] Paquete de confianza actualizado
- [ ] Certs en lista negra (RHEL 8+)

### Logs
- [ ] Errores recientes de certificado (`grep -i cert var/log/messages`)
- [ ] Errores SSL/TLS en logs de servicio
- [ ] Denegaciones SELinux (`grep AVC var/log/audit/audit.log | grep cert`)

### Recomendaciones
- [ ] Listar problemas de certificados encontrados
- [ ] Priorizar por severidad
- [ ] Sugerir pasos de remediación

32.7 Script Automatizado de Análisis SOS

Buscador de Problemas de Certificados

#!/bin/bash
# analyze-sos-certificates.sh
# Detección automatizada de problemas de certificados en informes SOS

SOS_DIR=$1

if [ -z "$SOS_DIR" ] || [ ! -d "$SOS_DIR" ]; then
  echo "Uso: $0 /path/to/sosreport-directory"
  exit 1
fi

cd "$SOS_DIR"

echo "=== Análisis de Certificados en Informe SOS ==="
echo "Informe: $(basename $SOS_DIR)"
echo ""

# Info del sistema
echo "Información del Sistema:"
echo "  Versión RHEL: $(cat etc/redhat-release 2>/dev/null)"
echo "  OpenSSL: $(cat sos_commands/crypto/openssl_version 2>/dev/null | head -2)"
if [ -f sos_commands/crypto/update-crypto-policies_--show ]; then
  echo "  Crypto-Policy: $(cat sos_commands/crypto/update-crypto-policies_--show)"
fi
echo ""

# Expiración de certificados
echo "Expiración de Certificados:"
if [ -d sos_commands/crypto ]; then
  grep -h "Not After" sos_commands/crypto/openssl_x509_* 2>/dev/null | \
    while read line; do
      echo "  $line"
    done
else
  echo "  No se encontraron datos de certificados"
fi
echo ""

# Estado de certmonger
echo "Estado de certmonger:"
if [ -f sos_commands/certmonger/getcert_list ]; then
  STATUS_COUNT=$(grep "status:" sos_commands/certmonger/getcert_list | sort | uniq -c)
  echo "$STATUS_COUNT"

  # Resaltar problemas
  if grep -q "CA_UNREACHABLE\|CA_REJECTED" sos_commands/certmonger/getcert_list; then
    echo "  ⚠️ Problemas encontrados:"
    grep -B5 "CA_UNREACHABLE\|CA_REJECTED" sos_commands/certmonger/getcert_list | \
      grep -E "(Request ID|status:)" | head -20
  fi
else
  echo "  certmonger no instalado o sin datos"
fi
echo ""

# Verificar problemas comunes
echo "Problemas Potenciales:"
ISSUES=0

# Certs expirados (verificación básica)
if grep -q "Not After.*202[0-3]" sos_commands/crypto/* 2>/dev/null; then
  echo "  ⚠️ Certificados potencialmente expirados encontrados"
  ((ISSUES++))
fi

# Problemas de certmonger
if grep -q "CA_UNREACHABLE" sos_commands/certmonger/getcert_list 2>/dev/null; then
  echo "  ⚠️ Estado CA_UNREACHABLE de certmonger encontrado"
  ((ISSUES++))
fi

# Denegaciones SELinux
if grep -q "avc.*denied.*cert" var/log/audit/audit.log 2>/dev/null; then
  echo "  ⚠️ Denegaciones SELinux relacionadas con certificados"
  ((ISSUES++))
fi

if [ $ISSUES -eq 0 ]; then
  echo "  ✅ No se detectaron problemas obvios"
fi

echo ""
echo "=== Análisis Completo ==="

32.8 Archivos Clave a Verificar en SOS

Archivos Críticos de Certificados

sosreport-hostname-YYYYMMDDHHMMSS/
├── etc/
│   ├── pki/
│   │   ├── tls/certs/                     ← Certificados (públicos)
│   │   ├── ca-trust/                      ← Almacén de confianza
│   │   └── nssdb/                         ← Bases de datos NSS
│   ├── httpd/conf.d/ssl.conf              ← Config Apache
│   ├── nginx/nginx.conf                   ← Config NGINX
│   └── postfix/main.cf                    ← Config Postfix
│
├── sos_commands/
│   ├── crypto/
│   │   ├── openssl_version                ← Versión OpenSSL
│   │   ├── openssl_x509_*                 ← Inspecciones de certificados
│   │   └── update-crypto-policies_--show  ← Política
│   │
│   ├── certmonger/
│   │   └── getcert_list                   ← Estado certmonger
│   │
│   ├── systemd/
│   │   └── systemctl_list-units           ← Estado de servicios
│   │
│   └── networking/
│       └── ss_-tulpn                      ← Puertos escuchando
│
└── var/log/
    ├── messages                           ← Log del sistema
    ├── httpd/ssl_error_log                ← Errores SSL Apache
    └── audit/audit.log                    ← Denegaciones SELinux

32.9 Escenarios Comunes en Informes SOS

Escenario 1: Sitio Web Caído - ¿Problema de Certificado?

Pasos de Análisis:

# 1. Verificar si httpd estaba ejecutándose
grep "httpd.service" sos_commands/systemd/systemctl_list-units
# active (running) ← Servicio estaba activo

# 2. Verificar log de errores SSL
tail var/log/httpd/ssl_error_log
# Buscar errores relacionados con certificados

# 3. Verificar expiración de certificado
cat sos_commands/crypto/openssl_x509_*server.crt* | grep "Not After"

# 4. Verificar configuración de Apache
cat etc/httpd/conf.d/ssl.conf | grep -E "SSLCertificate"

# 5. Verificar si existían archivos
ls -l etc/pki/tls/certs/ | grep server

Escenario 2: Fallos de Renovación de certmonger

Pasos de Análisis:

# 1. Verificar estado de certmonger
cat sos_commands/certmonger/getcert_list

# 2. Buscar CA_UNREACHABLE
grep "CA_UNREACHABLE" sos_commands/certmonger/getcert_list

# 3. Verificar conectividad IPA (si usa FreeIPA)
grep "ipa" var/log/messages | tail -50

# 4. Verificar tickets Kerberos
cat sos_commands/kerberos/klist* 2>/dev/null

# 5. Identificar cuándo debería haber ocurrido renovación
# Buscar fechas de expiración, calcular 2/3 del tiempo de vida

32.10 Conclusiones Clave

  1. Los informes SOS son invaluables para solución de problemas remota
  2. No incluyen claves privadas (¡seguridad!)
  3. SÍ incluyen información de certificados (certs públicos, config, logs)
  4. Estado de certmonger preservado en salida getcert_list
  5. Crypto-policy registrada (RHEL 8+)
  6. Usar para análisis post-incidente y auditorías
  7. Automatizar análisis con scripts

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ ANÁLISIS DE CERTIFICADOS EN INFORME SOS                      │
├──────────────────────────────────────────────────────────────┤
│ Generar:         sudo sos report                             │
│ Extraer:         tar xf sosreport-*.tar.xz                   │
│                                                              │
│ Archivos clave:  etc/pki/tls/certs/                          │
│                  etc/httpd/conf.d/ssl.conf                   │
│                  sos_commands/certmonger/getcert_list        │
│                  sos_commands/crypto/openssl_version         │
│                  sos_commands/crypto/update-crypto-policies* │
│                  var/log/httpd/ssl_error_log                 │
│                                                              │
│ Verificaciones comunes:                                      │
│   - Fechas de expiración de certificados                     │
│   - Estado de certmonger                                     │
│   - Configuraciones de servicios                             │
│   - Ajuste de crypto-policy                                  │
│   - Denegaciones SELinux                                     │
└──────────────────────────────────────────────────────────────┘

⚠️ Claves privadas NO incluidas (seguridad)
✅ Perfecto para solución de problemas remota

Navegación del Capítulo

Capítulo 33: Procedimientos de Emergencia

Producción Caída: Cuando los certificados fallan y los servicios están fuera de línea, necesitas procedimientos rápidos y confiables. Este capítulo es tu manual de emergencia.


33.1 Filosofía de Respuesta a Emergencias

Cuando la producción está caída:

  • La velocidad importa - Cada minuto cuenta
  • 🎯 Corregir primero, investigar después - Poner servicios en funcionamiento
  • 📝 Documentar todo - Para post-mortem
  • 🔄 Temporal está OK - La solución apropiada viene después de la recuperación

Este capítulo proporciona:

  • Procedimientos de diagnóstico rápido
  • Soluciones alternativas de emergencia
  • Certificados temporales
  • Procedimientos de rollback
  • Plantillas de comunicación

33.2 Diagnóstico Rápido (Primeros 60 Segundos)

Preguntas de Triaje

#============================================#
# TRIAJE DE EMERGENCIA - 60 SEGUNDOS
#============================================#

# P1: ¿Qué está roto?
systemctl status httpd nginx postfix

# P2: ¿Cuándo se rompió?
journalctl -xe --since "10 minutos ago" | grep -i cert

# P3: ¿Certificado expirado?
openssl x509 -in /etc/pki/tls/certs/server.crt -noout -dates

# P4: ¿Cambios recientes?
rpm -qa --last | head -20        # Actualizaciones recientes de paquetes
ausearch -m SYSCALL --start recent | grep cert  # Acceso reciente a archivo cert

# P5: ¿Disco lleno?
df -h /etc/pki

# P6: ¿SELinux bloqueando?
ausearch -m avc -ts recent | grep cert

Árbol de Decisión (Primera Respuesta)

Problema de Certificado Detectado
    │
    ├─ ¿El servicio no inicia?
    │   ├─ Archivo no encontrado → Solución Rápida #1: Restaurar desde respaldo
    │   ├─ Permission denied → Solución Rápida #2: Corregir permisos
    │   └─ Cert inválido → Solución Rápida #3: Usar cert temporal
    │
    ├─ ¿Certificado expirado?
    │   └─ Solución Rápida #4: Generar autofirmado temp O restaurar respaldo
    │
    ├─ ¿Fallo validación de cadena?
    │   └─ Solución Rápida #5: Agregar CA faltante O usar política LEGACY
    │
    └─ ¿Desconocido/Complejo?
        └─ Escalar + Aplicar Solución Rápida #6: Rollback al último bueno conocido

33.3 Solución Rápida #1: Restaurar desde Respaldo

Escenario: Archivo de certificado/clave faltante o corrupto

Tiempo: 2-5 minutos

#!/bin/bash
# emergency-restore-cert.sh

SERVICE=$1  # apache, nginx, postfix, etc.
BACKUP_DIR="/var/backups/certificates"

echo "=== EMERGENCIA: Restaurando Certificado $SERVICE ==="

# Detener servicio
systemctl stop $SERVICE

# Encontrar respaldo más reciente
LATEST=$(ls -dt $BACKUP_DIR/*/ | head -2)
echo "Usando respaldo de: $LATEST"

# Restaurar certificado
if [ -f "$LATEST/${SERVICE}.crt" ]; then
  cp "$LATEST/${SERVICE}.crt" /etc/pki/tls/certs/
  chmod 644 /etc/pki/tls/certs/${SERVICE}.crt
  echo "✅ Certificado restaurado"
else
  echo "❌ No se encontró respaldo para $SERVICE"
  exit 1
fi

# Restaurar clave
if [ -f "$LATEST/${SERVICE}.key" ]; then
  cp "$LATEST/${SERVICE}.key" /etc/pki/tls/private/
  chmod 600 /etc/pki/tls/private/${SERVICE}.key
  echo "✅ Clave privada restaurada"
fi

# Iniciar servicio
systemctl start $SERVICE

# Verificar
sleep 2
systemctl status $SERVICE

if systemctl is-active --quiet $SERVICE; then
  echo "✅ ÉXITO: $SERVICE está ejecutándose"
  exit 0
else
  echo "❌ FALLÓ: $SERVICE no inició"
  journalctl -xe -u $SERVICE | tail -20
  exit 1
fi

33.4 Solución Rápida #2: Emergencia de Permisos

Escenario: El servicio falla con “permission denied” en archivos de certificado

Tiempo: 30 segundos

#!/bin/bash
# emergency-fix-permissions.sh

echo "=== EMERGENCIA: Corrigiendo Permisos de Certificados ==="

# Corregir directorio de certificados
chmod 755 /etc/pki/tls/certs/
chmod 644 /etc/pki/tls/certs/*.crt 2>/dev/null

# Corregir directorio de clave privada
chmod 711 /etc/pki/tls/private/
chmod 600 /etc/pki/tls/private/*.key 2>/dev/null

# Corregir ownership (ajustar para tu servicio)
chown root:root /etc/pki/tls/certs/*.crt 2>/dev/null
chown root:root /etc/pki/tls/private/*.key 2>/dev/null

# Corregir contextos SELinux
restorecon -Rv /etc/pki/tls/

echo "✅ Permisos corregidos"

# Mostrar resultados
echo ""
echo "Permisos de certificados:"
ls -lZ /etc/pki/tls/certs/*.crt 2>/dev/null | head -5

echo ""
echo "Permisos de claves:"
ls -lZ /etc/pki/tls/private/*.key 2>/dev/null | head -5

33.5 Solución Rápida #3: Generar Certificado Autofirmado Temporal

Escenario: Certificado expirado o inválido, necesita solución inmediata

Tiempo: 1-2 minutos

⚠️ ADVERTENCIA: ¡Los certs autofirmados causan advertencias en navegador! ¡Solo para uso interno de emergencia!

#!/bin/bash
# emergency-self-signed-cert.sh

HOSTNAME=${1:-$(hostname -f)}
DAYS=${2:-30}
CERT_PATH="/etc/pki/tls/certs/${HOSTNAME}-temp.crt"
KEY_PATH="/etc/pki/tls/private/${HOSTNAME}-temp.key"

echo "=== EMERGENCIA: Generando Certificado Autofirmado Temporal ==="
echo "Hostname: $HOSTNAME"
echo "Válido por: $DAYS días"

# Generar certificado autofirmado
openssl req -x509 -nodes -days $DAYS \
  -newkey rsa:2048 \
  -keyout "$KEY_PATH" \
  -out "$CERT_PATH" \
  -subj "/C=US/ST=Emergency/L=Emergency/O=Emergency/CN=$HOSTNAME" \
  -addext "subjectAltName=DNS:$HOSTNAME,DNS:$(hostname -s)"

if [ $? -eq 0 ]; then
  # Establecer permisos
  chmod 600 "$KEY_PATH"
  chmod 644 "$CERT_PATH"

  echo "✅ Certificado temporal generado"
  echo "   Certificado: $CERT_PATH"
  echo "   Clave: $KEY_PATH"
  echo ""
  echo "⚠️ CRÍTICO: ¡Esta es una solución TEMPORAL!"
  echo "   - Solicitar certificado apropiado inmediatamente"
  echo "   - Documentar esta acción de emergencia"
  echo "   - Planificar reemplazo apropiado dentro de $DAYS días"
  echo ""
  echo "Para usar con Apache:"
  echo "  SSLCertificateFile $CERT_PATH"
  echo "  SSLCertificateKeyFile $KEY_PATH"

  # Mostrar certificado
  openssl x509 -in "$CERT_PATH" -noout -text | grep -E "(Subject:|Not After)"
else
  echo "❌ FALLÓ al generar certificado"
  exit 1
fi

33.6 Solución Rápida #4: Renovación de Certificado de Emergencia

Escenario: Certificado expirado, necesita renovación apropiada LO ANTES POSIBLE

Tiempo: 5-15 minutos (depende de CA)

#!/bin/bash
# emergency-renew-cert.sh

CERT_PATH=$1
KEY_PATH=$2
HOSTNAME=$3

echo "=== EMERGENCIA: Renovando Certificado Expirado ==="

# Generar nuevo CSR
CSR_PATH="/tmp/emergency-$(date +%s).csr"

openssl req -new -key "$KEY_PATH" -out "$CSR_PATH" \
  -subj "/CN=$HOSTNAME" \
  -addext "subjectAltName=DNS:$HOSTNAME"

if [ $? -eq 0 ]; then
  echo "✅ CSR generado: $CSR_PATH"
  echo ""
  echo "SIGUIENTES PASOS:"
  echo "1. Enviar CSR a CA inmediatamente:"
  echo "   cat $CSR_PATH"
  echo ""
  echo "2. Mientras esperas a CA:"
  echo "   - Usar cert autofirmado temporal (ver Solución Rápida #3)"
  echo "   - O restaurar desde respaldo (ver Solución Rápida #1)"
  echo ""
  echo "3. Una vez que CA retorne certificado:"
  echo "   cp new-cert.crt $CERT_PATH"
  echo "   systemctl reload <service>"

  # Si usas FreeIPA
  if command -v ipa-getcert &>/dev/null; then
    echo ""
    echo "4. Si usas FreeIPA, intenta renovación automática:"
    echo "   sudo ipa-getcert resubmit -f $CERT_PATH"
  fi
else
  echo "❌ FALLÓ al generar CSR"
  exit 1
fi

33.7 Solución Rápida #5: Emergencia de Cadena de Confianza

Escenario: Error “Unable to get local issuer certificate”

Tiempo: 1-2 minutos

#!/bin/bash
# emergency-fix-trust.sh

CA_CERT=$1  # Ruta a certificado CA

if [ -z "$CA_CERT" ] || [ ! -f "$CA_CERT" ]; then
  echo "❌ Uso: $0 /path/to/ca-cert.crt"
  exit 1
fi

echo "=== EMERGENCIA: Agregando CA al Almacén de Confianza ==="

# Copiar CA a anchors de confianza
cp "$CA_CERT" /etc/pki/ca-trust/source/anchors/

# Actualizar almacén de confianza
update-ca-trust extract

echo "✅ CA agregada al almacén de confianza del sistema"

# Verificar
if trust list | grep -q "$(basename "$CA_CERT" .crt)"; then
  echo "✅ VERIFICADO: CA ahora es confiable"
else
  echo "⚠️ Advertencia: No se pudo verificar que CA fue agregada"
fi

# Probar validación de certificado
echo ""
echo "Prueba tu certificado ahora:"
echo "  openssl verify /path/to/your/cert.crt"

Alternativa: Política LEGACY Temporal (RHEL 8+)

# Si problema de confianza es debido a algoritmos débiles
# ¡TEMPORAL - revertir después de solución apropiada!

echo "=== EMERGENCIA: Estableciendo Crypto Policy LEGACY ==="
update-crypto-policies --show  # Guardar actual
sudo update-crypto-policies --set LEGACY
systemctl restart <service>

echo "⚠️ CRÍTICO: ¡Esto es temporal!"
echo "Solución apropiada requerida dentro de 24 horas"

33.8 Solución Rápida #6: Rollback al Último Bueno Conocido

Escenario: Cambio reciente rompió todo, necesita revertir

Tiempo: 2-5 minutos

#!/bin/bash
# emergency-rollback.sh

echo "=== EMERGENCIA: Rollback a Última Configuración Buena Conocida ==="

# Detener servicio
systemctl stop httpd

# Respaldar estado actual (roto)
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
mkdir -p /var/backups/emergency/$TIMESTAMP
cp -a /etc/pki/tls/certs/*.crt /var/backups/emergency/$TIMESTAMP/ 2>/dev/null
cp -a /etc/pki/tls/private/*.key /var/backups/emergency/$TIMESTAMP/ 2>/dev/null
cp -a /etc/httpd/conf.d/ssl.conf /var/backups/emergency/$TIMESTAMP/ 2>/dev/null

# Restaurar desde último respaldo
LAST_GOOD="/var/backups/certificates/last-known-good"
if [ -d "$LAST_GOOD" ]; then
  cp -a "$LAST_GOOD"/*.crt /etc/pki/tls/certs/
  cp -a "$LAST_GOOD"/*.key /etc/pki/tls/private/
  cp -a "$LAST_GOOD"/ssl.conf /etc/httpd/conf.d/ 2>/dev/null

  # Corregir permisos
  chmod 644 /etc/pki/tls/certs/*.crt
  chmod 600 /etc/pki/tls/private/*.key

  echo "✅ Rollback al último bueno conocido"
else
  echo "❌ ¡No se encontró respaldo last-known-good!"
  echo "Buscando cualquier respaldo reciente..."
  ls -ldt /var/backups/certificates/*/ | head -5
  exit 1
fi

# Iniciar servicio
systemctl start httpd

# Verificar
sleep 2
if systemctl is-active --quiet httpd; then
  echo "✅ ÉXITO: Servicio restaurado"
else
  echo "❌ Servicio aún no inicia"
  journalctl -xe -u httpd | tail -20
  exit 1
fi

33.9 Procedimientos de Emergencia Específicos por Servicio

Recuperación de Emergencia Apache (httpd)

#============================================#
# RECUPERACIÓN DE EMERGENCIA APACHE
#============================================#

# 1. Detener Apache
systemctl stop httpd

# 2. Verificar sintaxis de configuración
apachectl configtest
# Si falla, corregir o restaurar ssl.conf desde respaldo

# 3. Verificar que existan archivos de certificado
ls -l /etc/pki/tls/certs/server.crt
ls -l /etc/pki/tls/private/server.key

# 4. Emergencia: Deshabilitar SSL temporalmente
mv /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.disabled
systemctl start httpd
# Servicio ahora se ejecuta solo en HTTP (puerto 80)

# 5. Corregir certificados, luego re-habilitar SSL
mv /etc/httpd/conf.d/ssl.conf.disabled /etc/httpd/conf.d/ssl.conf
systemctl reload httpd

Recuperación de Emergencia NGINX

#============================================#
# RECUPERACIÓN DE EMERGENCIA NGINX
#============================================#

# 1. Detener NGINX
systemctl stop nginx

# 2. Probar configuración
nginx -t
# Si falla, verificar qué línea/archivo tiene problema

# 3. Emergencia: Comentar configuración SSL
sed -i 's/^\(\s*ssl_certificate\)/# \1/' /etc/nginx/nginx.conf
sed -i 's/^\(\s*listen.*443\)/# \1/' /etc/nginx/nginx.conf
sed -i 's/^\(\s*listen.*ssl\)/# \1/' /etc/nginx/nginx.conf

# 4. Iniciar solo en HTTP
systemctl start nginx

# 5. Corregir certificados, restaurar configuración SSL
# Descomentar líneas o restaurar desde respaldo
systemctl reload nginx

Emergencia certmonger

#============================================#
# RECUPERACIÓN DE EMERGENCIA CERTMONGER
#============================================#

# 1. Verificar estado de certmonger
systemctl status certmonger
getcert list

# 2. Si cert muestra CA_UNREACHABLE
# Verificar conectividad IPA
ipa ping

# 3. Emergencia: Dejar de rastrear, renovación manual
REQUEST_ID=$(getcert list | grep "Request ID" | head -1 | awk -F"'" '{print $2}')
getcert stop-tracking -i $REQUEST_ID

# 4. Renovación manual con IPA
ipa-getcert request -f /etc/pki/tls/certs/server.crt \
  -k /etc/pki/tls/private/server.key \
  -D $(hostname -f) \
  -K host/$(hostname -f)@REALM

# 5. Si IPA no disponible, usar autofirmado temporal
./emergency-self-signed-cert.sh

33.10 Plantillas de Comunicación

Notificación de Incidente (Interna)

Asunto: [URGENTE] Problema de Certificado - <Servicio> Caído

RESUMEN DEL INCIDENTE:
- Servicio: <Apache/NGINX/etc>
- Impacto: Sitio web <Producción/Staging> caído
- Inicio: <Hora>
- Estado: Investigando / Aplicando solución / Resuelto

CAUSA RAÍZ:
- Certificado expiró el <Fecha>
- O: Permisos de archivo de certificado incorrectos
- O: Cadena de confianza CA faltante

ACCIÓN INMEDIATA TOMADA:
- Certificado autofirmado temporal aplicado
- Servicio restaurado a las <Hora>

SIGUIENTES PASOS:
- Solicitar certificado apropiado de CA
- Reemplazar cert temporal antes del <Fecha/Hora>
- Post-mortem programado para <Fecha>

SOLUCIÓN ALTERNATIVA:
- Los usuarios pueden ver advertencias de seguridad (esperado)
- El servicio es funcional a pesar de advertencias

Comunicación al Cliente (Externa)

Asunto: Restauración de Servicio - Breve Interrupción

Estimados Clientes,

Experimentamos una breve interrupción de servicio entre <Hora Inicio> y
<Hora Fin> debido a un problema de configuración de certificado. El servicio
ha sido completamente restaurado.

Pueden notar una advertencia de seguridad temporal. Esto es esperado y
seguro para continuar. Estamos trabajando para reemplazar el certificado
temporal con uno permanente dentro de las próximas horas.

Nos disculpamos por cualquier inconveniente.

Actualizaciones de estado: <URL>
Soporte: <Email/Teléfono>

33.11 Lista de Verificación Post-Emergencia

Después de recuperación de emergencia:

## Lista de Verificación Post-Emergencia

### Inmediato (Dentro de 1 Hora)
- [ ] Servicio confirmado ejecutándose
- [ ] Monitoreo restaurado
- [ ] Stakeholders notificados
- [ ] Solución temporal documentada

### Corto Plazo (Dentro de 24 Horas)
- [ ] Certificado apropiado obtenido
- [ ] Cert temporal reemplazado
- [ ] Configuración validada
- [ ] Respaldos verificados funcionando

### Seguimiento (Dentro de 1 Semana)
- [ ] Análisis de causa raíz completado
- [ ] Documento post-mortem creado
- [ ] Medidas de prevención identificadas
- [ ] Monitoreo/alertas mejoradas
- [ ] Documentación actualizada
- [ ] Equipo debriefing realizado

### Prevención
- [ ] Agregar monitoreo para este escenario
- [ ] Actualizar runbooks
- [ ] Programar renovaciones más tempranas
- [ ] Automatizar si es posible
- [ ] Probar procedimientos de recuperación

33.12 Contactos y Recursos de Emergencia

Mantén Esto a Mano

## Tarjeta de Respuesta a Emergencia de Certificado

### Comandos Rápidos
openssl x509 -in cert.crt -noout -dates      # Verificar expiración
systemctl status <service>                    # Estado servicio
journalctl -xe -u <service>                   # Logs recientes
getcert list                                  # Estado certmonger

### Ubicación Scripts de Emergencia
/usr/local/bin/emergency-*.sh

### Ubicación de Respaldo
/var/backups/certificates/

### Último Bueno Conocido
/var/backups/certificates/last-known-good/

### Información CA
URL CA: <URL>
Contacto CA: <Email/Teléfono>
Servidor FreeIPA: <Hostname>

### Escalación
Líder de Equipo: <Nombre> <Teléfono>
Gerente: <Nombre> <Teléfono>
De Guardia: <Pager/Teléfono>

### Documentación
Runbooks: <URL Wiki>
Incidentes Previos: <Sistema de Tickets>

33.13 Manual de Escenarios de Emergencia

Escenario 1: Certificado Expirado (Producción Caída)

Impacto: ALTO - Servicio no disponible Presión de Tiempo: Crítica Respuesta:

  1. Evaluar (30 segundos)

    openssl x509 -in /etc/pki/tls/certs/server.crt -noout -dates
    
  2. Solución Rápida (2 minutos)

    ./emergency-self-signed-cert.sh $(hostname -f) 30
    # Actualizar configuración de servicio para usar cert temp
    systemctl restart <service>
    
  3. Comunicar (5 minutos)

    • Notificar stakeholders
    • Actualizar página de estado
  4. Solución Apropiada (15-60 minutos)

    # Solicitar nuevo cert de CA
    # O usar certmonger
    ipa-getcert resubmit -f /etc/pki/tls/certs/server.crt
    
  5. Reemplazar cert temp, verificar, documentar

Escenario 2: Certificado Incorrecto Desplegado

Impacto: MEDIO - Servicio activo pero con errores Presión de Tiempo: Moderada Respuesta:

  1. Detener el sangrado - Rollback

    ./emergency-rollback.sh
    
  2. Verificar servicio restaurado

  3. Identificar certificado correcto

  4. Desplegar cert correcto con validación

  5. Documentar qué salió mal

Escenario 3: Servidor CA Caído (No Se Puede Renovar)

Impacto: MEDIO - Renovaciones futuras bloqueadas Presión de Tiempo: Depende de expiración cert Respuesta:

  1. Verificar cronología de expiración de cert

    openssl x509 -in cert.crt -noout -checkend $((86400*7))
    
  2. Si > 7 días: Esperar recuperación de CA, monitorear

  3. Si < 7 días:

    • Generar autofirmado temporal
    • Contactar soporte CA
    • Escalar a gestión
  4. Alternativa: Usar CA diferente temporalmente

Escenario 4: SELinux Bloqueando Certificados

Impacto: BAJO-MEDIO - Servicio no inicia Presión de Tiempo: Moderada Respuesta:

  1. Verificar denegaciones

    ausearch -m avc -ts recent | grep cert
    
  2. Solución rápida - Reetiquetar

    restorecon -Rv /etc/pki/tls/
    
  3. Si persiste - Permissive temporal

    setenforce 0  # ¡TEMPORAL!
    systemctl restart <service>
    
  4. Solución apropiada - Generar política

    audit2allow -a -M mycert
    semodule -i mycert.pp
    setenforce 1
    

33.14 Kit de Herramientas de Emergencia

Crear Kit de Respuesta a Emergencias

#!/bin/bash
# create-emergency-kit.sh
# Crea un kit de respuesta a emergencias portátil

KIT_DIR="/root/cert-emergency-kit"
mkdir -p "$KIT_DIR"

# Copiar scripts de emergencia
cp emergency-*.sh "$KIT_DIR/"

# Crear referencia rápida
cat > "$KIT_DIR/QUICK_REFERENCE.txt" << 'EOF'
=== REFERENCIA RÁPIDA EMERGENCIA DE CERTIFICADO ===

1. VERIFICAR ESTADO
   systemctl status <service>
   openssl x509 -in cert.crt -noout -dates

2. CERT EXPIRADO
   ./emergency-self-signed-cert.sh $(hostname -f)

3. ARCHIVOS FALTANTES
   ./emergency-restore-cert.sh <service>

4. PERMISOS
   ./emergency-fix-permissions.sh

5. ROLLBACK
   ./emergency-rollback.sh

6. LOGS
   journalctl -xe -u <service>
   tail -f /var/log/httpd/ssl_error_log

===========================
Última Actualización: $(date)
EOF

# Establecer permisos
chmod 700 "$KIT_DIR"
chmod 755 "$KIT_DIR"/*.sh

echo "✅ Kit de emergencia creado: $KIT_DIR"
ls -lh "$KIT_DIR"

33.15 Conclusiones Clave

  1. Velocidad sobre perfección en emergencias
  2. Las soluciones temporales están OK - Corregir apropiadamente después
  3. La comunicación es crítica - Mantener informados a stakeholders
  4. Documentar todo - Para post-mortem
  5. Practicar procedimientos de emergencia - No esperar a incidente real
  6. Tener respaldos listos - Probarlos regularmente
  7. Conocer tu ruta de escalación - Cuándo pedir ayuda
  8. Post-mortem es obligatorio - Aprender y mejorar

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ RESPUESTA A EMERGENCIA DE CERTIFICADO                        │
├──────────────────────────────────────────────────────────────┤
│ CERT EXPIRADO:   ./emergency-self-signed-cert.sh $(hostname) │
│ ARCHIVO FALTA:   ./emergency-restore-cert.sh <service>       │
│ PERMISOS:        ./emergency-fix-permissions.sh              │
│ PROB CONFIANZA:  ./emergency-fix-trust.sh /path/to/ca.crt    │
│ ROLLBACK:        ./emergency-rollback.sh                     │
│                                                              │
│ DESHAB SSL:      mv ssl.conf ssl.conf.disabled               │
│                  systemctl restart <service>                 │
│                                                              │
│ VER EXPIRACIÓN:  openssl x509 -in cert.crt -noout -dates     │
│ LOGS SERVICIO:   journalctl -xe -u <service>                 │
└──────────────────────────────────────────────────────────────┘

⚠️ RECORDAR: ¡Corregir primero, investigar después!

🧪 Laboratorio Práctico

Lab 16: Procedimientos de Emergencia

Aprenda técnicas rápidas de recuperación de certificados para emergencias en producción

  • 📁 Ubicación: labs/es_ES/16-emergency-procedures/
  • ⏱️ Tiempo: 30-40 minutos
  • 🎯 Nivel: Avanzado

Navegación del Capítulo

Capítulo 34: Planificación y Preparación de Migración RHEL

Planificar para el Éxito: Las migraciones de RHEL requieren planificación cuidadosa de certificados. Aprende cómo auditar, preparar y planificar la migración de certificados para evitar interrupciones.


34.1 Por Qué Importa la Planificación de Certificados

Sin Planificación:

❌ Actualizar RHEL → Los certificados fallan validación
❌ Los servicios no inician
❌ Interrupción de producción
❌ Rollback requerido
❌ Migración fallida

Con Planificación:

✅ Pre-auditoría identifica problemas
✅ Certificados preparados con anticipación
✅ Migración de prueba exitosa
✅ Migración de producción suave
✅ Sin interrupciones relacionadas con certificados

34.2 Auditoría de Certificados Pre-Migración

Inventario Completo de Certificados

#!/bin/bash
# pre-migration-cert-audit.sh
# Auditoría completa de certificados antes de migración RHEL

echo "=== Auditoría de Certificados Pre-Migración ==="
echo "Sistema: $(hostname)"
echo "RHEL Actual: $(cat /etc/redhat-release)"
echo "Fecha: $(date)"
echo ""

# Encontrar todos los certificados
echo "=== Inventario de Certificados ==="
find /etc/pki/tls/certs/ /etc/httpd/ /etc/nginx/ /etc/postfix/ /etc/openldap/ \
  -name "*.crt" -o -name "*.pem" 2>/dev/null | \
  while read cert; do
    if openssl x509 -in "$cert" -noout 2>/dev/null; then
      echo "Certificado: $cert"
      echo "  Sujeto: $(openssl x509 -in "$cert" -noout -subject)"
      echo "  Emisor: $(openssl x509 -in "$cert" -noout -issuer)"
      echo "  Expira: $(openssl x509 -in "$cert" -noout -enddate | cut -d= -f2)"

      # Verificar algoritmo de firma
      SIG_ALG=$(openssl x509 -in "$cert" -noout -text | grep "Signature Algorithm" | head -2)
      echo "  Firma: $SIG_ALG"

      # Verificar tamaño de clave
      KEY_SIZE=$(openssl x509 -in "$cert" -noout -text | grep "Public-Key" | grep -oP '\d+')
      echo "  Tamaño Clave: $KEY_SIZE bits"

      # Marcar problemas
      if echo "$SIG_ALG" | grep -qi "sha1"; then
        echo "  ⚠️ ADVERTENCIA: Firma SHA-1 (fallará en RHEL 9+)"
      fi

      if [ "$KEY_SIZE" -lt 2048 ]; then
        echo "  ⚠️ ADVERTENCIA: Clave < 2048 bits (puede fallar en RHEL 8+)"
      fi

      if ! openssl x509 -in "$cert" -noout -ext subjectAltName 2>/dev/null | grep -q "DNS:"; then
        echo "  ⚠️ ADVERTENCIA: Certificato no tiene SAN"
      fi

      # Verificar expiración
      if ! openssl x509 -in "$cert" -noout -checkend $((86400*90)); then
        echo "  ⚠️ ADVERTENCIA: Expira dentro de 90 días"
      fi

      echo ""
    fi
  done

# Rastreo de certmonger
echo "=== Certificados Rastreados por certmonger ==="
if command -v getcert &>/dev/null; then
  sudo getcert list | grep -E "(Request ID|certificate:|status:)"
else
  echo "certmonger no instalado"
fi

# CAs personalizadas
echo ""
echo "=== CAs Personalizadas en Almacén de Confianza ==="
ls -la /etc/pki/ca-trust/source/anchors/

# Configuraciones de servicios
echo ""
echo "=== Configuraciones de Certificados de Servicio ==="
echo "Apache:"
grep -h "SSLCertificate" /etc/httpd/conf.d/*.conf 2>/dev/null | grep -v "^#"

echo ""
echo "NGINX:"
grep -rh "ssl_certificate" /etc/nginx/ 2>/dev/null | grep -v "^#"

echo ""
echo "Postfix:"
sudo postconf | grep -E "smtpd_tls_cert|smtp_tls_cert"

echo ""
echo "=== Auditoría Completa ==="
echo "¡Guarda esta salida para referencia de migración!"

34.3 Problemas de Certificados a Corregir Antes de Migración

Correcciones Críticas Pre-Migración

Corrección 1: Firmas SHA-1 (RHEL 8→9)

# Encontrar certificados firmados con SHA-1
for cert in /etc/pki/tls/certs/*.crt; do
  if openssl x509 -in "$cert" -noout -text 2>/dev/null | \
     grep -qi "Signature Algorithm.*sha1"; then
    echo "⚠️ SHA-1: $cert"
  fi
done

# Acción: Reemitir TODOS los certificados SHA-1 antes de migrar a RHEL 9

Corrección 2: Claves Pequeñas (< 2048 bits)

# Encontrar claves pequeñas
for cert in /etc/pki/tls/certs/*.crt; do
  SIZE=$(openssl x509 -in "$cert" -noout -text 2>/dev/null | \
         grep "Public-Key" | grep -oP '\d+')
  if [ "$SIZE" -lt 2048 ] 2>/dev/null; then
    echo "⚠️ Clave pequeña ($SIZE): $cert"
  fi
done

# Acción: Reemitir con claves de 2048+ bits

Corrección 3: SANs Faltantes

# Encontrar certificados sin SANs
for cert in /etc/pki/tls/certs/*.crt; do
  if ! openssl x509 -in "$cert" -noout -ext subjectAltName 2>/dev/null | grep -q "DNS:"; then
    echo "⚠️ Sin SANs: $cert"
  fi
done

# Acción: Reemitir con SANs apropiados (requerido para navegadores modernos)

Corrección 4: Expirando Pronto

# Encontrar certificados expirando dentro de ventana de migración
for cert in /etc/pki/tls/certs/*.crt; do
  if ! openssl x509 -in "$cert" -noout -checkend $((86400*90)) 2>/dev/null; then
    echo "⚠️ Expirando pronto: $cert"
    openssl x509 -in "$cert" -noout -enddate
  fi
done

# Acción: Renovar antes de migración para evitar expiración durante migración

34.4 Estrategia de Respaldo

Qué Respaldar

#============================================#
# RESPALDO DE CERTIFICADOS PRE-MIGRACIÓN
#============================================#

BACKUP_DIR="/var/backups/pre-migration-$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"

# Respaldar certificados y claves
sudo tar czf "$BACKUP_DIR/certificates.tar.gz" \
  /etc/pki/tls/ \
  /etc/pki/ca-trust/source/anchors/ \
  /etc/pki/nssdb/

# Respaldar configuraciones de servicio
sudo tar czf "$BACKUP_DIR/service-configs.tar.gz" \
  /etc/httpd/conf.d/*.conf \
  /etc/nginx/nginx.conf \
  /etc/nginx/conf.d/ \
  /etc/postfix/main.cf \
  /etc/openldap/ \
  /var/lib/pgsql/data/postgresql.conf \
  /var/lib/pgsql/data/pg_hba.conf \
  2>/dev/null

# Respaldar base de datos certmonger
sudo tar czf "$BACKUP_DIR/certmonger.tar.gz" \
  /var/lib/certmonger/

# Guardar lista de certmonger
sudo getcert list > "$BACKUP_DIR/certmonger-list.txt" 2>/dev/null

# Guardar crypto-policy (RHEL 8+)
update-crypto-policies --show > "$BACKUP_DIR/crypto-policy.txt" 2>/dev/null

# Crear CSV de inventario
./pre-migration-cert-audit.sh > "$BACKUP_DIR/certificate-inventory.txt"

# Establecer permisos
sudo chmod 700 "$BACKUP_DIR"

echo "✅ Respaldo completo: $BACKUP_DIR"
ls -lh "$BACKUP_DIR"

34.5 Plan de Pruebas

Configuración de Entorno de Prueba

## Lista de Verificación de Pruebas de Migración

### Entorno de Prueba
- [ ] Clonar producción a VM/contenedor de prueba
- [ ] Misma versión RHEL que producción
- [ ] Mismos certificados (copias, ¡no originales!)
- [ ] Mismas configuraciones de servicio
- [ ] Red aislada de producción

### Migración de Prueba
- [ ] Ejecutar migración en sistema de prueba
- [ ] Verificar que todos los servicios inicien
- [ ] Probar validación de certificado
- [ ] Verificar crypto-policy (RHEL 7→8/9)
- [ ] Probar conexiones de cliente
- [ ] Verificar rastreo de certmonger (si se usa)
- [ ] Documentar cualquier problema

### Solución de Problemas
- [ ] Corregir problemas encontrados en prueba
- [ ] Actualizar plan de migración
- [ ] Re-probar
- [ ] Documentar soluciones alternativas

### Preparación para Producción
- [ ] Migración de prueba exitosa
- [ ] Problemas documentados y resueltos
- [ ] Plan de rollback listo
- [ ] Equipo capacitado
- [ ] Ventana de mantenimiento programada

34.6 Cronología de Migración

Calendario de Migración de Ejemplo

Semana 1-2: Planificación y Auditoría
├─ Completar inventario de certificados
├─ Identificar problemas (SHA-1, claves pequeñas, etc.)
├─ Planificar remediación
└─ Configurar entorno de prueba

Semana 3-4: Remediación
├─ Reemitir certificados problemáticos
├─ Actualizar configuraciones
├─ Probar en entorno actual
└─ Verificar que automatización funciona

Semana 5-6: Pruebas
├─ Clonar producción a prueba
├─ Realizar migración de prueba
├─ Validar certificados post-migración
├─ Documentar problemas y soluciones
└─ Actualizar runbook de migración

Semana 7: Preparación Pre-Migración
├─ Auditoría final de certificados
├─ Renovar certificados expirando
├─ Completar respaldos
├─ Briefing al equipo
└─ Verificar plan de rollback

Semana 8: Migración
├─ Ventana de mantenimiento
├─ Ejecutar migración
├─ Validar certificados
├─ Monitorear por 24-48 horas
└─ Documentar lecciones aprendidas

34.7 Planificación de Rollback

Procedimiento de Rollback de Certificados

#============================================#
# PLAN DE ROLLBACK DE CERTIFICADOS
#============================================#

# Si la migración falla debido a problemas de certificados:

# Paso 1: Rollback de RHEL (usando leapp o snapshots)
# Ver documentación de migración RHEL

# Paso 2: Restaurar certificados (si es necesario)
sudo tar xzf /var/backups/pre-migration-YYYYMMDD/certificates.tar.gz -C /

# Paso 3: Restaurar configuraciones de servicio
sudo tar xzf /var/backups/pre-migration-YYYYMMDD/service-configs.tar.gz -C /

# Paso 4: Restaurar certmonger
sudo tar xzf /var/backups/pre-migration-YYYYMMDD/certmonger.tar.gz -C /

# Paso 5: Reiniciar servicios
sudo systemctl restart httpd nginx postfix slapd

# Paso 6: Verificar
curl -v https://localhost/
sudo getcert list

34.8 Plan de Comunicación

Plantilla de Comunicación a Stakeholders

## Migración RHEL - Evaluación de Impacto en Certificados

### Detalles de Migración
- **De:** RHEL X.Y
- **A:** RHEL X.Y
- **Fecha:** YYYY-MM-DD
- **Ventana:** XX:00 - XX:00 UTC

### Análisis de Impacto en Certificados
- **Total Certificados:** XX
- **Certificados Requiriendo Acción:** XX
- **Servicios Afectados:** Apache, NGINX, Postfix, LDAP, etc.

### Acciones Pre-Migración Requeridas
- [ ] Reemitir XX certificados SHA-1
- [ ] Renovar XX certificados expirando
- [ ] Actualizar XX configuraciones de servicio
- [ ] Probar compatibilidad crypto-policy (RHEL 8+)

### Durante la Migración
- **Tiempo de Inactividad Esperado:** X horas
- **Validación de Certificados:** Post-migración
- **Plan de Rollback:** Disponible si es necesario

### Validación Post-Migración
- [ ] Todos los servicios inician exitosamente
- [ ] Validación de certificado funcionando
- [ ] crypto-policy aplicada (RHEL 8+)
- [ ] Rastreo de certmonger mantenido
- [ ] Conexiones de cliente exitosas

### Mitigación de Riesgos
- Respaldos completos completados
- Migración de prueba exitosa
- Procedimiento de rollback documentado
- Equipo en espera

### Contacto
- **Líder de Migración:** Nombre <email>
- **Escalación:** Gerente <email>

34.9 Lista de Verificación de Migración

Lista de Verificación Completa Pre-Migración

## Lista de Verificación Preparación para Migración de Certificados

### Auditoría e Inventario (Semana 1-3)
- [ ] Inventario completo de certificados
- [ ] Documentar todas las ubicaciones de certificados
- [ ] Identificar todos los servicios usando certificados
- [ ] Mapear dependencias de certificado a servicio
- [ ] Documentar CAs personalizadas en uso

### Identificación de Problemas (Semana 2-4)
- [ ] Identificar certificados firmados con SHA-1
- [ ] Identificar claves pequeñas (< 2048 bits)
- [ ] Identificar certificados sin SANs
- [ ] Identificar certificados expirando (< 180 días)
- [ ] Identificar configs TLS codificadas (vs crypto-policy)

### Remediación (Semana 3-6)
- [ ] Reemitir todos los certificados SHA-1
- [ ] Reemitir certificados de clave pequeña
- [ ] Agregar SANs a todos los certificados
- [ ] Renovar certificados expirando
- [ ] Eliminar configs TLS codificadas (preparar para crypto-policy)

### Pruebas (Semana 5-7)
- [ ] Configurar entorno de prueba
- [ ] Clonar certificados de producción a prueba
- [ ] Realizar migración de prueba
- [ ] Validar que todos los servicios inicien
- [ ] Probar conexiones de cliente
- [ ] Probar crypto-policy (RHEL 7→8/9)
- [ ] Documentar problemas encontrados
- [ ] Resolver problemas en prueba
- [ ] Re-probar hasta limpio

### Respaldo (Semana 7)
- [ ] Respaldo completo del sistema
- [ ] Respaldo específico de certificados
- [ ] Respaldo de configuración de servicio
- [ ] Respaldo de base de datos certmonger
- [ ] Probar procedimiento de restauración

### Documentación (Semana 7)
- [ ] Runbook de migración completo
- [ ] Procedimiento de rollback documentado
- [ ] Soluciones alternativas de problemas documentadas
- [ ] Equipo briefing realizado
- [ ] Stakeholders notificados

### Preparación Final (Día anterior)
- [ ] Verificar respaldos
- [ ] Verificar entorno de prueba
- [ ] Revisar runbook
- [ ] Confirmar ventana de mantenimiento
- [ ] Roles del equipo asignados

34.10 Conclusiones Clave

  1. Planificar con anticipación - Comenzar 6-8 semanas antes de migración
  2. Auditar exhaustivamente - Conocer cada certificado
  3. Corregir problemas temprano - No esperar hasta el día de migración
  4. Probar extensivamente - Múltiples ejecuciones de prueba
  5. Respaldar todo - Certificados, configuraciones, DB certmonger
  6. Documentar claramente - Runbook, rollback, problemas
  7. Comunicar proactivamente - Mantener informados a stakeholders

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA PLANIFICACIÓN DE MIGRACIÓN                 │
├──────────────────────────────────────────────────────────────┤
│ Cronología:    6-8 semanas antes de migración                │
│                                                              │
│ Pre-auditoría: Encontrar todos los certificados              │
│                Verificar firmas (SHA-1 → SHA-256)            │
│                Verificar tamaños clave (< 2048 → 2048+)      │
│                Verificar SANs (faltantes → agregar)          │
│                Verificar expiración (< 180 días → renovar)   │
│                                                              │
│ Respaldo:      tar czf certs.tar.gz /etc/pki/tls/            │
│                getcert list > certmonger-list.txt            │
│                update-crypto-policies --show > policy.txt    │
│                                                              │
│ Probar:        Clonar a entorno de prueba                    │
│                Realizar migración de prueba                  │
│                Validar que certificados funcionan            │
│                Documentar y corregir problemas               │
└──────────────────────────────────────────────────────────────┘

⚠️ Certificados SHA-1 FALLARÁN en RHEL 9+
⚠️ crypto-policies introducidas en RHEL 8
✅ Probar múltiples veces antes de producción

Navegación del Capítulo

Capítulo 35: Migración RHEL 7→8

Gran Salto: Migrar de RHEL 7 a RHEL 8 introduce crypto-policies - un cambio revolucionario en la gestión de certificados. ¡Planifica cuidadosamente!


35.1 Impacto en Certificados: MODERADO-ALTO

Qué Cambia

CaracterísticaRHEL 7RHEL 8Impacto
OpenSSL1.0.2k1.1.1kModerado
Versiones TLS1.0/1.1/1.21.2/1.3 (DEFAULT)ALTO
Crypto-PoliciesNinguna¡NUEVO!ALTO
Cifrados PredeterminadosMixtosMás EstrictosModerado
certmongerBásicoMejoradoBajo
GestiónManualAutomatizada (crypto-policies)ALTO

Cambio Clave: ¡crypto-policies revolucionan la gestión TLS!


35.2 Preparación Pre-Migración

Tareas Específicas de Certificados Pre-Migración

#============================================#
# PREPARACIÓN DE CERTIFICADOS RHEL 7→8
#============================================#

# Tarea 1: Auditar todos los certificados (ver Cap 34)
./pre-migration-cert-audit.sh > rhel7-cert-audit.txt

# Tarea 2: Verificar dependencias TLS 1.0/1.1
# Revisar configuraciones de servicio
grep -r "TLSv1\|TLSv1.1" /etc/httpd/ /etc/nginx/ /etc/postfix/

# Tarea 3: Identificar configuraciones manuales de cifrado
# ¡Estas serán sobrescritas por crypto-policies!
grep -r "SSLCipherSuite\|ssl_ciphers\|smtp.*ciphers" /etc/httpd/ /etc/nginx/ /etc/postfix/

# Tarea 4: Probar compatibilidad TLS 1.2
# Asegurar que todos los clientes soporten TLS 1.2+

# Tarea 5: Respaldar todo
sudo tar czf rhel7-complete-backup-$(date +%Y%m%d).tar.gz \
  /etc/pki/ \
  /etc/httpd/ \
  /etc/nginx/ \
  /etc/postfix/ \
  /var/lib/certmonger/

35.3 Migración Usando leapp

La Utilidad leapp

IMPORTANTE: Usa leapp para migración RHEL 7→8 (¡NO redhat-upgrade-tool!)

leapp es la utilidad de actualización soportada de Red Hat para RHEL 7→8 y 8→9.

#============================================#
# MIGRACIÓN RHEL 7→8 CON LEAPP
#============================================#

# Prerrequisitos
# - RHEL 7.9 (última versión)
# - Suscripción Red Hat válida
# - Todas las actualizaciones aplicadas
# - Respaldos completos

# Paso 1: Actualizar RHEL 7 a última versión
sudo yum update -y
sudo reboot

# Paso 2: Instalar leapp
sudo yum install leapp-upgrade -y

# Paso 3: Ejecutar verificación pre-actualización
sudo leapp preupgrade

# Revisar reporte:
cat /var/log/leapp/leapp-report.txt

# Inhibidores comunes relacionados con certificados:
# - Certificados SHA-1
# - Configuraciones de cifrado débiles
# - Paquetes no soportados

# Paso 4: Corregir problemas identificados
# Reemitir certificados SHA-1
# Actualizar configuraciones

# Paso 5: Realizar actualización
sudo leapp upgrade

# El sistema descarga RHEL 8, prepara actualización
# Reinicia automáticamente

# Paso 6: Después de reiniciar, ¡el sistema es RHEL 8!
cat /etc/redhat-release
# Red Hat Enterprise Linux release 8.X (Ootpa)

35.4 Validación de Certificados Post-Migración

Verificaciones Inmediatas Post-Migración

#============================================#
# VALIDACIÓN DE CERTIFICADOS POST-MIGRACIÓN
#============================================#

# Verificación 1: Verificar RHEL 8
cat /etc/redhat-release
openssl version
# Debería mostrar: OpenSSL 1.1.1k

# Verificación 2: Verificar crypto-policy
update-crypto-policies --show
# DEFAULT (debería establecerse automáticamente)

# Verificación 3: Verificar que archivos de certificado aún estén presentes
ls -la /etc/pki/tls/certs/
ls -la /etc/pki/tls/private/

# Verificación 4: Verificar permisos sin cambios
ls -l /etc/pki/tls/private/*.key
# Aún debería ser 600

# Verificación 5: Verificar CAs personalizadas
ls -la /etc/pki/ca-trust/source/anchors/

# Verificación 6: Actualizar almacén de confianza (por si acaso)
sudo update-ca-trust

# Verificación 7: Verificar rastreo de certmonger
sudo getcert list
# Todos los certificados aún deberían estar rastreados

# Verificación 8: Verificar configuraciones de servicio
# crypto-policies pueden haberlas actualizado
cat /etc/crypto-policies/back-ends/httpd.config

35.5 Reinicio y Prueba de Servicios

Reiniciar Todos los Servicios

#============================================#
# REINICIAR SERVICIOS DESPUÉS DE MIGRACIÓN
#============================================#

# Reiniciar servicios que usan certificados
sudo systemctl restart httpd
sudo systemctl restart nginx
sudo systemctl restart postfix
sudo systemctl restart slapd
sudo systemctl restart postgresql
sudo systemctl restart mariadb

# Verificar estado de servicios
systemctl status httpd nginx postfix | grep "Active:"

# Probar cada servicio
curl -v https://localhost/                             # Apache/NGINX
openssl s_client -connect localhost:443                # HTTPS
openssl s_client -starttls smtp -connect localhost:25  # Postfix
openssl s_client -connect localhost:636                # LDAPS

35.6 Problemas Comunes de Certificados RHEL 7→8

Problema 1: Clientes TLS 1.0/1.1 No Pueden Conectar

Síntoma: Clientes antiguos fallan después de migración

Causa: Crypto-policy DEFAULT bloquea TLS 1.0/1.1

Solución Rápida (Temporal):

sudo update-crypto-policies --set LEGACY
sudo systemctl restart httpd nginx postfix

Solución Apropiada:

# Actualizar clientes para soportar TLS 1.2+
# O crear módulo de política personalizado

Problema 2: Cifrados Codificados Conflictúan con crypto-policy

Síntoma: El servicio no inicia o se comporta inesperadamente

Causa: Configuración antigua tiene SSLCipherSuite que conflictúa

Solución:

# Eliminar configuraciones de cifrado codificadas
# Dejar que crypto-policy lo maneje

# Apache: Eliminar de ssl.conf
# SSLProtocol ...
# SSLCipherSuite ...

# NGINX: Eliminar de nginx.conf
# ssl_protocols ...
# ssl_ciphers ...

# Postfix: Eliminar de main.cf
# smtpd_tls_protocols ...
# smtpd_tls_mandatory_ciphers ...

Problema 3: Rastreo de certmonger Perdido

Síntoma: getcert list muestra vacío o certificados faltantes

Raro pero posible si la migración tuvo problemas

Solución:

# Restaurar base de datos certmonger desde respaldo
sudo systemctl stop certmonger
sudo tar xzf /var/backups/pre-migration-*/certmonger.tar.gz -C /
sudo systemctl start certmonger

# Verificar
sudo getcert list

35.7 Transición de Crypto-Policy

Adoptar Crypto-Policies

RHEL 7: Sin crypto-policies, configuración manual por servicio RHEL 8: crypto-policies gestionan TLS en todo el sistema

#============================================#
# TRANSICIÓN A CRYPTO-POLICIES
#============================================#

# Después de migración a RHEL 8:

# Paso 1: Verificar política actual
update-crypto-policies --show
# DEFAULT

# Paso 2: Eliminar configuraciones TLS manuales de servicios
# (Dejar que crypto-policy lo maneje)

# Paso 3: Probar con política DEFAULT
sudo systemctl restart httpd nginx postfix

# Paso 4: Si clientes antiguos necesitan TLS 1.0/1.1 (¡temporal!)
sudo update-crypto-policies --set LEGACY

# Paso 5: Planificar volver a DEFAULT
# Actualizar clientes, luego:
sudo update-crypto-policies --set DEFAULT

35.8 Ejemplo de Runbook de Migración

Ejecución Paso a Paso

## Runbook Migración RHEL 7→8 - Sección Certificados

### Pre-Migración (T-24 horas)
- [ ] Verificar respaldos completos y probados
- [ ] Verificar todos los certificados válidos > 90 días
- [ ] Sin certificados SHA-1 restantes
- [ ] Migración de entorno de prueba exitosa

### Inicio de Ventana de Migración (T=0)
- [ ] Anunciar ventana de mantenimiento
- [ ] Tomar respaldo final
- [ ] Ejecutar: `sudo leapp upgrade`
- [ ] El sistema reinicia automáticamente

### Post-Reinicio (T+30 min)
- [ ] Verificar RHEL 8: `cat /etc/redhat-release`
- [ ] Verificar crypto-policy: `update-crypto-policies --show`
- [ ] Verificar certificados presentes: `ls /etc/pki/tls/certs/`
- [ ] Verificar certmonger: `sudo getcert list`

### Validación de Servicios (T+45 min)
- [ ] Reiniciar todos los servicios
- [ ] Probar Apache: `curl -v https://localhost/`
- [ ] Probar NGINX: `curl -v https://localhost:8443/`
- [ ] Probar Postfix: `openssl s_client -starttls smtp -connect localhost:25`
- [ ] Probar LDAP: `ldapsearch -H ldaps://localhost:636 -x -b ""`
- [ ] Probar bases de datos (si aplica)

### Pruebas de Cliente (T+60 min)
- [ ] Probar desde clientes Windows
- [ ] Probar desde clientes Linux
- [ ] Probar desde clientes de aplicación
- [ ] Verificar que no haya errores TLS

### Monitoreo (T+2 horas a T+48 horas)
- [ ] Monitorear logs para errores de certificados
- [ ] Monitorear salud de servicios
- [ ] Verificar renovaciones de certmonger
- [ ] Verificar que no haya problemas de crypto-policy

### Finalización
- [ ] Documentar cualquier problema encontrado
- [ ] Actualizar runbook con lecciones aprendidas
- [ ] Cerrar ventana de mantenimiento
- [ ] Notificar a stakeholders de migración exitosa

35.9 Conclusiones Clave

  1. Usar utilidad leapp para migración RHEL 7→8 (método soportado)
  2. crypto-policies son NUEVAS en RHEL 8 - ¡Cambio mayor!
  3. TLS 1.0/1.1 deshabilitado por defecto - Probar compatibilidad de cliente
  4. Eliminar configuraciones TLS manuales - Dejar que crypto-policy gestione
  5. Probar extensivamente antes de migración de producción
  6. Política LEGACY disponible para compatibilidad (¡temporal!)
  7. Rastreo de certmonger debería sobrevivir migración

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────────────┐
│ LISTA DE VERIFICACIÓN CERTIFICADOS MIGRACIÓN RHEL 7→8                │
├──────────────────────────────────────────────────────────────────────┤
│ Antes:                 Auditar todos los certificados                │
│                        Reemitir certificados SHA-1                   │
│                        Probar compatibilidad TLS 1.2                 │
│                        Respaldar todo                                │
│                                                                      │
│ Migración:             Usar leapp upgrade (¡NO redhat-upgrade-tool!) │
│                        El sistema reinicia automáticamente           │
│                                                                      │
│ Después:               Verificar RHEL 8                              │
│                        Verificar crypto-policy (DEFAULT)             │
│                        Reiniciar todos los servicios                 │
│                        Probar conexiones de cliente                  │
│                        Monitorear por 48 horas                       │
│                                                                      │
│ Nueva Característica:  crypto-policies (control TLS sistema)         │
│ Bloqueado:             TLS 1.0/1.1 (en política DEFAULT)             │
│ Fallback:              Política LEGACY (si necesario, ¡temporal!)    │
└──────────────────────────────────────────────────────────────────────┘

✅ Usar leapp (oficialmente soportado)
⚠️ Cambio mayor: crypto-policies introducidas
⚠️ Probar soporte TLS 1.2 de cliente antes de migración

🧪 Laboratorio Práctico

Lab 17: Migración RHEL 7→8

Migre certificados durante actualización del SO a RHEL 8

  • 📁 Ubicación: labs/es_ES/17-rhel7to8-migration/
  • ⏱️ Tiempo: 40-50 minutos
  • 🎯 Nivel: Avanzado

Navegación del Capítulo

Capítulo 36: Migración RHEL 8→9

Transición OpenSSL 3.x: RHEL 8→9 trae OpenSSL 3.x con arquitectura de proveedores y validación más estricta. ¡Planifica cuidadosamente este cambio significativo!


36.1 Impacto en Certificados: ALTO

Qué Cambia

CaracterísticaRHEL 8RHEL 9Impacto
OpenSSL1.1.1k3.5.5ALTO
ArquitecturaTradicionalBasada en proveedoresALTO
TLS 1.0/1.1Política LEGACYCompletamente eliminadoALTO
SHA-1ObsoletoBloqueadoALTO
ValidaciónEstándarMás EstrictaModerado
Crypto-PoliciesBásicasSubpolíticasBajo
certmongerMejoradoSoporte ACMEBajo

Cambio Clave: ¡OpenSSL 3.x es un cambio arquitectónico mayor!


36.2 Requisitos Pre-Migración

Correcciones Críticas de Certificados

Requisito 1: NO Firmas SHA-1

#============================================#
# VERIFICAR SHA-1 (¡FALLARÁ EN RHEL 9!)
#============================================#

# Encontrar certificados firmados con SHA-1
for cert in /etc/pki/tls/certs/*.crt; do
  SIG=$(openssl x509 -in "$cert" -noout -text 2>/dev/null | \
        grep "Signature Algorithm" | head -2)
  if echo "$SIG" | grep -qi "sha1"; then
    echo "🚨 CRÍTICO: Firma SHA-1: $cert"
    echo "   $SIG"
    echo "   ⚠️ ¡DEBE reemitirse antes de migración a RHEL 9!"
  fi
done

# Acción: Reemitir TODOS los certificados SHA-1 antes de migración
# Sin excepciones - FALLARÁN en RHEL 9

Requisito 2: Todos los Certificados Válidos

# Asegurar que no haya certificados expirados
for cert in /etc/pki/tls/certs/*.crt; do
  if ! openssl x509 -in "$cert" -noout -checkend 0 2>/dev/null; then
    echo "❌ Expirado: $cert"
  fi
done

Requisito 3: Probar Aplicaciones Personalizadas

# Si tienes aplicaciones personalizadas usando OpenSSL
# Pueden necesitar actualizaciones para API de OpenSSL 3.x
rpm -qa | grep -E "custom|local"

# Probar estas aplicaciones en entorno RHEL 9 antes de migración

36.3 Migración Usando leapp

Proceso de Actualización RHEL 8→9

#============================================#
# MIGRACIÓN RHEL 8→9 CON LEAPP
#============================================#

# Prerrequisitos
# - RHEL 8.10 (última versión recomendada)
# - Suscripción válida
# - Todas las actualizaciones aplicadas
# - Respaldos completos
# - ¡Certificados SHA-1 reemitidos!

# Paso 1: Actualizar RHEL 8 completamente
sudo dnf update -y
sudo reboot

# Paso 2: Instalar leapp
sudo dnf install leapp-upgrade -y

# Paso 3: Ejecutar verificación pre-actualización
sudo leapp preupgrade

# Revisar reporte
cat /var/log/leapp/leapp-report.txt

# Verificaciones relacionadas con certificados:
# - Advertencias de certificados SHA-1
# - Compatibilidad OpenSSL
# - Compatibilidad de app personalizada

# Paso 4: Abordar inhibidores
# Corregir cualquier problema bloqueante

# Paso 5: Realizar actualización
sudo leapp upgrade

# Descarga RHEL 9, prepara actualización
# Reinicia para realizar actualización
# Reinicia nuevamente en RHEL 9

# Paso 6: Verificar RHEL 9
cat /etc/redhat-release
# Red Hat Enterprise Linux release 9.X (Plow)

openssl version
# OpenSSL 3.5.5

36.4 Validación Post-Migración

Validación Específica de Certificados

#============================================#
# VALIDACIÓN DE CERTIFICADOS POST-MIGRACIÓN (RHEL 9)
#============================================#

# Verificación 1: Versión de OpenSSL
openssl version
# OpenSSL 3.5.5  ← Confirmar

# Verificación 2: Verificar proveedores
openssl list -providers
# Debería mostrar: default, fips, legacy, base

# Verificación 3: Verificar que certificados aún estén presentes
ls -la /etc/pki/tls/certs/
ls -la /etc/pki/tls/private/

# Verificación 4: Probar validación de certificado
for cert in /etc/pki/tls/certs/*.crt; do
  openssl verify "$cert" 2>&1 | grep -v "OK" && echo "Problema: $cert"
done

# Verificación 5: Verificar crypto-policy
update-crypto-policies --show
# DEFAULT (debería mantenerse)

# Verificación 6: Probar operaciones de certificado
openssl x509 -in /etc/pki/tls/certs/server.crt -noout -text

# Verificación 7: Verificar rastreo de certmonger
sudo getcert list
# Todos los certificados aún deberían estar rastreados

# Verificación 8: Verificar almacén de confianza
trust list | head -20

36.5 Validación de Servicios

Probar Todos los Servicios

#============================================#
# VALIDACIÓN DE SERVICIOS POST-MIGRACIÓN
#============================================#

# Reiniciar servicios
sudo systemctl restart httpd nginx postfix slapd postgresql mariadb 2>/dev/null

# Probar cada servicio
echo "Probando Apache..."
curl -v https://localhost/ 2>&1 | grep -E "(SSL connection|subject:)"

echo "Probando con OpenSSL 3.x..."
openssl s_client -connect localhost:443 -tls1_3

echo "Probando Postfix..."
openssl s_client -starttls smtp -connect localhost:25 </dev/null

echo "Probando LDAPS..."
openssl s_client -connect localhost:636 </dev/null

# Verificar errores de proveedor
sudo journalctl --since "1 hour ago" | grep -i "provider\|unsupported"

36.6 Problemas Comunes RHEL 8→9

Problema 1: Certificados SHA-1 Rechazados

Síntoma:

openssl verify server.crt
# error 3 at 0 depth lookup: CA md too weak

Causa: El certificado tiene firma SHA-1 (bloqueada en RHEL 9)

Solución:

# SIN SOLUCIÓN ALTERNATIVA - Debe reemitirse
# ¡Esto debería haberse hecho pre-migración!

# Emergencia: Reemitir inmediatamente
openssl req -new -key server.key -out server.csr -sha256
# Enviar a CA, instalar nuevo certificado

Problema 2: Errores de Algoritmo Legacy

Síntoma:

openssl md5 file.txt
# Error: unsupported

Causa: MD5 y otros algoritmos legacy requieren proveedor explícito

Solución:

# Usar proveedor legacy
openssl md5 -provider legacy file.txt

# Mejor: Actualizar para usar SHA-256
openssl sha256 file.txt

Problema 3: Incompatibilidad OpenSSL 3.x en Aplicación Personalizada

Síntoma: La aplicación personalizada falla con errores OpenSSL

Causa: Aplicación compilada contra OpenSSL 1.1.1, API cambió en 3.x

Solución:

# Recompilar aplicación contra OpenSSL 3.x
# O actualizar código de aplicación para nueva API

# Solución alternativa temporal (si está disponible):
# Usar biblioteca compat (si se proporciona)

36.7 Consideraciones de crypto-policy

Crypto-Policy Después de Migración

#============================================#
# CRYPTO-POLICY POST-MIGRACIÓN
#============================================#

# Verificar política actual (debería mantenerse)
update-crypto-policies --show

# ¡RHEL 9 soporta subpolíticas!
# Ejemplo: Deshabilitar completamente SHA-1
sudo update-crypto-policies --set DEFAULT:NO-SHA1

# Listar módulos disponibles
ls /usr/share/crypto-policies/policies/modules/

# Probar política
sudo systemctl restart httpd
curl -v https://localhost/

36.8 certmonger Después de Migración

Verificar Funcionalidad de certmonger

#============================================#
# CERTMONGER POST-MIGRACIÓN
#============================================#

# Verificar estado de certmonger
systemctl status certmonger

# Listar certificados rastreados
sudo getcert list

# Verificar problemas
sudo getcert list | grep "status:" | grep -v "MONITORING"

# Si usas FreeIPA, probar conectividad
ipa ping

# Forzar prueba de renovación
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/test.crt

# RHEL 9 NUEVO: Soporte ACME disponible
# ¡Ahora puede usar certmonger con Let's Encrypt nativamente!

36.9 Runbook de Migración

Runbook Enfocado en Certificados

## Migración RHEL 8→9 - Sección Certificados

### Pre-Migración (T-24 horas)
- [ ] Verificar SIN certificados SHA-1 (¡crítico!)
- [ ] Todos los certificados válidos > 90 días
- [ ] Respaldos completos y probados
- [ ] Migración de prueba exitosa
- [ ] Apps personalizadas probadas en RHEL 9

### Inicio de Ventana de Migración (T=0)
- [ ] Respaldo final
- [ ] Ejecutar: `sudo leapp upgrade`
- [ ] Sistema reinicia (dos veces)

### Validación Post-Reinicio (T+45 min)
- [ ] Verificar RHEL 9: `cat /etc/redhat-release`
- [ ] Verificar OpenSSL 3.5.5: `openssl version`
- [ ] Verificar proveedores: `openssl list -providers`
- [ ] Verificar certificados: `ls /etc/pki/tls/certs/`
- [ ] Verificar crypto-policy: `update-crypto-policies --show`
- [ ] Verificar certmonger: `sudo getcert list`

### Reinicio de Servicios (T+60 min)
- [ ] Reiniciar todos los servicios que usan certificados
- [ ] Probar Apache/NGINX
- [ ] Probar Postfix
- [ ] Probar LDAP
- [ ] Probar bases de datos

### Validación de Certificados (T+90 min)
- [ ] Sin rechazos SHA-1
- [ ] Todos los certificados validan: `openssl verify`
- [ ] TLS 1.3 funcionando: `openssl s_client -tls1_3`
- [ ] Sin errores de proveedor en logs
- [ ] Estado certmonger todo MONITORING

### Pruebas de Cliente (T+2 horas)
- [ ] Probar desde todos los tipos de cliente
- [ ] Verificar que no haya problemas de compatibilidad
- [ ] Verificar funcionalidad de aplicación

### Post-Migración (24-48 horas)
- [ ] Monitorear problemas OpenSSL 3.x
- [ ] Verificar renovaciones de certmonger
- [ ] Monitorear logs de servicio
- [ ] Documentar cualquier problema

36.10 Conclusiones Clave

  1. OpenSSL 3.x es cambio mayor - La arquitectura de proveedores es nueva
  2. SHA-1 DEBE eliminarse antes de migración - ¡Sin excepciones!
  3. Usar leapp para migración (oficialmente soportado)
  4. Probar aplicaciones personalizadas en RHEL 9 primero
  5. Validación más estricta captura más problemas (¡bueno para seguridad!)
  6. certmonger gana soporte ACME en RHEL 9
  7. Subpolíticas disponibles para ajuste fino

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────────┐
│ LISTA DE VERIFICACIÓN CERTIFICADOS MIGRACIÓN RHEL 8→9            │
├──────────────────────────────────────────────────────────────────┤
│ CRÍTICO:    ¡SIN certificados SHA-1! (serán rechazados)          │
│             Reemitir todos los certs SHA-1 antes de migración    │
│                                                                  │
│ Antes:      Verificar SIN firmas SHA-1                           │
│             Probar apps personalizadas en RHEL 9                 │
│             Respaldar todo                                       │
│                                                                  │
│ Migración:  Usar leapp upgrade                                   │
│             El sistema reinicia dos veces                        │
│                                                                  │
│ Después:    Verificar OpenSSL 3.5.5                              │
│             Verificar proveedores: openssl list -providers       │
│             Probar algoritmos legacy necesitan -provider legacy  │
│             Reiniciar todos los servicios                        │
│             Verificar rastreo certmonger mantenido               │
│                                                                  │
│ Nuevo:      Arquitectura de proveedores                          │
│             Subpolíticas (DEFAULT:NO-SHA1)                       │
│             Soporte ACME de certmonger                           │
└──────────────────────────────────────────────────────────────────┘

🚨 SHA-1 está BLOQUEADO - ¡reemitir antes de migración!
✅ OpenSSL 3.x trae seguridad más estricta
✅ certmonger funciona con Let's Encrypt nativamente

🧪 Laboratorio Práctico

Lab 18: Migración RHEL 8→9

Maneje OpenSSL 3.x y seguridad más estricta en RHEL 9

  • 📁 Ubicación: labs/es_ES/18-rhel8to9-migration/
  • ⏱️ Tiempo: 40-50 minutos
  • 🎯 Nivel: Avanzado

Navegación del Capítulo

Capítulo 37: Solución de Problemas y Recuperación de Migración

Cuando las Cosas Salen Mal: Las migraciones no siempre van suavemente. Este capítulo cubre problemas comunes de migración y procedimientos de recuperación.


37.1 Problemas Comunes de Migración

Top 10 Problemas de Migración de Certificados

ProblemaSíntomasCausaSolución Rápida
1. Servicios no iniciansystemctl status fallaSintaxis config cambióRestaurar config, actualizar sintaxis
2. Rechazo SHA-1 (RHEL 9)“ca md too weak”Firma SHA-1Reemitir certificado
3. Desajuste versión TLSClientes no pueden conectarTLS 1.0/1.1 bloqueadoPolítica LEGACY (temp)
4. Problemas crypto-policyVarios erroresNuevo sistema de políticaEntender y configurar
5. certmonger perdió rastreogetcert list vacíoCorrupción DBRestaurar desde respaldo
6. CAs faltantesCert verify failedAlmacén confianza reiniciadoRe-agregar CAs
7. Cambios de permisosPermission deniedOwnership cambióCorregir permisos
8. Denegaciones SELinuxServicio bloqueadoContexto cambióReetiquetar archivos
9. Errores proveedor (RHEL 9)Algoritmo no soportadoCambio OpenSSL 3.xUsar -provider legacy
10. Degradación rendimientoConexiones lentasCrypto más estrictaEsperado, o ajustar

37.2 Procedimientos de Rollback

Cuándo Hacer Rollback

Hacer rollback si:

  • Los servicios críticos no pueden iniciar
  • Los problemas de certificados no pueden corregirse rápidamente
  • El impacto al negocio es severo
  • Dentro de ventana de rollback (usualmente 24-48 horas)

Rollback de leapp

#============================================#
# ROLLBACK MIGRACIÓN RHEL
#============================================#

# leapp crea snapshot durante actualización
# Rollback ANTES de reiniciar a nueva versión

# Durante actualización (si se detectan problemas):
# No reiniciar - investigar y corregir

# Después de actualización pero problemas encontrados:
# Verificar si dentro de ventana de rollback

# leapp no tiene rollback automático
# Usar snapshot/respaldo para restaurar

# Con snapshot LVM (si se creó pre-migración):
# Arrancar desde snapshot
# O restaurar desde respaldo

Rollback Específico de Certificados

#============================================#
# RESTAURAR CERTIFICADOS DESPUÉS DE MIGRACIÓN FALLIDA
#============================================#

# Escenario: Migrado, pero problemas de certificados
# Necesita restaurar estado de certificados

# Paso 1: Detener servicios
sudo systemctl stop httpd nginx postfix slapd

# Paso 2: Restaurar certificados
sudo tar xzf /var/backups/pre-migration-*/certificates.tar.gz -C /

# Paso 3: Restaurar configuraciones de servicio
sudo tar xzf /var/backups/pre-migration-*/service-configs.tar.gz -C /

# Paso 4: Restaurar certmonger
sudo systemctl stop certmonger
sudo tar xzf /var/backups/pre-migration-*/certmonger.tar.gz -C /
sudo systemctl start certmonger

# Paso 5: Restaurar crypto-policy (si RHEL 8+)
POLICY=$(cat /var/backups/pre-migration-*/crypto-policy.txt)
sudo update-crypto-policies --set $POLICY

# Paso 6: Iniciar servicios
sudo systemctl start httpd nginx postfix slapd

# Paso 7: Verificar
curl -v https://localhost/
sudo getcert list

37.3 El Servicio No Inicia Después de Migración

Diagnóstico

#============================================#
# SOLUCIÓN DE PROBLEMAS INICIO DE SERVICIO
#============================================#

# Verificar estado del servicio
systemctl status httpd

# Ver errores detallados
sudo journalctl -xe -u httpd

# Probar configuración
# Apache:
sudo apachectl configtest

# NGINX:
sudo nginx -t

# Postfix:
sudo postfix check

# Errores comunes relacionados con certificados:
# - Archivo no encontrado
# - Permission denied
# - Formato de certificado inválido
# - ca md too weak (SHA-1)

Soluciones

Problema: Sintaxis de Configuración Cambió

# Algunas directivas cambiaron entre versiones
# Verificar notas de lanzamiento para cambios

# Restaurar temporalmente configuración antigua
sudo cp /var/backups/pre-migration-*/ssl.conf /etc/httpd/conf.d/

# Actualizar a nueva sintaxis
# Investigar sintaxis correcta para nueva versión

Problema: Permisos Cambiaron Durante Migración

# Corregir permisos
sudo chmod 600 /etc/pki/tls/private/*.key
sudo chmod 644 /etc/pki/tls/certs/*.crt

# Corregir ownership
sudo chown root:root /etc/pki/tls/private/*.key

# Corregir contextos SELinux
sudo restorecon -Rv /etc/pki/tls/

37.4 Fallos de Conexión de Cliente Post-Migración

Incompatibilidad de Versión TLS

Síntoma: Los clientes no pueden conectar después de migración a RHEL 8/9

Diagnóstico:

# Probar desde servidor
openssl s_client -connect localhost:443 -tls1_2
# Funciona

openssl s_client -connect localhost:443 -tls1
# Falla (esperado en RHEL 8/9 DEFAULT)

# Verificar crypto-policy
update-crypto-policies --show
# DEFAULT  ← Bloquea TLS 1.0/1.1

Solución Temporal:

# Permitir TLS 1.0/1.1 temporalmente
sudo update-crypto-policies --set LEGACY
sudo systemctl restart httpd nginx postfix

# Probar clientes
# Documentar qué clientes necesitan TLS 1.0/1.1

# Planificar actualizar esos clientes, luego revertir a DEFAULT

Solución Apropiada:

# Actualizar clientes para soportar TLS 1.2+
# Luego usar política DEFAULT

sudo update-crypto-policies --set DEFAULT

37.5 Problemas de certmonger Post-Migración

Rastreo de certmonger Perdido

Síntoma:

sudo getcert list
# (vacío o certificados faltantes)

Solución:

# Restaurar base de datos certmonger
sudo systemctl stop certmonger
sudo tar xzf /var/backups/pre-migration-*/certmonger.tar.gz -C /
sudo systemctl start certmonger

# Verificar
sudo getcert list

# Si aún hay problemas, re-agregar certificados manualmente

certmonger CA_UNREACHABLE Después de Migración

Común después de actualización RHEL

Solución:

# Renovar ticket Kerberos
sudo kinit -k host/$(hostname -f)@REALM

# Reiniciar certmonger
sudo systemctl restart certmonger

# Reenviar solicitudes
for cert in $(sudo getcert list | grep "certificate:" | sed -n "s/.*location='\\([^']*\\)'.*/\\1/p"); do
  sudo ipa-getcert resubmit -f "$cert"
done

37.6 Procedimientos de Recuperación de Emergencia

Emergencia: Todos los Servicios Caídos

Situación: Migración completa pero nada funciona

Recuperación Rápida:

#!/bin/bash
# emergency-post-migration-recovery.sh

echo "=== EMERGENCIA: Recuperación de Certificados Post-Migración ==="

# 1. Verificar versión RHEL (confirmar que migración ocurrió)
cat /etc/redhat-release

# 2. Emergencia: Deshabilitar SSL temporalmente
# Apache
sudo mv /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.disabled
sudo systemctl start httpd
# Ahora Apache se ejecuta solo en HTTP (puerto 80)

# 3. Identificar problemas de certificados
sudo journalctl -xe | grep -i cert | tail -50

# 4. Para RHEL 9: Verificar rechazos SHA-1
grep "ca md too weak" /var/log/messages

# 5. Generar certificados autofirmados temporales
/usr/local/bin/emergency-self-signed-cert.sh $(hostname -f) 90

# 6. Re-habilitar SSL con cert temp
sudo mv /etc/httpd/conf.d/ssl.conf.disabled /etc/httpd/conf.d/ssl.conf
# Actualizar para usar cert temp
sudo systemctl restart httpd

# 7. Servicios restaurados (con advertencias)
# Planificar correcciones apropiadas de certificados

echo "✅ Recuperación de emergencia completa"
echo "⚠️ Usando certificados temporales - ¡corregir LO ANTES POSIBLE!"

37.7 Script de Validación Post-Migración

Validación Comprehensiva

#!/bin/bash
# post-migration-cert-validation.sh

echo "=== Validación de Certificados Post-Migración ==="

ISSUES=0

# Verificar versión RHEL
echo "1. Versión RHEL:"
cat /etc/redhat-release

# Verificar OpenSSL
echo ""
echo "2. Versión OpenSSL:"
openssl version

# Verificar crypto-policy (RHEL 8+)
if command -v update-crypto-policies &>/dev/null; then
  echo ""
  echo "3. Crypto-Policy:"
  update-crypto-policies --show
fi

# Verificar certificados
echo ""
echo "4. Estado de Certificados:"
CERT_COUNT=0
EXPIRED=0
for cert in /etc/pki/tls/certs/*.crt; do
  [ -f "$cert" ] || continue
  ((CERT_COUNT++))

  if ! openssl x509 -in "$cert" -noout -checkend 0 2>/dev/null; then
    echo "  ❌ EXPIRADO: $cert"
    ((EXPIRED++))
    ((ISSUES++))
  fi

  # Verificar SHA-1 (RHEL 9)
  if [ "$(cat /etc/redhat-release)" =~ "release 9" ]; then
    if openssl x509 -in "$cert" -noout -text | grep -qi "sha1.*Signature"; then
      echo "  ❌ SHA-1: $cert"
      ((ISSUES++))
    fi
  fi
done

echo "  Total certificados: $CERT_COUNT"
echo "  Expirados: $EXPIRED"

# Verificar certmonger
echo ""
echo "5. Estado de certmonger:"
if command -v getcert &>/dev/null; then
  sudo getcert list | grep "status:" | sort | uniq -c

  UNREACHABLE=$(sudo getcert list | grep -c "CA_UNREACHABLE")
  if [ $UNREACHABLE -gt 0 ]; then
    echo "  ⚠️ $UNREACHABLE certificados CA_UNREACHABLE"
    ((ISSUES++))
  fi
else
  echo "  certmonger no instalado"
fi

# Verificar servicios
echo ""
echo "6. Estado de Servicios:"
for svc in httpd nginx postfix slapd; do
  if systemctl is-active --quiet $svc 2>/dev/null; then
    echo "  ✅ $svc: ejecutándose"
  elif systemctl is-enabled --quiet $svc 2>/dev/null; then
    echo "  ❌ $svc: no ejecutándose (debería estar)"
    ((ISSUES++))
  fi
done

# Probar conexiones
echo ""
echo "7. Pruebas de Conexión:"
timeout 3 curl -ks https://localhost/ &>/dev/null && \
  echo "  ✅ HTTPS: OK" || echo "  ❌ HTTPS: FALLÓ"

# Resumen
echo ""
echo "==================================="
if [ $ISSUES -eq 0 ]; then
  echo "✅ ¡Validación de migración EXITOSA!"
  exit 0
else
  echo "⚠️ $ISSUES problemas encontrados - revisar arriba"
  exit 1
fi

37.8 Conclusiones Clave

  1. Tener plan de rollback listo antes de migración
  2. La mayoría de problemas son corregibles sin rollback
  3. Cambios de crypto-policy causan la mayoría de problemas de compatibilidad
  4. Rechazo SHA-1 no es negociable en RHEL 9
  5. Probar, probar, probar antes de migración de producción
  6. Documentar todo durante la solución de problemas
  7. Procedimientos de emergencia (Cap 33) aplican durante migración también

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA SOLUCIÓN DE PROBLEMAS DE MIGRACIÓN         │
├──────────────────────────────────────────────────────────────┤
│ Servicio falla:  Ver: journalctl -xe -u <service>            │
│                  Intentar: Restaurar config desde respaldo   │
│                                                              │
│ Cert rechazado:  Ver: Algoritmo de firma (¿SHA-1?)           │
│                  Solución: Reemitir con SHA-256+             │
│                                                              │
│ Cliente falla:   Ver: Soporte versión TLS                    │
│                  Temp: update-crypto-policies --set LEGACY   │
│                  Solución: Actualizar cliente                │
│                                                              │
│ certmonger:      Ver: getcert list                           │
│                  Solución: Restaurar /var/lib/certmonger/    │
│                                                              │
│ Emergencia:      Deshabilitar SSL temporalmente              │
│                  Generar autofirmado temp                    │
│                  Restaurar desde respaldo                    │
│                                                              │
│ Rollback:        Usar snapshot/respaldo                      │
│                  Restaurar certificados                      │
│                  Restaurar configuraciones                   │
└──────────────────────────────────────────────────────────────┘

✅ La mayoría de problemas son corregibles sin rollback completo
⚠️ Tener respaldos listos
⚠️ Probar en no-producción primero

Navegación del Capítulo

Capítulo 38: Guía Completa del Modo FIPS

Cumplimiento Federal: El cumplimiento FIPS 140-2/140-3 es requerido para sistemas federales de EE.UU. y muchas industrias reguladas. Aprende cómo habilitar y gestionar el modo FIPS en RHEL.


38.1 ¿Qué es FIPS?

FIPS = Federal Information Processing Standards (Estándares Federales de Procesamiento de Información)

FIPS 140-2/140-3 = Programa de Validación de Módulos Criptográficos

Propósito:

  • ✅ Validar que módulos criptográficos cumplan requisitos de seguridad
  • ✅ Asegurar implementación apropiada de algoritmos aprobados
  • ✅ Requerido para sistemas del gobierno federal de EE.UU.
  • ✅ A menudo requerido para: Banca, salud, contratistas de defensa

Estado de Validación FIPS por Versión RHEL

Versión RHELEstado FIPSEstándarNotas
RHEL 7ValidadoFIPS 140-2Módulos OpenSSL 1.0.2 validados
RHEL 8ValidadoFIPS 140-2OpenSSL 1.1.1, NSS, libgcrypt validados
RHEL 9ValidadoFIPS 140-2Proveedor OpenSSL 3.x, transición a 140-3 en progreso
RHEL 10En procesoFIPS 140-2/140-3Transición en curso, verificar estado actual

Importante: A partir de 2025, RHEL 9 usa módulos validados FIPS 140-2. La transición a FIPS 140-3 está en progreso pero aún no completa. Siempre verifica el estado actual de validación en https://csrc.nist.gov/projects/cryptographic-module-validation-program


38.2 Habilitar Modo FIPS

FIPS en Tiempo de Instalación (Recomendado)

Mejor Práctica: Habilitar FIPS durante instalación de RHEL

# En el prompt de arranque de instalación, agregar:
fips=1

# El sistema se instala en modo FIPS desde el inicio
# Todas las operaciones criptográficas son conformes a FIPS desde arranque

Por Qué Tiempo de Instalación es Mejor:

  • Kernel configurado apropiadamente
  • Todos los paquetes instalados en modo FIPS
  • No se necesita migración post-instalación
  • Estado FIPS más limpio

FIPS Post-Instalación (RHEL 8/9/10)

#============================================#
# HABILITAR MODO FIPS POST-INSTALACIÓN
#============================================#

# Verificar estado FIPS actual
fips-mode-setup --check
# FIPS mode is disabled.

# Habilitar modo FIPS
sudo fips-mode-setup --enable

# La salida muestra qué cambiará:
# - Parámetros de arranque del kernel
# - Crypto policy
# - Reconfiguración del sistema

# ¡SE DEBE REINICIAR!
sudo reboot

# Después de reiniciar, verificar
fips-mode-setup --check
# FIPS mode is enabled.

# Verificar crypto-policy
update-crypto-policies --show
# FIPS

# Verificar proveedor FIPS cargado (RHEL 9+)
openssl list -providers | grep fips
#   fips
#     name: OpenSSL FIPS Provider
#     version: 3.5.5
#     status: active

38.3 Requisitos FIPS para Certificados

Algoritmos Aprobados

Aprobados por FIPS para Certificados:

✅ RSA: 2048, 3072, 4096 bits
✅ ECC: P-256 (secp256r1), P-384 (secp384r1), P-521 (secp521r1)
✅ Firmas: SHA-256, SHA-384, SHA-512
✅ TLS: Solo 1.2, 1.3

Bloqueados en Modo FIPS:

❌ RSA < 2048 bits
❌ MD5, SHA-1
❌ TLS 1.0, 1.1
❌ 3DES, RC4, DES
❌ Claves DSA
❌ Curvas elípticas no aprobadas

38.4 Generar Certificados Conformes a FIPS

Generación de Claves Conformes a FIPS

#============================================#
# GENERAR CLAVES CONFORMES A FIPS
#============================================#

# Verificar modo FIPS habilitado
fips-mode-setup --check

# Generar clave RSA 2048 (conforme a FIPS)
openssl genpkey -algorithm RSA -out fips-server.key \
  -pkeyopt rsa_keygen_bits:2048

# RSA 3072 (más fuerte, aún conforme a FIPS)
openssl genpkey -algorithm RSA -out fips-server.key \
  -pkeyopt rsa_keygen_bits:3072

# EC P-256 (curva aprobada por FIPS)
openssl genpkey -algorithm EC -out fips-ec.key \
  -pkeyopt ec_paramgen_curve:P-256

# EC P-384 (más fuerte, aprobada por FIPS)
openssl genpkey -algorithm EC -out fips-ec.key \
  -pkeyopt ec_paramgen_curve:P-384

# Verificar clave generada en modo FIPS
openssl pkey -in fips-server.key -check

CSR Conforme a FIPS

#============================================#
# GENERAR CSR CONFORME A FIPS
#============================================#

# CSR con SHA-256 (aprobado por FIPS)
openssl req -new -key fips-server.key -out fips-server.csr \
  -sha256 \
  -subj "/C=US/O=Federal Agency/CN=secure.example.gov" \
  -addext "subjectAltName=DNS:secure.example.gov"

# SHA-384 (más fuerte, aprobado por FIPS)
openssl req -new -key fips-server.key -out fips-server.csr \
  -sha384 \
  -subj "/C=US/O=Federal Agency/CN=secure.example.gov"

# ❌ NUNCA usar SHA-1 o MD5 en modo FIPS
# ¡Serán rechazados!

38.5 Verificación del Modo FIPS

Verificación Completa de FIPS

#============================================#
# VERIFICAR QUE MODO FIPS ESTÁ ACTIVO
#============================================#

# Verificación 1: fips-mode-setup
fips-mode-setup --check
# FIPS mode is enabled.

# Verificación 2: Parámetro del kernel
cat /proc/cmdline | grep fips
# Debería mostrar: fips=1

# Verificación 3: Crypto-policy
update-crypto-policies --show
# FIPS

# Verificación 4: Proveedor FIPS de OpenSSL (RHEL 9+)
openssl list -providers
# Debería mostrar proveedor fips como activo

# Verificación 5: Probar operación solo-FIPS
# Intentar algoritmo no-FIPS (debería fallar)
echo "test" | openssl md5
# Error: disabled for FIPS  ← ¡Bueno!

# Verificación 6: Verificar que operaciones de certificado usan FIPS
openssl version -a | grep FIPS

38.6 Crypto-Policy FIPS

Entender Política FIPS

#============================================#
# DETALLES DE CRYPTO-POLICY FIPS
#============================================#

# La política se establece automáticamente a FIPS cuando se habilita modo FIPS
update-crypto-policies --show
# FIPS

# Qué fuerza la política FIPS:
cat /etc/crypto-policies/back-ends/opensslcnf.config

# Ajustes clave:
# - TLS 1.2 mínimo
# - Solo cifrados aprobados por FIPS
# - Solo algoritmos de firma aprobados por FIPS
# - Claves mínimo 2048 bits

¡No se puede cambiar de política FIPS mientras está en modo FIPS!


38.7 Servicios en Modo FIPS

Apache en Modo FIPS

#============================================#
# APACHE EN MODO FIPS
#============================================#

# Apache usa automáticamente política FIPS
# ¡No se necesita configuración manual!

# Verificar
sudo systemctl restart httpd

# Probar
openssl s_client -connect localhost:443

# Debería mostrar:
# - TLS 1.2 o 1.3
# - Cifrado aprobado por FIPS
# - Sin algoritmos débiles

# Ver configuración FIPS real de Apache
cat /etc/crypto-policies/back-ends/httpd.config

Otros Servicios

Todos los servicios cumplen automáticamente con política FIPS:

  • NGINX → Usa cifrados/protocolos FIPS
  • Postfix → TLS conforme a FIPS
  • OpenSSH → Solo algoritmos FIPS
  • Bases de datos → SSL aprobado por FIPS

38.8 Problemas Comunes de FIPS

Problema 1: Algoritmo No-FIPS Intentado

Síntoma:

Error: disabled for FIPS

Ejemplos:

# MD5 (no aprobado por FIPS)
openssl md5 file.txt
# Error: digital envelope routines:EVP_DigestInit_ex:disabled for fips

# Firma SHA-1 (no aprobada por FIPS para firmar)
openssl dgst -sha1 -sign key.pem file.txt
# Error: disabled for fips

Solución:

# Usar algoritmos aprobados por FIPS
openssl sha256 file.txt  # Usar SHA-256 en lugar de MD5
openssl dgst -sha256 -sign key.pem file.txt  # Usar SHA-256 para firmar

Problema 2: Aplicación Legacy Incompatible

Síntoma: La aplicación falla en modo FIPS

Causa: La aplicación usa algoritmos no-FIPS (MD5, SHA-1, cifrados débiles)

Soluciones:

# Solución 1: Actualizar aplicación para usar algoritmos FIPS

# Solución 2: Si la aplicación no puede actualizarse:
# Puede no poder ejecutarse en modo FIPS
# Considerar si FIPS es realmente requerido

# Solución 3: Aislamiento de contenedor (avanzado)
# Ejecutar app no-FIPS en contenedor sin FIPS

38.9 Deshabilitar Modo FIPS

Cuándo y Cómo Deshabilitar

#============================================#
# DESHABILITAR MODO FIPS (si es necesario)
#============================================#

# Verificar estado actual
fips-mode-setup --check

# Deshabilitar FIPS
sudo fips-mode-setup --disable

# SE DEBE REINICIAR
sudo reboot

# Después de reiniciar
fips-mode-setup --check
# FIPS mode is disabled.

# Crypto-policy revierte a DEFAULT
update-crypto-policies --show
# DEFAULT

Nota: ¡Deshabilitar FIPS puede tener implicaciones de cumplimiento!


38.10 Conclusiones Clave

  1. FIPS 140-2 es el estándar actual en RHEL (transición 140-3 en progreso)
  2. Habilitar en instalación para estado FIPS más limpio
  3. Habilitación post-instalación requiere reinicio
  4. Solo algoritmos aprobados por FIPS permitidos
  5. Crypto-policy automáticamente establecida a FIPS
  6. Los servicios cumplen automáticamente
  7. Probar aplicaciones antes de habilitar FIPS en producción

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA MODO FIPS                                  │
├──────────────────────────────────────────────────────────────┤
│ Estado:       fips-mode-setup --check                        │
│ Habilitar:    sudo fips-mode-setup --enable && reboot        │
│ Deshabilitar: sudo fips-mode-setup --disable && reboot       │
│                                                              │
│ Estándar:     FIPS 140-2 (validado)                          │
│               FIPS 140-3 (transición en progreso)            │
│                                                              │
│ Aprobados:    RSA 2048+, ECC P-256/384/521                   │
│               SHA-256/384/512                                │
│               TLS 1.2/1.3                                    │
│                                                              │
│ Bloqueados:   MD5, SHA-1, TLS 1.0/1.1                        │
│               RSA < 2048, 3DES, RC4                          │
│                                                              │
│ Política:     Automáticamente establecida a FIPS             │
│ Verificar:    openssl list -providers | grep fips            │
└──────────────────────────────────────────────────────────────┘

⚠️ FIPS 140-2 es actual (transición 140-3 en curso)
⚠️ Requiere reinicio para habilitar/deshabilitar
✅ Todos los servicios RHEL cumplen automáticamente

🧪 Laboratorio Práctico

Lab 19: Configuración del Modo FIPS

Habilita y configura modo de cumplimiento FIPS 140-2

  • 📁 Ubicación: labs/es_ES/19-fips-mode/
  • ⏱️ Tiempo: 40-50 minutos
  • 🎯 Nivel: Avanzado

Navegación del Capítulo

Capítulo 39: Certificados Compatibles con FIPS

Listo para Cumplimiento: Aprende cómo generar, validar y gestionar certificados compatibles con FIPS en RHEL para entornos federales y regulados.


39.1 Requisitos de Certificados FIPS

Requisitos Obligatorios

Para Cumplimiento FIPS 140-2/140-3:

✅ Algoritmo de Clave: RSA 2048+ o ECC P-256/384/521
✅ Firma: SHA-256, SHA-384, o SHA-512
✅ Protocolos TLS: Solo 1.2 o 1.3
✅ Generado en modo FIPS (para claves nuevas)
✅ Módulo validado usado para operaciones

❌ NO MD5, SHA-1
❌ NO RSA < 2048 bits
❌ NO TLS 1.0/1.1
❌ NO 3DES, RC4, DES
❌ NO algoritmos no aprobados

39.2 Generar Certificados FIPS

Flujo de Trabajo Completo de Certificado FIPS

#============================================#
# GENERACIÓN COMPLETA DE CERTIFICADO FIPS
#============================================#

# Prerrequisitos: Modo FIPS debe estar habilitado
fips-mode-setup --check
# FIPS mode is enabled.

# Paso 1: Generar clave RSA conforme a FIPS
openssl genpkey -algorithm RSA \
  -out /etc/pki/tls/private/fips-server.key \
  -pkeyopt rsa_keygen_bits:2048

# O más fuerte (3072/4096)
openssl genpkey -algorithm RSA \
  -out /etc/pki/tls/private/fips-server.key \
  -pkeyopt rsa_keygen_bits:3072

# Paso 2: Establecer permisos
sudo chmod 600 /etc/pki/tls/private/fips-server.key

# Paso 3: Generar CSR con SHA-256
openssl req -new \
  -key /etc/pki/tls/private/fips-server.key \
  -out /tmp/fips-server.csr \
  -sha256 \
  -subj "/C=US/O=Federal Agency/OU=IT/CN=secure.example.gov" \
  -addext "subjectAltName=DNS:secure.example.gov,DNS:www.secure.example.gov"

# Paso 4: Verificar CSR
openssl req -in /tmp/fips-server.csr -noout -text | grep -E "(Signature Algorithm|Public-Key)"
# Signature Algorithm: sha256WithRSAEncryption  ← Debe ser SHA-256+
# Public-Key: (2048 bit)  ← Debe ser 2048+

# Paso 5: Enviar a CA conforme a FIPS
# Recibir certificado de vuelta

# Paso 6: Verificar cumplimiento del certificado
openssl x509 -in fips-server.crt -noout -text | grep "Signature Algorithm"
# Signature Algorithm: sha256WithRSAEncryption  ← ¡Bueno!

Claves EC Conformes a FIPS

#============================================#
# CLAVES DE CURVA ELÍPTICA PARA FIPS
#============================================#

# P-256 (aprobada por FIPS)
openssl genpkey -algorithm EC \
  -out /etc/pki/tls/private/fips-ec.key \
  -pkeyopt ec_paramgen_curve:P-256

# P-384 (más fuerte, aprobada por FIPS)
openssl genpkey -algorithm EC \
  -out /etc/pki/tls/private/fips-ec.key \
  -pkeyopt ec_paramgen_curve:P-384

# Generar CSR
openssl req -new -key /etc/pki/tls/private/fips-ec.key \
  -out /tmp/fips-ec.csr \
  -sha256 \
  -subj "/CN=secure.example.gov"

39.3 Validar Cumplimiento FIPS

Verificación de Cumplimiento de Certificado

#!/bin/bash
# check-fips-compliance.sh
# Verificar que certificado es conforme a FIPS

CERT=$1

if [ -z "$CERT" ] || [ ! -f "$CERT" ]; then
  echo "Uso: $0 /path/to/certificate.crt"
  exit 1
fi

echo "=== Verificación de Cumplimiento FIPS ==="
echo "Certificado: $CERT"
echo ""

COMPLIANT=true

# Verificar algoritmo de firma
SIG_ALG=$(openssl x509 -in "$CERT" -noout -text | grep "Signature Algorithm" | head -2)
echo "Algoritmo de Firma: $SIG_ALG"

if echo "$SIG_ALG" | grep -Eqi "md5|sha1"; then
  echo "  ❌ FALLÓ: MD5/SHA-1 no aprobados por FIPS"
  COMPLIANT=false
else
  echo "  ✅ PASÓ: Firma aprobada por FIPS"
fi

# Verificar tamaño de clave
KEY_SIZE=$(openssl x509 -in "$CERT" -noout -text | grep "Public-Key" | grep -oP '\d+')
echo ""
echo "Tamaño de Clave: $KEY_SIZE bits"

if [ "$KEY_SIZE" -lt 2048 ]; then
  echo "  ❌ FALLÓ: Tamaño de clave < 2048 bits"
  COMPLIANT=false
else
  echo "  ✅ PASÓ: Tamaño de clave adecuado"
fi

# Verificar algoritmo de clave
KEY_ALG=$(openssl x509 -in "$CERT" -noout -text | grep "Public Key Algorithm")
echo ""
echo "Algoritmo de Clave: $KEY_ALG"

if echo "$KEY_ALG" | grep -qi "dsa"; then
  echo "  ❌ FALLÓ: DSA no aprobado por FIPS"
  COMPLIANT=false
fi

# Resultado final
echo ""
echo "================================"
if [ "$COMPLIANT" = true ]; then
  echo "✅ El certificado es CONFORME A FIPS"
  exit 0
else
  echo "❌ El certificado NO es conforme a FIPS"
  echo "   Reemitir con parámetros aprobados por FIPS"
  exit 1
fi

39.4 Selección de CA FIPS

La CA Debe Estar Validada por FIPS

CA Interna:

  • Usar FreeIPA en modo FIPS
  • Dogtag PKI (CA de FreeIPA) tiene validación FIPS

CA Externa:

  • Verificar que CA esté validada FIPS 140-2/140-3
  • Solicitar documentación de cumplimiento FIPS
  • CAs FIPS comunes: DigiCert Federal, Entrust, IdenTrust

39.5 Configuración de Servicios para FIPS

Servicios Automáticamente Conformes a FIPS

Cuando se habilita modo FIPS, todos los servicios usan automáticamente crypto-policy FIPS:

# Apache - no se necesita configuración especial
# Solo asegurar que certificado es conforme a FIPS

# NGINX - usa automáticamente política FIPS

# Postfix - conforme a FIPS automáticamente

# Verificar cada servicio
openssl s_client -connect localhost:443
# Verificar cifrado usado - debería ser aprobado por FIPS

39.6 Conclusiones Clave

  1. FIPS 140-2 es el estándar validado actual en RHEL
  2. Transición FIPS 140-3 está en progreso
  3. Habilitar en instalación para mejores resultados
  4. Solo RSA 2048+ o ECC P-256/384
  5. Firmas SHA-256+ requeridas
  6. Los servicios cumplen automáticamente con política FIPS
  7. Probar aplicaciones antes de habilitar FIPS

Tarjeta de Referencia Rápida

┌───────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA CERTIFICADOS CONFORMES A FIPS               │
├───────────────────────────────────────────────────────────────┤
│ Estándar:   FIPS 140-2 (validado actual)                      │
│             FIPS 140-3 (transición en progreso)               │
│                                                               │
│ Claves:     RSA 2048/3072/4096                                │
│             ECC P-256/384/521                                 │
│                                                               │
│ Firma:      SHA-256, SHA-384, SHA-512                         │
│             (NO MD5, NO SHA-1)                                │
│                                                               │
│ Generar:    openssl genpkey -algorithm RSA ... (en modo FIPS) │
│ CSR:        openssl req -new -sha256 ...                      │
│ Verificar:  Verificar alg firma, tamaño clave                 │
│                                                               │
│ Probar:     echo test | openssl md5                           │
│             (debería fallar si FIPS funciona)                 │
└───────────────────────────────────────────────────────────────┘

✅ Modo FIPS debe estar habilitado para cumplimiento
✅ Todas las operaciones usan módulos criptográficos validados
⚠️ Verificar estado actual 140-2/140-3 para tus necesidades

Navegación del Capítulo

Capítulo 40: Fortalecimiento de Seguridad RHEL para Certificados

Defensa en Profundidad: Más allá de FIPS, aprende cómo fortalecer la seguridad de certificados en RHEL usando SELinux, TPM, tarjetas inteligentes y herramientas de escaneo de seguridad.


40.1 Resumen de Fortalecimiento de Seguridad

Capas de Seguridad de Certificados:

  1. Permisos de Archivo - Proteger claves privadas
  2. SELinux - Control de acceso obligatorio
  3. Firewall - Limitar exposición
  4. Auditoría - Rastrear acceso
  5. TPM - Protección de clave por hardware
  6. Tarjetas Inteligentes - Tokens físicos
  7. Monitoreo - Detectar problemas
  8. Escaneo de Cumplimiento - Verificar configuración

40.2 SELinux para Certificados

Contextos SELinux Apropiados

#============================================#
# CONTEXTOS DE CERTIFICADO SELINUX
#============================================#

# Verificar contextos actuales
ls -Z /etc/pki/tls/certs/*.crt
ls -Z /etc/pki/tls/private/*.key

# Contextos correctos:
# Certificados: system_u:object_r:cert_t:s0
# Claves privadas: system_u:object_r:cert_t:s0

# Corregir contextos si están mal
sudo restorecon -Rv /etc/pki/tls/

# Verificar
ls -Z /etc/pki/tls/certs/server.crt
# system_u:object_r:cert_t:s0  ← Correcto

Política de Certificados SELinux

#============================================#
# ENDURECIMIENTO DE CERTIFICADOS SELINUX
#============================================#

# Asegurar SELinux enforcing
getenforce
# Enforcing  ← Bueno

# Si permissive, habilitar enforcing
sudo setenforce 1

# Hacer permanente
sudo sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config

# Verificar denegaciones relacionadas con certificados
sudo ausearch -m avc -ts recent | grep cert

# Si se encuentran denegaciones, generar política
sudo ausearch -m avc -ts recent | audit2allow -M mycert-policy
sudo semodule -i mycert-policy.pp

40.3 Fortalecimiento de Permisos de Archivo

Modelo de Permisos Estrictos

#============================================#
# PERMISOS DE ARCHIVO FORTALECIDOS
#============================================#

# Certificados (públicos) - acceso mínimo
sudo chmod 444 /etc/pki/tls/certs/*.crt
sudo chown root:root /etc/pki/tls/certs/*.crt

# Claves privadas (¡secretas!) - solo propietario
sudo chmod 400 /etc/pki/tls/private/*.key
sudo chown root:root /etc/pki/tls/private/*.key

# Aún más estricto: Inmutable (no puede modificarse ni por root sin eliminar flag)
sudo chattr +i /etc/pki/tls/certs/critical.crt
sudo chattr +i /etc/pki/tls/private/critical.key

# Eliminar inmutable cuando se necesite actualizar
# sudo chattr -i /etc/pki/tls/private/critical.key

# Verificar
ls -l /etc/pki/tls/private/
# -r--------. 1 root root  ← 400, muy restrictivo

40.4 TPM (Módulo de Plataforma Confiable)

Usar TPM para Almacenamiento de Claves

Beneficios de TPM:

  • ✅ Claves protegidas por hardware
  • ✅ Las claves nunca salen del TPM
  • ✅ Resistente a manipulación
  • ✅ Atestación de plataforma
#============================================#
# TPM PARA CLAVES DE CERTIFICADO (AVANZADO)
#============================================#

# Verificar si TPM está disponible
ls /dev/tpm*

# Instalar herramientas TPM
sudo dnf install tpm2-tools -y

# Generar clave en TPM
tpm2_createprimary -C o -g sha256 -G rsa -c primary.ctx
tpm2_create -G rsa -u rsa.pub -r rsa.priv -C primary.ctx

# Usar clave TPM con OpenSSL requiere configuración adicional
# (Complejo, caso de uso empresarial)

# Para certmonger con TPM:
# Experimental/avanzado - verificar docs Red Hat

40.5 Tarjetas Inteligentes y PIV

Usar Tarjetas Inteligentes para Autenticación

#============================================#
# CONFIGURACIÓN TARJETA INTELIGENTE (PIV/CAC)
#============================================#

# Instalar soporte de tarjeta inteligente
sudo dnf install opensc pcsc-lite -y

# Iniciar demonio PC/SC
sudo systemctl enable --now pcscd

# Verificar si tarjeta es legible
pkcs11-tool --list-slots

# Listar certificados en tarjeta
pkcs11-tool --list-objects

# Usar tarjeta inteligente con SSH
# /etc/ssh/sshd_config:
# PubkeyAuthentication yes

# Extraer clave pública de tarjeta
ssh-keygen -D /usr/lib64/opensc-pkcs11.so > ~/.ssh/authorized_keys

40.6 Auditoría y Monitoreo

auditd para Acceso a Certificados

#============================================#
# AUDITAR ACCESO A CERTIFICADOS
#============================================#

# Agregar reglas de auditoría para acceso a clave privada
sudo auditctl -w /etc/pki/tls/private/ -p war -k certificate-access

# Hacer permanente
echo "-w /etc/pki/tls/private/ -p war -k certificate-access" | \
  sudo tee -a /etc/audit/rules.d/certificate.rules

# Recargar reglas
sudo augenrules --load

# Monitorear acceso
sudo ausearch -k certificate-access

# Monitoreo en tiempo real
sudo ausearch -k certificate-access -ts recent -i

40.7 Escaneo OpenSCAP

Escaneo de Cumplimiento de Seguridad

#============================================#
# ESCANEO DE CERTIFICADOS OPENSCAP
#============================================#

# Instalar OpenSCAP
sudo dnf install openscap-scanner scap-security-guide -y

# Escanear problemas de certificados
sudo oscap xccdf eval \
  --profile xccdf_org.ssgproject.content_profile_pci-dss \
  --results scan-results.xml \
  --report scan-report.html \
  /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml

# Ver reporte
firefox scan-report.html

# Verificaciones relacionadas con certificados:
# - Permisos de archivo
# - Contextos SELinux
# - Algoritmos débiles
# - Expiración

40.8 Lista de Verificación de Fortalecimiento de Seguridad

## Lista de Verificación Fortalecimiento de Seguridad de Certificados

### Seguridad de Archivo
- [ ] Claves privadas modo 400 o 600 (¡nunca 644!)
- [ ] Certificados modo 444 o 644
- [ ] Ownership: root:root o usuario del servicio
- [ ] Contextos SELinux: cert_t
- [ ] Considerar flag inmutable (+i) para certs críticos

### Control de Acceso
- [ ] SELinux enforcing
- [ ] Reglas de auditoría para acceso a clave privada
- [ ] Firewall limitando puertos TLS
- [ ] Principio de menor privilegio aplicado

### Seguridad de Algoritmo
- [ ] Solo firmas SHA-256+
- [ ] Claves RSA 2048+ o ECC P-256+
- [ ] Solo TLS 1.2+ (no 1.0/1.1)
- [ ] Cifrados fuertes (vía crypto-policy)
- [ ] Modo FIPS si es requerido

### Seguridad Operacional
- [ ] Certificados monitoreados para expiración
- [ ] Renovación automática habilitada (certmonger)
- [ ] Respaldos cifrados
- [ ] Claves nunca enviadas por email o en tickets
- [ ] Acceso registrado y revisado
- [ ] Escaneos de seguridad regulares

### Seguridad de Red
- [ ] Reglas de firewall restrictivas
- [ ] Solo puertos necesarios abiertos
- [ ] Certificate pinning (donde aplique)
- [ ] HSTS habilitado para servidores web
- [ ] OCSP stapling habilitado

### Cumplimiento
- [ ] Escaneos OpenSCAP pasando
- [ ] Cumplimiento STIG verificado
- [ ] Benchmarks CIS cumplidos
- [ ] Documentación actual
- [ ] Pista de auditoría mantenida

40.9 Conclusiones Clave

  1. Defensa en profundidad - Múltiples capas de seguridad
  2. SELinux enforcing - Obligatorio para producción
  3. Permisos de archivo críticos - 400/600 para claves
  4. Auditar todo - Rastrear acceso a claves
  5. TPM para alta seguridad - Protección por hardware
  6. OpenSCAP para cumplimiento - Escaneo automatizado
  7. Monitorear continuamente - La seguridad es continua

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ ENDURECIMIENTO DE SEGURIDAD DE CERTIFICADOS                  │
├──────────────────────────────────────────────────────────────┤
│ Permisos:     chmod 400 /etc/pki/tls/private/*.key           │
│               chmod 444 /etc/pki/tls/certs/*.crt             │
│                                                              │
│ SELinux:      getenforce (debe ser Enforcing)                │
│               restorecon -Rv /etc/pki/tls/                   │
│               ls -Z (verificar contextos)                    │
│                                                              │
│ Auditoría:    auditctl -w /etc/pki/tls/private/ -p war       │
│               ausearch -k certificate-access                 │
│                                                              │
│ Escanear:     oscap xccdf eval --profile pci-dss ...         │
│                                                              │
│ Inmutable:    chattr +i /etc/pki/tls/private/key.key         │
│               chattr -i (para modificar)                     │
└──────────────────────────────────────────────────────────────┘

✅ SELinux enforcing es obligatorio
✅ Auditar acceso a clave privada
✅ Usar 400 (no 600) para máxima seguridad

🧪 Laboratorio Práctico

Lab 20: Fortalecimiento de Seguridad

Aplique mejores prácticas de seguridad a configuraciones de certificados

  • 📁 Ubicación: labs/es_ES/20-security-hardening/
  • ⏱️ Tiempo: 30-40 minutos
  • 🎯 Nivel: Avanzado

Navegación del Capítulo

Capítulo 41: Cumplimiento y Auditoría

Cumplir Requisitos: Aprende cómo cumplir requisitos de cumplimiento de seguridad (STIG, CIS, PCI-DSS) y auditar configuraciones de certificados en RHEL.


41.1 Marcos de Cumplimiento

Requisitos Comunes Relacionados con Certificados

MarcoEnfoqueRequisitos de Certificados
STIGSeguridad DoDFIPS, algoritmos fuertes, auditoría
CIS BenchmarkMejores prácticas industriaTLS 1.2+, cifrados fuertes, permisos
PCI-DSSIndustria tarjetas de pagoCrypto fuerte, no TLS/cifrados débiles
HIPAASaludCifrado, control acceso, auditoría
NIST 800-53Sistemas federalesFIPS, algoritmos aprobados, monitoreo

41.2 Cumplimiento STIG

Requisitos DISA STIG para Certificados

Requisitos STIG Clave:

## Controles STIG de Certificados

### V-238200: SSH debe usar cifrados fuertes
- Requisito: Solo algoritmos aprobados por FIPS
- Verificar: /etc/ssh/sshd_config
- Solución: Usar crypto-policies (RHEL 8+)

### V-238201: Servidor web debe usar TLS fuerte
- Requisito: Solo TLS 1.2+
- Verificar: Configuración Apache/NGINX
- Solución: Deshabilitar TLS 1.0/1.1

### V-238202: Certificados deben ser de CA aprobada por DoD
- Requisito: Usar CA aprobada
- Verificar: Emisor del certificado
- Solución: Obtener de fuente aprobada

### V-238203: Claves privadas deben estar protegidas
- Requisito: Modo 600 o más estricto
- Verificar: ls -l /etc/pki/tls/private/
- Solución: chmod 600

### V-238204: Expiración de certificado debe monitorearse
- Requisito: Monitoreo automatizado
- Verificar: Sistema de monitoreo en lugar
- Solución: Implementar (ver Capítulo 26)

Escaneo de Cumplimiento STIG

#============================================#
# ESCANEO CUMPLIMIENTO STIG PARA CERTIFICADOS
#============================================#

# Instalar SCAP Security Guide
sudo dnf install scap-security-guide openscap-scanner -y

# Ejecutar escaneo STIG
sudo oscap xccdf eval \
  --profile xccdf_org.ssgproject.content_profile_stig \
  --results stig-results.xml \
  --report stig-report.html \
  /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml

# Ver reporte
firefox stig-report.html

# Verificar hallazgos específicos de certificados
grep -i "cert\|tls\|ssl" stig-report.html

41.3 Cumplimiento CIS Benchmark

Controles CIS para Certificados

Recomendaciones CIS RHEL Benchmark:

## Controles de Certificados CIS

### 5.2.14: Asegurar que solo se usen cifrados fuertes
- Verificar: Crypto-policy DEFAULT o FUTURE
- Comando: `update-crypto-policies --show`

### 5.2.15: Asegurar que solo se usen algoritmos fuertes
- Verificar: No MD5, SHA-1, claves débiles
- Escanear: Verificar todos los certificados

### 5.2.16: Asegurar TLS 1.2 mínimo
- Verificar: Crypto-policy o config de servicio
- Probar: `openssl s_client -tls1_2`

### 5.3.1: Asegurar permisos en claves privadas
- Requisito: 600 o más estricto
- Verificar: `ls -l /etc/pki/tls/private/`

### 5.3.2: Asegurar monitoreo de expiración de certificados
- Requisito: Verificaciones automatizadas
- Implementación: certmonger o script de monitoreo

Escaneo de Cumplimiento CIS

#============================================#
# ESCANEO CIS BENCHMARK
#============================================#

# Ejecutar escaneo CIS
sudo oscap xccdf eval \
  --profile xccdf_org.ssgproject.content_profile_cis \
  --results cis-results.xml \
  --report cis-report.html \
  /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml

# Generar script de remediación
sudo oscap xccdf generate fix \
  --profile xccdf_org.ssgproject.content_profile_cis \
  --fix-type bash \
  stig-results.xml > remediation.sh

# Revisar y ejecutar remediación
chmod +x remediation.sh
sudo ./remediation.sh

41.4 Cumplimiento PCI-DSS

Requisitos de Certificados PCI-DSS

Requisitos PCI-DSS v4.0:

## Controles de Certificados PCI-DSS

### Requisito 4.2.1: Criptografía fuerte
- TLS 1.2 mínimo (1.3 recomendado)
- Solo suites de cifrado fuertes
- Verificar: crypto-policy DEFAULT o FUTURE

### Requisito 4.2.1.1: Protocolos inseguros deshabilitados
- NO SSL, TLS 1.0, TLS 1.1
- Verificar: `openssl s_client -tls1`
- Debería fallar en sistema conforme

### Requisito 4.2.1.2: Algoritmos de cifrado fuertes
- AES-128 mínimo
- NO 3DES, DES, RC4
- Verificar: `openssl ciphers -v`

### Requisito 8.3.2: Autenticación basada en certificado
- Para acceso administrativo
- Implementación: Certificados de cliente, tarjetas inteligentes

### Requisito 10: Auditar acceso a certificados
- Registrar todo acceso a clave privada
- Implementación: Reglas auditd

Script de Validación PCI-DSS

#!/bin/bash
# pci-dss-cert-check.sh

echo "=== Verificación de Cumplimiento PCI-DSS de Certificados ==="

# Verificación 1: Solo TLS 1.2+
echo "1. Verificación de Versión TLS:"
if openssl s_client -connect localhost:443 -tls1 &>/dev/null; then
  echo "  ❌ FALLÓ: TLS 1.0 está habilitado"
else
  echo "  ✅ PASÓ: TLS 1.0 deshabilitado"
fi

# Verificación 2: Cifrados fuertes
echo ""
echo "2. Fortaleza de Cifrado:"
WEAK=$(openssl ciphers -v | grep -Ei "3des|rc4|des-cbc" | wc -l)
if [ $WEAK -gt 0 ]; then
  echo "  ❌ FALLÓ: Cifrados débiles disponibles"
else
  echo "  ✅ PASÓ: Sin cifrados débiles"
fi

# Verificación 3: Monitoreo de expiración de certificado
echo ""
echo "3. Monitoreo de Expiración:"
if systemctl is-active --quiet certmonger || \
   systemctl list-timers | grep -q cert-monitor; then
  echo "  ✅ PASÓ: Monitoreo habilitado"
else
  echo "  ⚠️ ADVERTENCIA: No se detectó monitoreo automatizado"
fi

# Verificación 4: Permisos de clave privada
echo ""
echo "4. Permisos de Clave Privada:"
BAD_PERMS=$(find /etc/pki/tls/private/ -name "*.key" -not -perm 600 2>/dev/null | wc -l)
if [ $BAD_PERMS -gt 0 ]; then
  echo "  ❌ FALLÓ: $BAD_PERMS claves con permisos incorrectos"
else
  echo "  ✅ PASÓ: Todas las claves apropiadamente protegidas"
fi

echo ""
echo "=== Verificación Completa ==="

41.5 Procedimientos de Auditoría

Lista de Verificación de Auditoría de Certificados

## Lista de Verificación Auditoría Trimestral de Certificados

### Revisión de Inventario
- [ ] Todos los certificados documentados
- [ ] Inventario de certificados actual
- [ ] Ownership documentado
- [ ] Propósito documentado

### Revisión de Expiración
- [ ] Sin certificados expirados
- [ ] Sin certificados expirando < 30 días
- [ ] Proceso de renovación documentado
- [ ] Alertas de monitoreo funcionando

### Revisión de Seguridad
- [ ] Solo firmas SHA-256+ (sin SHA-1 ni MD5)
- [ ] Claves RSA 2048+ o ECC P-256+
- [ ] Solo TLS 1.2+ (no 1.0/1.1)
- [ ] Permisos de clave privada correctos (600)
- [ ] Contextos SELinux correctos
- [ ] Sin certificados innecesarios

### Revisión de Configuración
- [ ] Configuraciones de servicio revisadas
- [ ] Crypto-policy apropiada
- [ ] Sin sobrescrituras de cifrado débil
- [ ] HSTS habilitado (servidores web)
- [ ] Certificate pinning documentado

### Revisión de Acceso
- [ ] Logs de auditoría revisados
- [ ] Acceso no autorizado investigado
- [ ] Acceso a clave limitado a personal autorizado
- [ ] Acceso a respaldo controlado

### Revisión de Cumplimiento
- [ ] Cumplimiento STIG/CIS/PCI verificado
- [ ] Escaneos de seguridad pasando
- [ ] Remediación completa
- [ ] Documentación actualizada

41.6 Reportes de Cumplimiento Automatizados

Generar Reporte de Cumplimiento

#!/bin/bash
# generate-compliance-report.sh

REPORT_FILE="compliance-report-$(date +%Y%m%d).txt"

cat > "$REPORT_FILE" << EOF
=== Reporte de Cumplimiento de Certificados ===
Generado: $(date)
Sistema: $(hostname)
Versión RHEL: $(cat /etc/redhat-release)

=== Configuración ===
Versión OpenSSL: $(openssl version)
Crypto-Policy: $(update-crypto-policies --show 2>/dev/null || echo "N/A (RHEL 7)")
Modo FIPS: $(fips-mode-setup --check 2>/dev/null || echo "N/A")
SELinux: $(getenforce)

=== Inventario de Certificados ===
EOF

# Contar certificados
TOTAL=$(find /etc/pki/tls/certs/ -name "*.crt" -type f 2>/dev/null | wc -l)
echo "Total Certificados: $TOTAL" >> "$REPORT_FILE"

# Verificar expiraciones
echo "" >> "$REPORT_FILE"
echo "Estado de Expiración:" >> "$REPORT_FILE"
EXPIRING=0
for cert in /etc/pki/tls/certs/*.crt; do
  [ -f "$cert" ] || continue
  if ! openssl x509 -in "$cert" -noout -checkend $((86400*30)) 2>/dev/null; then
    echo "  ⚠️ Expira dentro de 30 días: $cert" >> "$REPORT_FILE"
    ((EXPIRING++))
  fi
done
echo "Certificados expirando < 30 días: $EXPIRING" >> "$REPORT_FILE"

# Verificar algoritmos
echo "" >> "$REPORT_FILE"
echo "Cumplimiento de Algoritmos:" >> "$REPORT_FILE"
SHA1_COUNT=0
for cert in /etc/pki/tls/certs/*.crt; do
  [ -f "$cert" ] || continue
  if openssl x509 -in "$cert" -noout -text 2>/dev/null | grep -qi "sha1.*signature"; then
    echo "  ❌ Firma SHA-1: $cert" >> "$REPORT_FILE"
    ((SHA1_COUNT++))
  fi
done
echo "Certificados SHA-1: $SHA1_COUNT (debería ser 0)" >> "$REPORT_FILE"

# Verificar permisos
echo "" >> "$REPORT_FILE"
echo "Cumplimiento de Permisos:" >> "$REPORT_FILE"
BAD_PERMS=$(find /etc/pki/tls/private/ -name "*.key" -not -perm 600 2>/dev/null | wc -l)
echo "Claves con permisos incorrectos: $BAD_PERMS (debería ser 0)" >> "$REPORT_FILE"

# Estado de certmonger
if command -v getcert &>/dev/null; then
  echo "" >> "$REPORT_FILE"
  echo "Estado de certmonger:" >> "$REPORT_FILE"
  sudo getcert list | grep "status:" | sort | uniq -c >> "$REPORT_FILE"
fi

echo "" >> "$REPORT_FILE"
echo "=== Reporte Completo ===" >> "$REPORT_FILE"

cat "$REPORT_FILE"
echo ""
echo "Reporte guardado en: $REPORT_FILE"

41.7 Conclusiones Clave

  1. El cumplimiento es continuo - No es de una sola vez
  2. Existen múltiples marcos - STIG, CIS, PCI, HIPAA
  3. OpenSCAP automatiza escaneo en RHEL
  4. Documentar todo - Requerido para auditorías
  5. Auditorías regulares esenciales - Trimestral mínimo
  6. La remediación debe rastrearse - Corregir y verificar
  7. El monitoreo es cumplimiento - Validación continua

Tarjeta de Referencia Rápida

┌──────────────────────────────────────────────────────────────┐
│ REFERENCIA RÁPIDA CUMPLIMIENTO Y AUDITORÍA                   │
├──────────────────────────────────────────────────────────────┤
│ STIG:         oscap ... --profile stig                       │
│ CIS:          oscap ... --profile cis                        │
│ PCI-DSS:      oscap ... --profile pci-dss                    │
│                                                              │
│ Requisitos Comunes:                                          │
│   - Solo TLS 1.2+                                            │
│   - Algoritmos fuertes (SHA-256+, RSA 2048+)                 │
│   - Sin cifrados débiles (3DES, RC4)                         │
│   - Claves privadas protegidas (modo 600)                    │
│   - Monitoreo de expiración                                  │
│   - Logging de auditoría habilitado                          │
│   - Modo FIPS (para federal)                                 │
│                                                              │
│ Herramientas: OpenSCAP, aide, auditd                         │
│ Escanear:     oscap xccdf eval --profile <profile> ...       │
│ Remediar:     oscap xccdf generate fix ...                   │
└──────────────────────────────────────────────────────────────┘

✅ El cumplimiento es continuo, no de una sola vez
✅ Automatizar escaneo con OpenSCAP
✅ Documentar todas las configuraciones y excepciones

Navegación del Capítulo

Guía de Camino de Aprendizaje

Cómo usar este tutorial efectivamente basado en tu rol y nivel de experiencia.


🎯 Para Principiantes Completos

Objetivo: Aprender certificados desde cero

Camino: Leer en orden (8 semanas)

Semana 1: Fundamentos (Cap 1-7)

  • Cap 1: Criptografía, Estructura PKI y Fundamentos
  • Cap 2: Introducción a los Certificados en RHEL
  • Cap 3: Resumen de Herramientas de Certificados en RHEL
  • Cap 4: Criptografía Básica para Administradores RHEL
  • Cap 5: Certificados X.509 en RHEL
  • Cap 6: Inmersión Profunda en el Almacén de Confianza RHEL
  • Cap 7: Firmas Digitales y Verificación en RHEL
  • Resultado: Entender certificados, cadenas de confianza y herramientas RHEL

Semana 2: Dominio de Versiones (Cap 8-13)

  • Cap 8: Diferencias entre versiones
  • Cap 9: RHEL 7
  • Cap 10: RHEL 8
  • Cap 11: RHEL 9
  • Cap 12: RHEL 10
  • Cap 13: Compatibilidad
  • Resultado: Conocer diferencias de versiones

Semana 3-4: Servicios (Cap 14-21)

  • Configurar Apache, NGINX, Postfix, LDAP, Bases de datos, FreeIPA
  • Resultado: Puede configurar cualquier servicio

Semana 5: Automatización (Cap 22-26)

  • certmonger, crypto-policies, Ansible, monitoreo
  • Resultado: Automatizar ciclo de vida de certificados

Semana 6: Solución de Problemas (Cap 27-33)

  • Dominar solución de problemas sistemática
  • Resultado: ¡Puede solucionar cualquier problema de certificado! ⭐

Semana 7: Migración (Cap 34-37)

  • Procedimientos de actualización RHEL
  • Resultado: Migrar versiones RHEL de forma segura

Semana 8: Seguridad (Cap 38-41)

  • FIPS, fortalecimiento, cumplimiento
  • Resultado: Cumplir requisitos de seguridad

🔧 Para Administradores de Sistemas

Objetivo: Configurar y mantener certificados

Camino Recomendado:

  1. Inicio Rápido (3-5 horas)

    • Cap 1: Criptografía y Fundamentos de PKI
    • Cap 3: Herramientas
    • Cap 27: Metodología de Solución de Problemas de Certificados RHEL
  2. Tu Versión RHEL (1-2 horas)

    • Cap 9 (RHEL 7), Cap 10 (RHEL 8), Cap 11 (RHEL 9), o Cap 12 (RHEL 10)
  3. Tus Servicios (3-4 horas)

    • Cap 14-21: Elegir capítulos para servicios que usas
  4. Automatización (2-3 horas)

    • Cap 22: certmonger
    • Cap 23: Crypto-policies (si RHEL 8+)
  5. Referencia

    • Mantener Cap 27-33 a mano para solución de problemas

Tiempo Total: ~10-15 horas para competencia


🚨 Para Ingenieros de Soporte

Objetivo: Resolver problemas de certificados rápido

Camino Vía Rápida:

  1. Comenzar Aquí (1 hora)

  2. Problemas Comunes (2 horas)

    • Cap 28: Errores Comunes
    • Cap 29: Solución de Problemas Específica por Servicio
    • Cap 30: Problemas de certmonger
    • Cap 31: Problemas de Crypto-Policy
  3. Herramientas (1 hora)

    • Cap 3: Herramientas RHEL
    • Cap 32: Informes SOS
  4. Emergencia (30 min)

    • Cap 33: Procedimientos de Emergencia
  5. Referencia Según Necesidad

    • Cap 9-12: Capítulos específicos por versión
    • Cap 14-21: Capítulos de servicio

Tiempo Total: 5-8 horas para competencia en solución de problemas

Luego: Usar capítulos como referencia durante incidentes


🏢 Para Arquitectos Empresariales

Objetivo: Diseñar infraestructura de certificados

Camino Estratégico:

  1. Resumen (1 hora)

    • Cap 1-2: Fundamentos e introducción
  2. CA Empresarial (2 horas)

    • Cap 19: FreeIPA
  3. Automatización (3 horas)

    • Cap 22: certmonger
    • Cap 23: Crypto-policies
    • Cap 25: Automatización Ansible para Certificados
  4. Mejores Prácticas (2 horas)

    • Cap 21: Mejores Prácticas de Servicio
    • Cap 26: Monitoreo y Alertas en RHEL
  5. Seguridad (3 horas)

    • Cap 38-41: FIPS, fortalecimiento, cumplimiento
  6. Migración (2 horas)

    • Cap 34-37: Si se planifican actualizaciones

Tiempo Total: ~13 horas para conocimiento de arquitectura


🔒 Para Equipos de Seguridad/Cumplimiento

Objetivo: Asegurar cumplimiento y seguridad

Camino de Cumplimiento:

  1. Fundamento (1 hora)

    • Cap 1: Criptografía y Fundamentos de PKI
    • Cap 2: Introducción a Certificados en RHEL
  2. Enfoque Seguridad (4 horas)

    • Cap 38: Modo FIPS
    • Cap 39: Certificados Compatibles con FIPS
    • Cap 40: Fortalecimiento de Seguridad
    • Cap 41: Cumplimiento y Auditoría ⭐
  3. Crypto-Policies (1 hora)

    • Cap 23: Entender controles en todo el sistema
  4. Monitoreo (1 hora)

    • Cap 26: Monitoreo y Alertas en RHEL
  5. Procedimientos de Auditoría (1 hora)

    • Cap 32: Informes SOS
    • Cap 41: Secciones de cumplimiento y auditoría

Tiempo Total: ~8-10 horas para experiencia en cumplimiento


🎓 Para Preparación de Capacitación/Certificación

Objetivo: Dominio completo

Camino Completo: Todos los capítulos en orden

Inversión de Tiempo: 40-50 horas

Resultado: Conocimiento de nivel experto en gestión de certificados RHEL


📚 Puntos de Entrada Rápida

Por Tipo de Problema:

“El servicio no inicia” → Cap 28 (Errores Comunes), Cap 29 (Solución de Problemas Específica por Servicio)

“Los clientes no pueden conectar” → Cap 13 (Compatibilidad), Cap 31 (Crypto-Policy)

“certmonger no renueva” → Cap 30 (Solución de Problemas de certmonger)

“Planificando actualización RHEL” → Cap 34-37 (Migración)

“Necesito cumplimiento FIPS” → Cap 38-39 (FIPS)

“Configurando nuevo servicio” → Cap 14-21 (Capítulos de servicio)

Por Versión RHEL:

Usando RHEL 7 → Cap 9 (Gestión RHEL 7)

Usando RHEL 8 → Cap 10 (¡Crypto-Policies son clave!)

Usando RHEL 9 → Cap 11 (OpenSSL 3.x, SHA-1 bloqueado)

Usando RHEL 10 → Cap 12 (Últimas características)

Entorno mixto → Cap 13 (Compatibilidad entre Versiones)


🗺️ Mapa del Tutorial

COMENZAR AQUÍ
    │
    ├─ ¿Nuevo en certificados?
    │   └─ Cap 1 → Cap 2 → Cap 3 → Continuar en orden
    │
    ├─ ¿Necesitas resolver problemas AHORA?
    │   └─ Cap 27 → Cap 28 → Cap 29 → Cap 33
    │
    ├─ ¿Configurando un servicio?
    │   └─ Cap 14-21 (elige tu servicio)
    │
    ├─ ¿Planificando migración?
    │   └─ Cap 34 → Cap 35/36 → Cap 37
    │
    ├─ ¿Necesitas automatización?
    │   └─ Cap 22 (certmonger) → Cap 23 (crypto-policies)
    │
    └─ ¿Cumplimiento requerido?
        └─ Cap 38-41 (FIPS, seguridad, auditoría)

⏱️ Estimaciones de Tiempo

CaminoTiempoCapítulos
Inicio Rápido3-5 horas1, 3, 27
Solución de Problemas5-8 horas27-33
Principiante Completo40-50 horasTodos en orden
Administrador de sistemas10-15 horasCapítulos seleccionados
Ingeniero Soporte5-8 horasEnfoque de solución de problemas
Cumplimiento8-10 horasCapítulos seguridad

💡 Consejos de Estudio

  1. Práctica es esencial - Practicar en VM RHEL
  2. Seguir ejemplos - Copiar-pegar y entender
  3. Usar referencias rápidas - Cuando el capítulo las incluya
  4. Marcar solución de problemas - Capítulos 27-33
  5. Conocer tu versión RHEL - Enfocarse en capítulos relevantes
  6. Construir un lab - Usar FreeIPA para práctica

Comenzar Aprendizaje: Capítulo 1: Criptografía, Estructura PKI y Fundamentos →

¿Necesitas ayuda rápida? Guía de Inicio Rápido de Solución de Problemas →

Referencia de Versión: Guía de Referencia Rápida de Versiones RHEL para Certificados →

Guía de Inicio Rápido de Solución de Problemas

¡Cuando tengas un problema de certificado, comienza aquí!


🚨 ¿Emergencia? ¡Salta al Capítulo 33!

Si la producción está caída, ve inmediatamente a Capítulo 33: Procedimientos de Emergencia


📋 El Método de 7 Pasos (Capítulo 27)

1. Identificar: versión de RHEL, OpenSSL y crypto-policy
2. Verificar: expiración, hostname, coincidencia clave-certificado y algoritmo
3. Confianza: validación de CA, cadena e intermedios
4. Configuración: archivos del servicio, rutas y permisos
5. Sistema: crypto-policy, FIPS, SELinux y firewall
6. Probar: conexiones en vivo, curl y openssl s_client
7. Logs: logs del servicio, journal y auditoría SELinux

Metodología completa: Capítulo 27


⚡ Diagnósticos Rápidos

Primeros 60 Segundos

# ¿Qué versión de RHEL?
cat /etc/redhat-release

# ¿Certificado expirado?
openssl x509 -in /etc/pki/tls/certs/server.crt -noout -checkend 0

# ¿Servicio en ejecución?
systemctl status httpd

# ¿Errores recientes?
journalctl -xe | grep -i cert | tail -20

# ¿Crypto-policy? (RHEL 8+)
update-crypto-policies --show

🔍 Problemas Comunes

Certificado Expirado

# Verificar
openssl x509 -in cert.crt -noout -dates

# Solución
sudo getcert resubmit -f cert.crt  # Si usas seguimiento con certmonger
# O renovar manualmente, o usar los procedimientos de emergencia del Capítulo 33

Cadena de Confianza Rota

# Verificar
openssl verify cert.crt

# Solución
sudo cp ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

Permiso Denegado

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

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

Desajuste de Hostname

# Verificar
openssl x509 -in cert.crt -noout -ext subjectAltName

# Solución
# Reemitir certificado con SANs correctos

Sin Cifrado Compartido (RHEL 8+)

# Verificar
update-crypto-policies --show

# Solución temporal
sudo update-crypto-policies --set LEGACY
sudo systemctl restart httpd

# Solución apropiada: actualizar el cliente para soportar TLS 1.2+

SHA-1 Rechazado (RHEL 9+)

# Verificar
openssl x509 -in cert.crt -noout -text | grep "Signature Algorithm"

# Solución
# Debe reemitirse con SHA-256+ (sin solución alternativa)

📖 Dónde Buscar

Tipo de ProblemaIr al Capítulo
Solución de problemas generalCapítulo 27
Errores comunesCapítulo 28
Problemas Apache/NGINX/PostfixCapítulo 29
Problemas de certmongerCapítulo 30
Problemas de crypto-policyCapítulo 31
Análisis de informes SOSCapítulo 32
Emergencia en producciónCapítulo 33
Específico para RHEL 7Capítulo 9
Específico para RHEL 8Capítulo 10
Específico para RHEL 9Capítulo 11
Específico para RHEL 10Capítulo 12
Después de migraciónCapítulos 35-36

⚙️ Comandos Específicos por Servicio

# Apache
apachectl configtest
tail -f /var/log/httpd/ssl_error_log

# NGINX
nginx -t
tail -f /var/log/nginx/error.log

# Postfix
postfix check
tail -f /var/log/maillog | grep TLS

# OpenLDAP
slapcat -b "cn=config" | grep TLS
# Nota: ¡Las claves deben ser propiedad de ldap:ldap!

# PostgreSQL
sudo -u postgres psql -c "SHOW ssl;"
# Nota: ¡Las claves deben ser propiedad de postgres:postgres!

# certmonger
getcert list
journalctl -u certmonger -f

🎯 Referencia Rápida

Problemas Más Comunes:

  1. Certificado expirado → Renovar
  2. CA faltante → Agregar al almacén de confianza
  3. Permisos incorrectos → chmod 600
  4. Desajuste cert/clave → Regenerar CSR
  5. Desajuste de hostname → Reemitir con SANs
  6. Versión TLS → Verificar crypto-policy
  7. SELinux denegando → restorecon
  8. certmonger CA_UNREACHABLE → Verificar IPA/Kerberos

Emergencia: Capítulo 33

Metodología: Capítulo 27

Guía de Referencia Rápida de Versiones RHEL para Certificados

Referencia rápida para diferencias de certificados entre versiones de RHEL.


Resumen de Versiones

RHELLanzadoOpenSSLSoporte TLSCrypto-PoliciesCaracterística Principal
720141.0.2k-261.0/1.1/1.2❌ NoConfiguración manual
820191.1.1k-141.2/1.3¡NUEVO!Políticas en todo el sistema
920223.5.5-21.2/1.3✅ MejoradoOpenSSL 3.x, estricto
1020253.5.5-21.3 pref✅ MejoradoPreparación PQC, moderno

Detección Rápida

# Verificar versión RHEL
cat /etc/redhat-release

# Verificar OpenSSL (verificación indirecta de versión)
openssl version
# 1.0.2k = RHEL 7
# 1.1.1k = RHEL 8
# 3.5.5  = RHEL 9 o 10

# Verificar crypto-policies (solo RHEL 8+)
update-crypto-policies --show 2>/dev/null || echo "RHEL 7 (sin crypto-policies)"

Configuración TLS por Versión

RHEL 7

# Configuración manual requerida en todas partes
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5:!3DES

RHEL 8/9/10

# ¡crypto-policies lo manejan automáticamente!
# No se necesitan SSLProtocol o SSLCipherSuite
# Solo incluir rutas de certificado

Comandos Comunes por Versión

TareaRHEL 7RHEL 8/9/10
Generar Claveopenssl genrsa -out key 2048openssl genpkey -algorithm RSA -out key
Verificar PolíticaN/Aupdate-crypto-policies --show
Config TLSManual por servicioAutomática vía crypto-policies
certmongerBásicoMejorado (RHEL 9: soporte ACME)

Solución de Problemas por Versión

RHEL 7

  • Verificar problemas TLS 1.0/1.1
  • Configuraciones manuales de cifrado
  • Sin crypto-policies

RHEL 8

  • ¡Verificar crypto-policy primero!
  • TLS 1.0/1.1 deshabilitado en DEFAULT
  • Política LEGACY para compatibilidad

RHEL 9

  • Problemas de proveedor OpenSSL 3.x
  • SHA-1 BLOQUEADO
  • Usar -provider legacy para algoritmos antiguos

RHEL 10

  • Igual que RHEL 9
  • Valores predeterminados aún más estrictos
  • Verificar documentación de versión menor

Impacto de Migración

MigraciónImpacto en CertificadosCambios Principales
7→8Moderado-Altocrypto-policies, TLS 1.0/1.1 bloqueado
8→9AltoOpenSSL 3.x, SHA-1 bloqueado, más estricto
9→10BajoMismo OpenSSL, fortalecimiento incremental

Soluciones Rápidas por Versión

Error “no shared cipher”

  • RHEL 7: Actualizar configuración de cifrado manualmente
  • RHEL 8/9/10: sudo update-crypto-policies --set LEGACY (¡temp!)

Certificado SHA-1

  • RHEL 7/8: Funciona (obsoleto)
  • RHEL 9/10: BLOQUEADO — debe reemitirse

Cliente TLS 1.0

  • RHEL 7: Funciona por defecto
  • RHEL 8/9/10: Bloqueado en DEFAULT, usar LEGACY (¡temp!)

Detalles Completos: Ver Capítulos 9-12

Apéndice A: cert-manager de Kubernetes

cert-manager es un proyecto CNCF que automatiza la emisión de certificados dentro de clusters Kubernetes.

1. Arquitectura

  • Issuer / ClusterIssuer – Define CA o servidor ACME.
  • Certificate – Estado deseado para un cert (nombres DNS, duración).
  • Controller – Reconcilia recursos, almacena secretos.
graph LR
  subgraph K8s
    A[Certificate] --> B[Secret TLS]
    A --> C(Issuer)
  end
  C -->|ACME| LE[Let's Encrypt]

2. Instalación

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.1/cert-manager.yaml

3. Ejemplo: TLS Ingress

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: le-key
    solvers:
    - http01:
        ingress:
          class: nginx
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: web-tls
  namespace: default
spec:
  secretName: web-tls
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  commonName: example.com
  dnsNames:
  - example.com
  - www.example.com

4. Renovación y Estado

kubectl describe certificate web-tls muestra condición Ready y próximo tiempo de renovación.


🧪 Laboratorio Práctico

Lab 21: cert-manager de Kubernetes

Automatice gestión de certificados en Kubernetes

  • 📁 Ubicación: labs/es_ES/21-kubernetes-cert-manager/
  • ⏱️ Tiempo: 50-60 minutos
  • 🎯 Nivel: Avanzado

Apéndice B: PKI de HashiCorp Vault

Vault proporciona una PKI dinámica donde los certificados se emiten bajo demanda con TTLs cortos.

1. ¿Por Qué Vault?

  • Aplicación centralizada de políticas
  • Certs dinámicos de corta duración reducen necesidades de revocación
  • Impulsado por API (REST + CLI)

2. Habilitar Motor PKI

vault secrets enable pki
vault secrets tune -max-lease-ttl=87600h pki
vault write pki/root/generate/internal common_name="corp.example" ttl=87600h
vault write pki/config/urls issuing_certificates="https://vault.corp/v1/pki/ca" \
                                    crl_distribution_points="https://vault.corp/v1/pki/crl"

3. Roles y Emisión

vault write pki/roles/web allowed_domains="web.corp" allow_subdomains=true max_ttl=72h
vault write pki/issue/web common_name=app01.web.corp ttl=24h

4. Renovación Automática Sidecar del Agente

# vault-agent.hcl
pid_file = "/var/run/agent.pid"
auto_auth {
  method "kubernetes" {
    mount_path = "auth/k8s"
    role       = "web"
  }
  sink "file" {
    config = {
      path = "/etc/tls/web.pem"
    }
  }
}

🧪 Laboratorio Práctico

Lab 22: PKI de HashiCorp Vault

Emisión dinámica de certificados con Vault

  • 📁 Ubicación: labs/es_ES/22-vault-pki/
  • ⏱️ Tiempo: 45-55 minutos
  • 🎯 Nivel: Avanzado

Apéndice C: Arquitectura Zero Trust

PKI en Arquitectura Zero Trust

Zero Trust (ZT) asume ninguna confianza implícita basada en ubicación de red. Cada solicitud debe autenticarse y autorizarse.

1. Google BeyondCorp y NIST SP 800-207

Estos marcos recomiendan identidad fuerte, cifrado de transporte y evaluación continua.

2. Rol de PKI

  • Identidad de dispositivo vía certificados.
  • mTLS para tráfico este-oeste.
  • Credenciales de corta duración auto-rotadas.

3. Perfil de Certificado para ZT

ExtensiónPropósito
SAN: URI:spiffe://ID de Carga de Trabajo
Key Usage: digitalSignatureAuthN
EKU: clientAuth, serverAuthTLS Mutuo
Validity ≤ 24hLimitar radio de explosión

4. Puntos de Aplicación de Política

  1. Gateways terminan TLS y verifican certs de cliente.
  2. Service Mesh sidecars realizan mTLS transparentemente.
  3. Agentes de Endpoint mantienen certificados de dispositivo.

5. Lab: Emitir Certificados SPIFFE con cert-manager

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: spiffe-workload
spec:
  duration: 24h
  commonName: spiffe://prod/web/api
  uriSANs:
  - spiffe://prod/web/api
  issuerRef:
    name: mesh-issuer
    kind: ClusterIssuer

Apéndice D: Integración DevSecOps

PKI en DevSecOps y CI/CD

Integrar gestión de certificados en pipelines CI/CD asegura que cada artefacto de build y entorno use identidades confiables.

1. Firmar Artefactos de Build

  • Contenedores – cosign, Notary v2.
  • Paquetes – Firmas GPG RPM/DEB.
  • Binarios – Windows Authenticode.

2. TLS Automatizado para Entornos de Vista Previa

Los pipelines activan cert-manager para emitir certs efímeros para branches de corta duración.

3. Ejemplo: GitHub Actions con cosign

name: Build & Sign
on: push
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Build image
      run: docker build -t ghcr.io/org/app:${{ github.sha }} .
    - name: Login registry
      run: echo ${{ secrets.GH_TOKEN }} | docker login ghcr.io -u user --password-stdin
    - name: Push image
      run: docker push ghcr.io/org/app:${{ github.sha }}
    - name: Sign image
      env:
        COSIGN_EXPERIMENTAL: "1"
        COSIGN_KEY: ${{ secrets.COSIGN_KEY }}
      run: cosign sign -key env://COSIGN_KEY ghcr.io/org/app:${{ github.sha }}

4. Puertas de Política

Los escáneres de seguridad de cadena de suministro verifican firmas y aplican política antes de desplegar.

5. Gestión de Secretos

Almacenar claves privadas para firma en HashiCorp Vault o AWS KMS, no en secretos de repo.

Apéndice E: Teoría de Políticas PKI

Políticas, Líneas Base y Auditorías

1. Por Qué Importan las Políticas

Las políticas formalizan cómo pueden emitirse y usarse los certificados, asegurando consistencia y defensa legal.

2. Requisitos de Línea Base (CAB Forum)

Requisitos que las CAs públicamente confiables deben seguir, incluyendo:

  • Métodos de validación de dominio
  • Tamaños de clave ≥ RSA 2048 bits / ECC 256 bits
  • Validez máxima 398 días

3. Política de Certificado (CP) vs CPS

DocumentoAudienciaContenido
CPPartes confiantesQué aseguramiento proporciona la PKI
CPSAuditores, operadoresCómo la CA cumple la CP

4. Auditorías y Cumplimiento

  • Auditorías WebTrust / ETSI para CAs públicas.
  • PKIs internas pueden alinearse con NIST SP 800-53 o ISO 27001.

5. Caso de Estudio RHEL

El certmonger de RHEL puede renovar automáticamente certificados de host de acuerdo con pautas CP/CPS empresariales.

Apéndice F: Certificados IoT

Certificados de Dispositivos IoT

Los dispositivos Internet de las Cosas requieren identidades únicas para comunicación segura. Los certificados proporcionan prueba criptográfica de autenticidad del dispositivo.

1. ¿Por Qué Certificados para IoT?

  • Identidad de Dispositivo – Cada sensor, gateway o actuador obtiene un cert único.
  • Redes Zero-Trust – Los dispositivos se autentican mutuamente con nube/edge.
  • Seguridad de Cadena de Suministro – Certificados aprovisionados en fabricación previenen clonación.
  • Actualizaciones OTA – La firma de código asegura integridad del firmware.

2. Modelos de Aprovisionamiento de Certificados

Aprovisionamiento de Fábrica

Certificados grabados en almacenamiento seguro del dispositivo (TPM, elemento seguro) antes del envío.

sequenceDiagram
    Factory->>HSM: Generar par de claves
    HSM->>Factory: Retornar CSR
    Factory->>CA: Firmar CSR
    CA-->>Factory: Certificado
    Factory->>Device: Inyectar cert + clave privada

Aprovisionamiento Justo a Tiempo

El dispositivo genera clave en primer arranque, envía CSR a servicio de registro.

# El dispositivo genera clave
openssl ecparam -genkey -name prime256v1 -out device.key

# Crear CSR con serial del dispositivo
openssl req -new -key device.key -out device.csr -subj "/CN=device-12345/serialNumber=12345"

# Enviar a API de inscripción
curl -X POST https://enroll.iot.example.com/csr \
  -H "Authorization: Bearer $ENROLL_TOKEN" \
  --data-binary @device.csr -o device.crt

3. AWS IoT Core

Registrar Certificado de Dispositivo

# Generar clave y CSR
openssl ecparam -genkey -name prime256v1 -out iot-device.key
openssl req -new -key iot-device.key -out iot-device.csr -subj "/CN=iot-device-001"

# Usar AWS CLI para firmar
aws iot create-certificate-from-csr --certificate-signing-request file://iot-device.csr \
  --set-as-active > cert-response.json

# Extraer certificado
jq -r '.certificatePem' cert-response.json > iot-device.crt

Adjuntar Política

aws iot attach-policy --policy-name IoTDevicePolicy --target arn:aws:iot:region:account:cert/certId

Conexión MQTT

import paho.mqtt.client as mqtt
import ssl

client = mqtt.Client()
client.tls_set(
    ca_certs="AmazonRootCA1.pem",
    certfile="iot-device.crt",
    keyfile="iot-device.key",
    tls_version=ssl.PROTOCOL_TLSv1_2
)
client.connect("xxxxxx.iot.us-east-1.amazonaws.com", 8883)
client.publish("device/telemetry", "{'temp': 22.5}")

4. Azure IoT Hub

Autenticación X.509 de Dispositivo

# Generar cert de dispositivo firmado por CA personalizada
openssl req -new -key device.key -out device.csr -subj "/CN=device-001"
openssl x509 -req -in device.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out device.crt -days 365 -sha256

# Cargar CA a Azure IoT Hub (portal o CLI)
az iot hub certificate create --hub-name MyIoTHub --name MyCACert --path ca.crt

# Conectar dispositivo
from azure.iot.device import IoTHubDeviceClient

device_client = IoTHubDeviceClient.create_from_x509_certificate(
    hostname="MyIoTHub.azure-devices.net",
    device_id="device-001",
    x509=X509(cert_file="device.crt", key_file="device.key")
)
device_client.connect()
device_client.send_message("Hola desde device-001")

5. Microchip ATECC608 Elemento Seguro

Chip crypto de hardware almacena claves privadas que nunca salen del silicio.

Flujo de Aprovisionamiento

  1. El dispositivo genera par de claves dentro de ATECC608.
  2. CSR creado usando clave en chip.
  3. CA firma CSR, certificado almacenado en EEPROM del dispositivo.
// Ejemplo Arduino con biblioteca ATECC
#include <ArduinoECCX08.h>

void setup() {
  ECCX08.begin();

  // Generar CSR
  byte csr[256];
  ECCX08.getCSR(csr);

  // Enviar CSR a CA vía HTTP/MQTT
  // Recibir certificado firmado
  // Almacenar en EEPROM
}

6. Rotación de Certificados para Dispositivos Restringidos

Certificados de Corta Duración

Emitir certs de 7 días con renovación automatizada vía protocolos ligeros como EST (RFC 7030).

# Inscripción simple EST
curl --cacert ca.crt --cert current-device.crt --key device.key \
  https://est.example.com/.well-known/est/simpleenroll \
  --data-binary @new-device.csr -o renewed-device.crt

Certificados Bootstrap

Cert inicial de larga duración usado solo para inscripción, luego reemplazado por certs operacionales de corta duración.

7. LoRaWAN y Secure Join

LoRaWAN 1.1+ soporta secure join con claves específicas de dispositivo derivadas de certificados:

Dispositivo → JoinRequest (firmado con cert DevEUI)
Network Server → JoinAccept (claves de sesión cifradas)

8. Resumen de Mejores Prácticas

PrácticaRazón
Usar ECC (P-256, P-384)Claves más pequeñas, menor consumo de energía
Hardware Root of TrustTPM, ATECC, o TrustZone previenen extracción de clave
Validez de Certificado ≤ 1 añoLimitar radio de explosión de compromiso
Revocación vía OCSP/CRLDeshabilitar dispositivos comprometidos remotamente
PKI Separada para IoTAislar CA de dispositivo de IT empresarial

9. Despliegues del Mundo Real

  • Automotriz – ECUs de vehículo usan certificados para comunicación V2X (IEEE 1609.2).
  • IoT Industrial – PLCs y dispositivos SCADA autenticados vía IEC 62351.
  • Smart Home – El protocolo Matter exige certificados X.509 para comisionamiento de dispositivo.

Consejo de Seguridad: Nunca embeber la misma clave privada en múltiples dispositivos. Cada dispositivo debe tener un certificado único para habilitar revocación selectiva.

Apéndice G: Certificados VPN

Certificados VPN — OpenVPN, WireGuard e IPsec

Las Redes Privadas Virtuales usan certificados para autenticar endpoints y establecer túneles cifrados.

1. OpenVPN con PKI

Configurar Easy-RSA

git clone https://github.com/OpenVPN/easy-rsa.git
cd easy-rsa/easyrsa3
./easyrsa init-pki
./easyrsa build-ca nopass
./easyrsa gen-req server nopass
./easyrsa sign-req server server
./easyrsa gen-req client1 nopass
./easyrsa sign-req client client1
./easyrsa gen-dh
openvpn --genkey secret ta.key

Configuración de Servidor

/etc/openvpn/server.conf:

port 1194
proto udp
dev tun

ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/server.crt
key /etc/openvpn/pki/private/server.key
dh /etc/openvpn/pki/dh.pem
tls-auth /etc/openvpn/ta.key 0

server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"

cipher AES-256-GCM
auth SHA256
user nobody
group nobody
persist-key
persist-tun

status /var/log/openvpn-status.log
verb 3

Iniciar:

sudo systemctl enable --now openvpn-server@server

Configuración de Cliente

client1.ovpn:

client
dev tun
proto udp
remote vpn.example.com 1194

ca ca.crt
cert client1.crt
key client1.key
tls-auth ta.key 1

cipher AES-256-GCM
auth SHA256
verb 3

Conectar:

sudo openvpn --config client1.ovpn

2. WireGuard (Sin Certificados pero Basado en Claves)

WireGuard usa claves públicas Curve25519 en lugar de certificados X.509. Sin embargo, puedes envolver claves WireGuard en certificados para gestión de identidad empresarial.

Generar Claves

wg genkey | tee privatekey | wg pubkey > publickey

Configuración de Servidor

/etc/wireguard/wg0.conf:

[Interface]
PrivateKey = <server-private-key>
Address = 10.9.0.1/24
ListenPort = 51820

[Peer]
PublicKey = <client-public-key>
AllowedIPs = 10.9.0.2/32

Habilitar:

sudo systemctl enable --now wg-quick@wg0

Configuración de Cliente

[Interface]
PrivateKey = <client-private-key>
Address = 10.9.0.2/24
DNS = 8.8.8.8

[Peer]
PublicKey = <server-public-key>
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Conectar:

sudo wg-quick up wg0

3. IPsec (strongSwan) con X.509

Instalar strongSwan

sudo dnf install strongswan -y

Generar Certificados

# CA
ipsec pki --gen --type rsa --size 4096 --outform pem > ca.key.pem
ipsec pki --self --ca --lifetime 3650 --in ca.key.pem --type rsa \
  --dn "CN=VPN CA" --outform pem > ca.crt.pem

# Cert de servidor
ipsec pki --gen --type rsa --size 2048 --outform pem > server.key.pem
ipsec pki --req --type priv --in server.key.pem --dn "CN=vpn.example.com" \
  --san vpn.example.com --outform pem > server.req.pem
ipsec pki --issue --cacert ca.crt.pem --cakey ca.key.pem --type pkcs10 \
  --in server.req.pem --lifetime 365 --outform pem > server.crt.pem

# Cert de cliente
ipsec pki --gen --type rsa --size 2048 --outform pem > client.key.pem
ipsec pki --req --type priv --in client.key.pem --dn "CN=client@example.com" \
  --outform pem > client.req.pem
ipsec pki --issue --cacert ca.crt.pem --cakey ca.key.pem --type pkcs10 \
  --in client.req.pem --lifetime 365 --outform pem > client.crt.pem

Copiar a /etc/ipsec.d/:

sudo cp ca.crt.pem /etc/ipsec.d/cacerts/
sudo cp server.crt.pem /etc/ipsec.d/certs/
sudo cp server.key.pem /etc/ipsec.d/private/

Configuración de Servidor

/etc/ipsec.conf:

config setup
    charondebug="ike 2, knl 2, cfg 2"

conn %default
    ikelifetime=60m
    keylife=20m
    rekeymargin=3m
    keyingtries=1
    keyexchange=ikev2
    authby=pubkey

conn rw
    leftcert=server.crt.pem
    leftid=@vpn.example.com
    leftsubnet=0.0.0.0/0
    leftfirewall=yes
    right=%any
    rightid=%any
    rightsourceip=10.10.10.0/24
    auto=add

Iniciar:

sudo systemctl enable --now strongswan

Configuración de Cliente

Instalar cert/clave de cliente, luego conectar vía NetworkManager o línea de comandos.

4. Revocación de Certificados en VPNs

CRL de OpenVPN

./easyrsa revoke client1
./easyrsa gen-crl

Actualizar server.conf:

crl-verify /etc/openvpn/pki/crl.pem

OCSP de strongSwan

En /etc/ipsec.conf:

conn rw
    leftcert=server.crt.pem
    leftsendcert=always
    rightca="CN=VPN CA"
    rightcert=*
    ocsp_uri=http://ocsp.example.com

5. Comparación

VPNSoporte CertificadoGestión de ClavesCaso de Uso
OpenVPNPKI X.509 completaEasy-RSA, manualSitio-a-sitio empresarial y acceso remoto
WireGuardClaves públicas (no X.509 por defecto)Pares de claves simplesModerno, alto rendimiento, IoT
IPsec (strongSwan)PKI X.509 completaHerramientas ipsec pkiConforme a estándares, interop con Cisco/Juniper

6. Mejores Prácticas

  1. CA Separada para VPN – Aislar certs VPN de certs TLS web.
  2. Validez Corta – Emitir certs de cliente VPN con expiración 30-90 días.
  3. CRL/OCSP – Habilitar verificación de revocación en el servidor.
  4. Tokens de Hardware – Almacenar claves de cliente en YubiKeys o smartcards para trabajadores remotos.

Mundo real: Muchas organizaciones migran de OpenVPN a WireGuard por rendimiento pero envuelven claves WireGuard en X.509 para integración con sistemas IAM existentes.

Apéndice H: Secure Boot y Uso de Certificados

Secure Boot, cadenas de confianza y operaciones con certificados en RHEL

Secure Boot es donde el firmware, los cargadores de arranque, los kernels y el código cargado por el kernel dejan de ser “simples archivos en disco” y se convierten en objetos de código autenticados. Si entiendes los certificados TLS pero no Secure Boot, te falta una gran parte de cómo realmente comienza la confianza en un sistema moderno.

Este apéndice se centra en tres cosas:

  1. Qué hace realmente Secure Boot.
  2. Dónde se usan certificados y claves en la cadena de arranque.
  3. Cómo RHEL usa shim, GRUB, mokutil, pesign, los keyrings del kernel y la firma de módulos en despliegues reales.

1. Qué es Secure Boot

UEFI Secure Boot es un modelo de verificación de firmas respaldado por firmware para la ruta de arranque. El firmware comprueba si un ejecutable EFI está firmado por una clave o certificado de confianza antes de permitir su ejecución.

Eso significa que Secure Boot no es lo mismo que:

  • Cifrado de disco completo
  • Secretos sellados con TPM
  • Measured Boot
  • Monitoreo de integridad de archivos
  • Lista blanca de aplicaciones en espacio de usuario
  • Confianza TLS para servicios web

Secure Boot trata específicamente de autorizar código durante la ruta de arranque y para extensiones del espacio del kernel, como los módulos de kernel cargables.

En términos simples, la pregunta que Secure Boot formula es:

“¿Debería confiarse en este componente de firmware, binario EFI, cargador de arranque, kernel o módulo para su ejecución?”

2. Por qué los certificados importan en Secure Boot

Los certificados son el mecanismo de transporte de la confianza. Vinculan una clave pública a una identidad o contexto de política para que un verificador pueda decidir si una firma debe ser aceptada.

En el ecosistema de Secure Boot, los certificados y las claves se usan en diferentes lugares:

UbicaciónPropósito
Variables de firmware UEFIAlmacenan anclas de confianza de la plataforma y revocaciones
shimContiene confianza embebida del proveedor para verificación de la siguiente etapa
Keyrings del kernelMantienen claves de confianza usadas para autenticar módulos y artefactos relacionados
Lista MOKAñade confianza controlada por el propietario sin reescribir las bases de datos del firmware
Bloques de firma en binarios EFIDemuestran que los componentes de arranque fueron firmados por una clave privada de confianza

Este es un dominio de confianza diferente al almacén de confianza TLS de RHEL en /etc/pki/ca-trust/. Ese almacén de confianza es para operaciones PKI en espacio de usuario como HTTPS, LDAPS, SMTP TLS, obtención de paquetes y validación de aplicaciones. No decide qué binario EFI arranca el firmware.

3. El modelo de confianza de UEFI Secure Boot

3.1 Bases de datos principales del firmware

UEFI Secure Boot gira comúnmente en torno a cuatro bases de datos importantes respaldadas por variables:

Base de datosSignificadoRol típico
PKPlatform KeyPropietario de nivel superior de la política de Secure Boot de la plataforma
KEKKey Exchange Key databaseAutoriza actualizaciones a las bases de datos de firmas permitidas y revocadas
dbFirmas / certificados permitidosLista de confianza para ejecutables y controladores EFI
dbxFirmas / certificados / hashes prohibidosLista de revocación usada para bloquear binarios o certificados conocidos como maliciosos

Son conceptualmente simples, pero los administradores los confunden rutinariamente:

  • PK controla la autoridad de Secure Boot de la plataforma.
  • KEK controla las actualizaciones de la lista de permitidos y la lista de denegados.
  • db indica qué está permitido arrancar.
  • dbx indica qué nunca debe ser aceptado, incluso si alguna vez fue de confianza.

3.2 Setup Mode vs User Mode

El firmware UEFI generalmente tiene diferentes estados operacionales:

  • Setup Mode: la propiedad de la plataforma no está finalizada; los cambios de inscripción de claves son posibles.
  • User Mode: la política de Secure Boot se aplica activamente usando las claves instaladas.
  • Custom Mode: modo específico del proveedor que puede permitir la gestión manual de claves.

Esto importa porque la gente a menudo confunde “Secure Boot habilitado en los menús del firmware” con “Secure Boot completamente aplicado con la política de confianza esperada.” No siempre son el mismo estado.

4. Qué se firma realmente

Secure Boot no es una firma sobre “el sistema.” Es una cadena de objetos firmados o confiados por separado.

Los objetos autenticados comunes incluyen:

  • Aplicaciones EFI
  • Cargadores de arranque EFI
  • Binarios EFI de GRUB
  • Kernels de Linux
  • Módulos de kernel cargables
  • A veces ejecutables de actualización de firmware del proveedor

El hecho de que un componente participe en el arranque no significa que esté firmado de forma independiente de la misma manera. Por ejemplo:

  • Los binarios EFI se autentican típicamente como ejecutables PE/COFF con firmas embebidas.
  • Los módulos del kernel se firman de una manera específica de Linux y son verificados por el kernel contra claves X.509 de confianza.
  • El initramfs es parte del flujo de arranque, pero en el modelo clásico de Secure Boot de RHEL no es simplemente “otro ejecutable EFI firmado con PE de forma independiente.”

Esa distinción importa. La documentación descuidada difumina todo en “toda la cadena de arranque está firmada.” Eso no es lo suficientemente preciso para solucionar problemas o diseñar políticas.

5. Cadena de confianza de Secure Boot en RHEL

5.1 Flujo de alto nivel

En un sistema RHEL típico con UEFI Secure Boot habilitado:

  1. El firmware valida el cargador de arranque EFI de primera etapa contra las claves de confianza en las bases de datos del firmware.
  2. El cargador de primera etapa es típicamente shim.
  3. shim contiene un ancla de confianza embebida de Red Hat usada para autenticar la siguiente etapa.
  4. shim valida el binario EFI de GRUB de RHEL.
  5. GRUB valida el kernel que carga usando la clave pública embebida en shim (GRUB no lleva sus propias claves de confianza).
  6. El kernel usa sus keyrings de confianza para validar los módulos de kernel cargables y otro código del espacio del kernel.

Eso te da una cadena de autorización desde el firmware hasta la extensibilidad del espacio del kernel.

5.2 Por qué existe shim

shim existe porque los fabricantes de hardware envían ampliamente sistemas con raíces de firma UEFI confiadas por Microsoft ya inscritas. Red Hat puede por lo tanto tener el cargador de primera etapa firmado para que sea aceptado por hardware comercial sin pedir a cada fabricante de hardware que preinstale un ancla de confianza de firmware exclusiva de Red Hat.

Después de que el firmware acepta shim, shim se convierte en el puente entre la confianza del firmware y la confianza del sistema operativo del proveedor.

En la práctica en RHEL:

  • El firmware confía en la ruta de firma reconocida por Microsoft para shim.
  • shim contiene un certificado CA de Secure Boot de Red Hat embebido.
  • Ese certificado embebido de Red Hat se usa para validar GRUB y el kernel.

5.3 Por qué RHEL no depende de la carga arbitraria de módulos de GRUB

Bajo Secure Boot, RHEL no quiere que se cargue código arbitrario sin firmar dentro del perímetro de seguridad del cargador de arranque. La documentación de Red Hat explica que la carga de módulos de GRUB está deshabilitada en contextos de Secure Boot porque no existe un modelo de firma y verificación de propósito general para módulos de GRUB arbitrarios equivalente a la ruta firmada controlada que Red Hat distribuye.

El punto operacional es simple:

  • Si estás en un sistema con Secure Boot, no asumas que “GRUB puede simplemente cargar cualquier cosa desde el disco.”
  • Todo el diseño intenta mantener el código sin firmar fuera de la ruta de arranque.

6. Certificados y claves usados por Secure Boot en RHEL

6.1 Certificados del firmware

La confianza del firmware proviene de claves y certificados almacenados en variables UEFI (PK, KEK, db, dbx) como se describe en la sección 3.1. Estos no se gestionan con update-ca-trust.

6.2 Certificado embebido en shim

La documentación de Red Hat para RHEL 8/9/10 describe shim como contenedor de un certificado público de Red Hat usado para autenticar GRUB y el kernel. Esta confianza embebida es una de las razones por las que shim es central en el diseño de Secure Boot de RHEL.

6.3 Machine Owner Key (MOK)

La facilidad Machine Owner Key es la válvula de escape práctica que mantiene Secure Boot usable en el mundo real.

Sin MOK, estarías atrapado entre dos malas opciones:

  1. Deshabilitar Secure Boot cada vez que necesites código personalizado.
  2. Convencer a tu fabricante de hardware de que añada permanentemente tu certificado público a las bases de datos del firmware.

MOK proporciona una tercera opción:

  • Inscribes tu propio certificado público en el sistema.
  • shim y MokManager gestionan esa inscripción.
  • En el arranque, la clave se propaga a un keyring de confianza del kernel para que tus componentes personalizados firmados puedan ser aceptados.

6.4 Keyrings del kernel

En RHEL moderno, la verificación de firmas de módulos del kernel depende de los keyrings del kernel, principalmente:

KeyringRol
.builtin_trusted_keysClaves de confianza integradas embebidas en el kernel o cargadas como parte de la ruta de arranque de confianza
.platformConfianza derivada de la plataforma, incluyendo claves provenientes de las bases de datos de Secure Boot y MOK
.blacklistClaves y hashes revocados que deben ser rechazados

La documentación de RHEL para la firma de módulos señala explícitamente:

  • las firmas de módulos se verifican contra claves X.509 de confianza de .builtin_trusted_keys y .platform
  • las entradas revocadas de la blacklist se excluyen de la verificación
  • las claves MOK se propagan a .platform en arranques con Secure Boot habilitado

Eso significa que la confianza es aditiva, pero la revocación siempre prevalece.

7. Qué protege y qué no protege Secure Boot

7.1 Qué protege

Secure Boot está diseñado para reducir la posibilidad de que el sistema ejecute código no autorizado en la ruta de arranque, como:

  • binarios EFI manipulados
  • cargadores de arranque maliciosos
  • kernels modificados
  • módulos del kernel sin firmar o no confiables

7.2 Qué no resuelve automáticamente

Secure Boot no protege automáticamente:

  • binarios de espacio de usuario
  • scripts de shell
  • archivos de configuración
  • secretos en reposo
  • manipulación de memoria en tiempo de ejecución después de que un sistema ya ha sido comprometido
  • identidad de servidor TLS para servicios
  • escalación de privilegios local a través de código firmado pero vulnerable

Secure Boot es un control de autorización de arranque. No es un marco completo de integridad del host.

7.3 Secure Boot vs Measured Boot vs TPM

La gente mezcla estos conceptos porque todos tocan la confianza en el arranque. Eso es pensar con pereza.

Están relacionados, pero son diferentes:

CaracterísticaFunción principal
Secure BootBloquea la ejecución de código no autorizado en la ruta de arranque
Measured BootRegistra mediciones de arranque en los PCRs del TPM
TPMAlmacena secretos protegidos y mediciones; puede sellar datos al estado del arranque
IMA appraisalExtiende la política de integridad más allá del arranque temprano hacia la evaluación de archivos y decisiones de carga en tiempo de ejecución

Una implicación práctica en RHEL:

  • Secure Boot decide si el código es aceptado para arrancar o cargarse.
  • Los flujos de trabajo basados en TPM pueden depender de valores de PCR que reflejan la política de Secure Boot y el estado de las bases de datos del firmware.

Si las claves del firmware o las bases de datos de revocación cambian, las mediciones del TPM también pueden cambiar. Eso importa para el desbloqueo automático de LUKS, la atestación y los flujos de trabajo con secretos sellados.

8. Kernel Lockdown en RHEL

En RHEL, arrancar en modo EFI Secure Boot activa el comportamiento de kernel lockdown. Esto es importante porque Secure Boot por sí solo no es suficiente si el kernel en ejecución aún expone interfaces que permiten a usuarios privilegiados manipular la memoria del kernel o evadir decisiones de confianza.

Lockdown está diseñado para cerrar esa brecha.

Las restricciones típicas incluyen límites o bloqueos directos sobre cosas como:

  • cargar módulos sin firmar
  • rutas de modificación directa de la imagen del kernel
  • interfaces de acceso directo como /dev/mem
  • algunas rutas de kexec sin firmar
  • interfaces que podrían debilitar el límite de confianza del arranque

Por eso los administradores a veces ven mensajes como:

Lockdown: X: Y is restricted; see man kernel_lockdown.7

Eso no es drama aleatorio del kernel. Es la política de Secure Boot extendiéndose hacia la aplicación en tiempo de ejecución.

9. El modelo mental del administrador de RHEL

Si solo vas a retener un modelo en tu cabeza, que sea este:

  1. El firmware confía en las claves en db y rechaza claves o hashes en dbx.
  2. El firmware autoriza shim.
  3. shim autoriza los componentes de arranque de la siguiente etapa de Red Hat y también soporta operaciones MOK.
  4. MOK te permite añadir certificados públicos controlados por el propietario.
  5. El kernel confía en claves integradas y derivadas de la plataforma/MOK para la verificación de módulos.
  6. Lockdown previene evasiones obvias en tiempo de ejecución.

Si cualquiera de esos pasos está roto, tu flujo de trabajo personalizado de arranque o módulos falla.

10. Secure Boot en RHEL: verificaciones operacionales diarias

10.1 Comprobar si Secure Boot está habilitado

sudo mokutil --sb-state

La salida típica es algo como:

SecureBoot enabled

10.2 Comprobar mensajes de Secure Boot e integridad en el log del kernel

sudo dmesg | grep -Ei 'secure boot|integrity|lockdown|EFI: Loaded cert'

En sistemas RHEL, los mensajes del log de integridad a menudo muestran de dónde provienen las claves, como:

  • UEFI:db
  • shim embebido
  • UEFI:MokListRT

10.3 Listar claves de confianza de la plataforma

sudo keyctl list %:.platform
sudo keyctl list %:.builtin_trusted_keys
sudo keyctl list %:.blacklist

Lo que debes buscar:

  • certificados derivados del firmware
  • certificados inscritos mediante MOK
  • hashes o claves revocadas en .blacklist

10.4 Inspeccionar firmas en binarios EFI

En RHEL, pesign es la herramienta soportada para inspeccionar y añadir firmas a los binarios EFI relevantes:

sudo pesign --show-signature --in /boot/efi/EFI/redhat/shimx64.efi
sudo pesign --show-signature --in /boot/efi/EFI/redhat/grubx64.efi

En sistemas AArch64, los nombres comúnmente cambian a shimaa64.efi y grubaa64.efi.

11. Paquetes y herramientas clave de RHEL

Al trabajar con firma personalizada de Secure Boot en RHEL 8/9/10, la documentación de Red Hat se centra en estas herramientas:

sudo dnf install pesign openssl kernel-devel mokutil keyutils

Roles principales:

HerramientaPropósito
pesignFirmar e inspeccionar binarios EFI y kernels
efikeygenGenerar un par de claves X.509 orientado a Secure Boot en la base de datos de pesign
mokutilInscribir e inspeccionar Machine Owner Keys y el estado de Secure Boot
keyctlInspeccionar keyrings del kernel
sign-fileAñadir firmas a módulos del kernel de Linux
certutil / pk12utilExportar claves y certificados desde la base de datos NSS usada por pesign
opensslExtraer o transformar material de claves cuando sea necesario

12. Generar una clave personalizada de Secure Boot en RHEL

12.1 Generar una clave para firma de módulos

La documentación de Red Hat indica efikeygen como la forma estándar de crear un par X.509 autofirmado para flujos de trabajo de Secure Boot:

sudo efikeygen \
  --dbdir /etc/pki/pesign \
  --self-sign \
  --module \
  --common-name 'CN=Organization signing key' \
  --nickname 'Custom Secure Boot key'

12.2 Generar una clave para firma de kernels

sudo efikeygen \
  --dbdir /etc/pki/pesign \
  --self-sign \
  --kernel \
  --common-name 'CN=Organization signing key' \
  --nickname 'Custom Secure Boot key'

12.3 Nota sobre FIPS

La documentación de Red Hat señala que en modo FIPS puede ser necesario especificar el token NSS explícitamente:

sudo efikeygen \
  --dbdir /etc/pki/pesign \
  --self-sign \
  --kernel \
  --common-name 'CN=Organization signing key' \
  --nickname 'Custom Secure Boot key' \
  --token 'NSS FIPS 140-2 Certificate DB'

El material generado se almacena bajo /etc/pki/pesign/.

13. Inscripción del certificado público con MOK

Este es el paso que la gente se salta, y luego pierde horas culpando a Secure Boot en lugar de a su propio proceso.

Generar una clave no es suficiente. El sistema de destino debe confiar en el certificado público correspondiente.

13.1 Exportar el certificado público

sudo certutil -d /etc/pki/pesign \
  -n 'Custom Secure Boot key' \
  -Lr > sb_cert.cer

13.2 Importarlo en MOK

sudo mokutil --import sb_cert.cer

Se te pedirá que establezcas una contraseña temporal de inscripción.

13.3 Reiniciar y completar la inscripción

En el siguiente arranque:

  1. shim detecta la inscripción pendiente.
  2. MokManager.efi se inicia.
  3. Eliges Enroll MOK.
  4. Introduces la contraseña que estableciste durante mokutil --import.
  5. El certificado se añade a la lista MOK persistente.

Una vez inscrito en un sistema con Secure Boot habilitado, la clave se propaga al keyring .platform en los arranques posteriores.

14. Firma de módulos de kernel personalizados en RHEL

Esta es una de las tareas de Secure Boot más comunes en el mundo real. Los controladores fuera del árbol, módulos de proveedores, agentes HBA, sondas de monitoreo o productos de seguridad a menudo fallan aquí.

14.1 Exportar el certificado público

Exporta el certificado público como se describe en la sección 13.1 para producir sb_cert.cer.

14.2 Exportar la clave privada desde la base de datos NSS

sudo pk12util -o sb_cert.p12 \
  -n 'Custom Secure Boot key' \
  -d /etc/pki/pesign

Luego extrae la clave privada:

openssl pkcs12 \
  -in sb_cert.p12 \
  -out sb_cert.priv \
  -nocerts \
  -noenc

Eso produce una clave privada sin cifrar. Trata ese archivo como un arma cargada, porque eso es lo que es.

14.3 Firmar el módulo

sudo /usr/src/kernels/$(uname -r)/scripts/sign-file \
  sha256 \
  sb_cert.priv \
  sb_cert.cer \
  my_module.ko

Esto añade la firma del módulo directamente al archivo del módulo del kernel.

14.4 Verificar el firmante

modinfo my_module.ko | grep signer

14.5 Cargar el módulo

sudo insmod my_module.ko

o después de colocarlo bajo el árbol de módulos:

sudo cp my_module.ko /lib/modules/$(uname -r)/extra/
sudo depmod -a
sudo modprobe my_module

14.6 Advertencia operacional sobre fechas de validez

La documentación de Red Hat advierte a los administradores que firmen kernels y módulos dentro del período de validez del certificado y también señala que sign-file no advierte sobre malas decisiones de temporización. No trates la ausencia de una advertencia de la herramienta como prueba de que tu flujo de trabajo de firma es correcto.

15. Firma de kernels y binarios EFI en RHEL

15.1 Firmar un kernel en x86_64

sudo pesign \
  --certificate 'Custom Secure Boot key' \
  --in vmlinuz-version \
  --sign \
  --out vmlinuz-version.signed

Inspeccionar el resultado:

sudo pesign --show-signature --in vmlinuz-version.signed

Reemplazar la imagen sin firmar con la firmada:

sudo mv vmlinuz-version.signed vmlinuz-version

Si omites este paso, el sistema aún arranca la original sin firmar.

15.2 Firmar un binario EFI de GRUB en x86_64

sudo pesign \
  --in /boot/efi/EFI/redhat/grubx64.efi \
  --out /boot/efi/EFI/redhat/grubx64.efi.signed \
  --certificate 'Custom Secure Boot key' \
  --sign

Inspeccionar el resultado:

sudo pesign --in /boot/efi/EFI/redhat/grubx64.efi.signed --show-signature

Reemplazar el binario sin firmar con el firmado:

sudo mv /boot/efi/EFI/redhat/grubx64.efi.signed /boot/efi/EFI/redhat/grubx64.efi

15.3 Nota sobre AArch64

En sistemas AArch64, trabajarás típicamente con:

  • /boot/efi/EFI/redhat/shimaa64.efi
  • /boot/efi/EFI/redhat/grubaa64.efi

La documentación de RHEL también cubre el flujo de trabajo de descompresión/recompresión para firmar imágenes del kernel en ARM de 64 bits.

16. Dónde aparece la confianza de Secure Boot dentro del kernel RHEL en ejecución

La documentación de RHEL muestra que un sistema con Secure Boot habilitado puede exponer evidencia de fuentes de confianza cargadas tanto en los logs del kernel como en los keyrings.

Ejemplos de lo que puedes ver:

  • Entradas de certificados de Microsoft provenientes de UEFI db
  • Claves de Secure Boot de Red Hat provenientes de shim embebido
  • Claves inscritas por el propietario provenientes de MokListRT
  • Revocaciones reflejadas en .blacklist

Eso te da tres fuentes de confianza diferentes en juego:

  1. Confianza del firmware
  2. Confianza embebida del proveedor
  3. Confianza añadida por el propietario

Si no sabes cuál de las tres está usando tu sistema para un módulo o binario EFI dado, estás solucionando problemas a ciegas.

17. Revocación de Secure Boot y dbx

La revocación es de donde provienen muchos de los incidentes de “pero antes funcionaba.”

La base de datos dbx contiene firmas, certificados o hashes revocados. Si un objeto encadena hacia una entrada revocada, el sistema lo rechaza incluso si antes era de confianza.

Consecuencias operacionales:

  • los cargadores de arranque antiguos pueden dejar de funcionar después de actualizaciones de revocación
  • las firmas vulnerables o deprecadas pueden volverse inaceptables
  • los sistemas de laboratorio que nunca reciben actualizaciones de firmware derivan hacia estados de compatibilidad extraños
  • las cadenas de arranque personalizadas se rompen si las anclaste a algo que luego aparece en los datos de revocación

Dentro de Linux, las entradas revocadas se representan a través del keyring blacklist. Por eso la confianza sola no es suficiente; el objeto también debe no estar revocado.

18. Expiración del certificado de Secure Boot de Microsoft 2011

El certificado de firma Microsoft UEFI CA 2011, que ha sido el ancla de confianza principal usada por el firmware para validar shim en prácticamente todo el hardware comercial x86_64, está programado para expirar el 27 de junio de 2026.

Esto no significa que los sistemas existentes dejen de arrancar inmediatamente. Los sistemas que ya tienen el certificado 2011 inscrito en el firmware db continuarán aceptando binarios firmados con ese certificado después de la fecha de expiración. Sin embargo, Microsoft ya no firmará nuevos binarios con la clave 2011 después de la expiración, por lo que las futuras actualizaciones de shim deben estar firmadas con el certificado de reemplazo Microsoft UEFI CA 2023.

18.1 Qué ha hecho Red Hat

Red Hat publicó nuevos binarios de shim para todas las versiones soportadas de RHEL 8, RHEL 9 y RHEL 10 en x86_64 que están doblemente firmados con los certificados de firma de Secure Boot de Microsoft 2011 y Microsoft 2023. Esto significa que el nuevo shim arrancará en sistemas que tengan cualquiera de los dos certificados o ambos inscritos en el firmware.

En AArch64, a partir de RHEL 9.7 y RHEL 10.0, el binario shim está firmado únicamente con el certificado Microsoft 2023.

18.2 Comprobar qué certificado firmó tu shim

sudo pesign -S -i /boot/efi/EFI/redhat/shimx64.efi

Si ves Microsoft Windows UEFI Driver Publisher, esa es la ruta del certificado 2011. Si ves referencias al certificado 2023, el sistema está usando la ruta de firma actualizada.

18.3 Qué deben hacer los administradores

  1. Actualizar shim en todos los sistemas RHEL soportados para obtener la versión con doble firma antes de depender de actualizaciones de firmware que añadan el certificado 2023.
  2. Estar atentos a las actualizaciones de firmware de los fabricantes de hardware que inscriban el certificado Microsoft 2023 en la UEFI db. Sin el certificado 2023 en el firmware, los futuros binarios de shim firmados solo con la clave 2023 no serán aceptados.
  3. Tener en cuenta el impacto en el TPM: las actualizaciones de UEFI db cambiarán los valores del Platform Configuration Register (PCR) del TPM, particularmente PCR7. Si usas desbloqueo automático basado en TPM para volúmenes cifrados con LUKS, atestación de Measured Boot o secretos sellados contra PCR7, esas vinculaciones se romperán después de los cambios en db. El enfoque recomendado es primero resellar contra un valor de PCR que no haya cambiado (como PCR0), reiniciar y luego resellar contra el nuevo valor de PCR7.
  4. Los sistemas heredados (servidores físicos antiguos, appliances o sistemas que nunca reciben actualizaciones de firmware) que no pueden inscribir el certificado 2023 quedarán limitados a arrancar binarios de shim firmados con el certificado 2011.

18.4 Por qué esto importa para este libro

Este es un ejemplo concreto y del mundo real de cada concepto que cubre este apéndice: bases de datos de confianza del firmware, ciclo de vida de certificados, riesgo de revocación, sensibilidad de las mediciones del TPM y el costo operacional de ignorar la gestión de certificados de firma. Si tu organización no sabía que esto iba a pasar, tu gestión del ciclo de vida de Secure Boot tiene una brecha.

19. Secure Boot y notas de versión de RHEL

19.1 RHEL 7

RHEL 7 estableció el modelo básico de Secure Boot de Red Hat:

  • shim como cargador de primera etapa
  • Clave embebida de Red Hat en shim
  • GRUB y kernel firmados
  • MOK para confianza añadida por el propietario
  • Módulos del kernel firmados requeridos en sistemas con Secure Boot habilitado

La documentación de RHEL 7 también hace un punto importante que mucha gente pasa por alto: el Secure Boot clásico trata sobre la integridad del código en espacio del kernel, no sobre la validación general de todo el contenido en espacio de usuario.

19.2 RHEL 8

RHEL 8 mantiene el mismo modelo general, con documentación pública mejorada en torno a:

  • .builtin_trusted_keys
  • .platform
  • .blacklist
  • efikeygen
  • pesign
  • Procedimientos de inscripción MOK

La documentación de RHEL 8 también muestra explícitamente que las claves inscritas mediante MOK se propagan a .platform.

19.3 RHEL 9

RHEL 9 documenta la misma ruta de confianza central y es más estricto y claro operacionalmente en torno a:

  • validación de firmas de módulos contra keyrings de confianza
  • confianza de plataforma impulsada por MOK
  • firma de kernels y módulos personalizados
  • comportamiento de lockdown en sistemas con Secure Boot

RHEL 9 es la línea base práctica si estás diseñando un flujo de trabajo moderno de Secure Boot en RHEL hoy en día.

19.4 RHEL 10

La documentación de RHEL 10 continúa con el mismo conjunto de herramientas y modelo de confianza para la firma personalizada de kernels y módulos con pesign, mokutil, efikeygen, keyctl y keyrings del kernel.

El punto importante es la continuidad: esta no es una característica aleatoria que cambia de forma en cada versión. Los nombres de las herramientas y los conceptos de confianza se mantienen reconocibles a través de las generaciones soportadas de RHEL.

20. Casos de uso comunes en RHEL

20.1 Despliegue de controladores de terceros

Ejemplos comunes:

  • controladores de controladora de almacenamiento
  • agentes de monitoreo con módulos del kernel
  • módulos de seguridad de endpoint
  • controladores de red personalizados
  • módulos de gestión de hardware del proveedor

Si el módulo no está firmado o está firmado por una clave no confiable, el sistema lo rechaza en un host con Secure Boot habilitado.

20.2 Compilaciones personalizadas del kernel

Si compilas tu propio kernel, al firmware y la cadena de arranque no les importa que provenga de tu pipeline de CI. Solo les importa si la imagen está firmada por una clave de confianza y si el sistema tiene esa ancla de confianza inscrita.

20.3 Entornos que eliminan anclas de confianza del proveedor

Algunas organizaciones quieren un control más estricto y reducen la dependencia de anclas de confianza predeterminadas de terceros. Eso es posible, pero significa que tú eres responsable de toda la cadena:

  • política de firma
  • protección de la clave privada
  • gestión de confianza del firmware
  • firma de GRUB/kernel
  • estrategia de revocación
  • ruta de recuperación si tu infraestructura de firma falla

La mayoría de los equipos subestiman esa carga operacional.

20.4 Máquinas virtuales

Secure Boot también importa en entornos virtualizados si el firmware del invitado expone soporte de UEFI Secure Boot. No asumas que “es solo una VM” significa que la confianza en el arranque es irrelevante. La infraestructura virtual es uno de los lugares más fáciles para que proliferen imágenes personalizadas sin firmar.

21. Solución de problemas de Secure Boot en RHEL

21.1 Verificaciones rápidas

sudo mokutil --sb-state
sudo mokutil --list-enrolled
sudo keyctl list %:.platform
sudo keyctl list %:.blacklist
sudo dmesg | grep -Ei 'secure boot|lockdown|integrity|module|cert'

21.2 Patrones de fallo típicos

SíntomaCausa probable
El módulo no se cargaMódulo sin firmar o firmante no confiable
El módulo muestra firmante pero aún fallaClave no inscrita en el sistema de destino, ruta de keyring incorrecta o firmante revocado
Se ejecutó la importación MOK pero la confianza no es visibleInscripción no completada en MokManager después del reinicio
El binario EFI no arrancaFalta firma de confianza, flujo de trabajo de reemplazo incorrecto o certificado/hash revocado
El comportamiento cambió después de una actualización de firmwareCambios en db/dbx alteraron el estado de confianza o revocación
El flujo de trabajo de desbloqueo con TPM falla después de actualizar clavesLas mediciones de PCR cambiaron después de actualizaciones de la base de datos de Secure Boot

21.3 Pistas en el log del kernel

Busca mensajes que mencionen:

  • integrity
  • MokListRT
  • EFI: Loaded cert
  • Lockdown
  • module verification failed

Si no inspeccionas el log del kernel, estás adivinando.

22. Mejores prácticas para la gestión de certificados de Secure Boot

22.1 Separar roles

No uses una sola clave de firma para todo a menos que disfrutes convirtiendo un compromiso en un incidente a nivel de toda la plataforma.

Prefiere claves separadas para:

  • cargadores de arranque / binarios EFI
  • kernels
  • módulos del kernel de terceros o internos
  • flujos de trabajo de emergencia o de último recurso

22.2 Proteger la clave privada adecuadamente

Preferir:

  • firma offline
  • almacenamiento de claves respaldado por HSM o token donde sea posible
  • acceso mínimo del operador
  • pasos de firma auditados
  • planificación de rotación de certificados

Evitar:

  • dejar claves extraídas sin cifrar en hosts de compilación
  • copiar material de firma entre trabajos de CI improvisados
  • claves de laboratorio de larga duración reutilizadas en producción

22.3 Mantener la inscripción MOK limitada

Cada certificado de confianza adicional expande lo que la plataforma puede aceptar. Inscribe solo lo que necesites. “Solo añade otro MOK para que funcione” es cómo empieza la proliferación de confianza.

22.4 Rastrear revocaciones y actualizaciones de firmware

Si dependes de confianza personalizada de Secure Boot:

  • monitorea las actualizaciones de firmware y dbx
  • prueba las rutas de recuperación antes del despliegue amplio
  • valida el arranque en hardware de staging
  • comprende el impacto en los secretos sellados con TPM y la atestación

22.5 Mantener Secure Boot y TLS PKI mentalmente separados

Los mismos conceptos X.509 aparecen en ambas áreas, pero los mundos operacionales son diferentes.

No confundas:

  • bases de datos de confianza del firmware con /etc/pki/ca-trust
  • inscripción MOK con instalación de anclas de confianza CA
  • claves de firma de módulos con certificados TLS de servidor web

Usan criptografía relacionada, pero resuelven problemas diferentes.

23. Verdades duras que los administradores suelen aprender tarde

  1. Secure Boot es fácil hasta que necesitas código personalizado.
  2. El código personalizado es fácil hasta que necesitas operaciones de firma duraderas.
  3. Las operaciones de firma duraderas son fáciles hasta que necesitas revocación, rotación, atestación y recuperación de flota.

La mayoría de los equipos no fallan en Secure Boot porque la criptografía sea demasiado difícil. Fallan porque su modelo operacional es descuidado:

  • sin modelo de propiedad de claves
  • sin planificación del ciclo de vida de certificados
  • sin hardware de pruebas
  • sin ruta de reversión
  • sin idea de qué es confiable por el firmware vs shim vs MOK vs keyrings del kernel

Eso no es una limitación técnica. Eso es un fallo de proceso.

24. Quick Reference

┌──────────────────────────────────────────────────────────────────────┐
│ RHEL SECURE BOOT QUICK REFERENCE                                     │
├──────────────────────────────────────────────────────────────────────┤
│ Check state:        mokutil --sb-state                               │
│ List MOKs:          mokutil --list-enrolled                          │
│ List platform keys: keyctl list %:.platform                          │
│ Built-in keys:      keyctl list %:.builtin_trusted_keys              │
│ Revocations:        keyctl list %:.blacklist                         │
│ View EFI signature: pesign --show-signature --in <efi-binary>        │
│                                                                      │
│ RHEL boot path:     firmware -> shim -> GRUB -> kernel -> modules    │
│                                                                      │
│ Firmware DBs:       PK / KEK / db / dbx                              │
│ Owner trust:        MOK -> .platform                                 │
│ Kernel trust:       .builtin_trusted_keys + .platform                │
│ Revocation:         .blacklist / dbx                                 │
│                                                                      │
│ Common packages:    pesign openssl kernel-devel mokutil keyutils     │
└──────────────────────────────────────────────────────────────────────┘

25. Conclusiones clave

  1. Secure Boot es una cadena de autorización basada en certificados para el código de arranque y del espacio del kernel.
  2. En RHEL, shim es el puente entre la confianza del firmware y la confianza controlada por Red Hat.
  3. MOK es el mecanismo crítico para añadir confianza controlada por el propietario sin reescribir las bases de datos del firmware.
  4. La carga de módulos del kernel depende de los keyrings de confianza, no del paquete CA de espacio de usuario.
  5. La revocación importa tanto como la confianza; dbx y .blacklist pueden romper artefactos que “antes funcionaban.”
  6. Si estás firmando módulos o kernels personalizados, el problema no es solo la criptografía. Es la gestión del ciclo de vida.

26. Lecturas oficiales de RHEL que conviene tener a mano

  • Documentación de gestión del kernel de RHEL 8/9/10 sobre firma de kernels y módulos para Secure Boot
  • Guía de administración del kernel y Secure Boot de RHEL 7
  • kernel_lockdown(7)
  • mokutil(1)
  • keyctl(1)
  • pesign(1)

Apéndice I: Glosario

Glosario de Términos PKI y Certificados

A

ACME (Automated Certificate Management Environment) Protocolo (RFC 8555) para emisión y renovación automatizada de certificados, popularizado por Let’s Encrypt.

ASN.1 (Abstract Syntax Notation One) Formato de serialización de datos usado para codificar certificados X.509.

Asymmetric Cryptography (Criptografía Asimétrica) Sistema de clave pública donde cifrado/descifrado usan pares de claves complementarias (pública y privada).

B

Baseline Requirements (Requisitos de Línea Base) Reglas CAB Forum que las CAs públicamente confiables deben seguir (ej., validez máxima 398 días).

C

CA (Certificate Authority / Autoridad Certificadora) Entidad que emite y firma certificados digitales.

CAB Forum (CA/Browser Forum) Consorcio industrial que define estándares para certificados TLS públicamente confiables.

Certificate Chain (Cadena de Certificado) Secuencia de certificados desde entidad final → intermedio(s) → CA raíz.

Certificate Policy (CP / Política de Certificado) Documento de alto nivel describiendo qué aseguramientos proporciona una PKI.

Certificate Revocation List (CRL / Lista de Revocación de Certificados) Lista firmada de números seriales de certificados revocados.

Certificate Signing Request (CSR / Solicitud de Firma de Certificado) Mensaje solicitando a una CA firmar una clave pública, incluye DN del sujeto y extensiones.

Certificate Transparency (CT / Transparencia de Certificado) Sistema de log público (RFC 6962) que registra todos los certificados emitidos para auditabilidad.

Certification Practice Statement (CPS / Declaración de Prácticas de Certificación) Procedimientos operacionales detallados de cómo una CA implementa su CP.

Cipher Suite (Suite de Cifrado) Conjunto de algoritmos criptográficos usados en TLS (ej., intercambio de clave, cifrado, MAC).

CN (Common Name / Nombre Común) Campo en sujeto del certificado; históricamente contenía nombre de dominio, ahora reemplazado por SAN.

Code Signing Certificate (Certificado de Firma de Código) Certificado con extKeyUsage: codeSigning para autenticar publicadores de software.

D

DER (Distinguished Encoding Rules) Codificación binaria de ASN.1, usado para certificados en keystores Java y sistemas embebidos.

DH (Diffie-Hellman) Algoritmo de intercambio de clave permitiendo a dos partes acordar un secreto compartido sobre canal inseguro.

DN (Distinguished Name / Nombre Distinguido) Identificador jerárquico en formato X.500 (ej., /C=US/O=Example/CN=server.example.com).

E

ECC (Elliptic Curve Cryptography / Criptografía de Curva Elíptica) Criptografía de clave pública usando curvas elípticas; ofrece claves más pequeñas que RSA para seguridad equivalente.

ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) Intercambio de clave proporcionando forward secrecy en TLS.

ECDSA (Elliptic Curve Digital Signature Algorithm) Esquema de firma basado en curvas elípticas.

EKU (Extended Key Usage / Uso Extendido de Clave) Extensión X.509 especificando propósitos permitidos del certificado (serverAuth, clientAuth, codeSigning, etc.).

End-Entity Certificate (Certificado de Entidad Final) Certificado hoja emitido a servidores, dispositivos o usuarios (no una CA).

EST (Enrollment over Secure Transport) Protocolo RFC 7030 para inscripción de certificado, más simple que SCEP completo.

F

FIPS 140-2 Estándar del gobierno de EE.UU. para seguridad de módulo criptográfico (Niveles 1-5).

Forward Secrecy (Secreto Hacia Adelante) Propiedad asegurando que claves de sesión pasadas permanezcan seguras incluso si clave privada de largo plazo es comprometida (logrado vía DH/ECDHE efímero).

H

HSM (Hardware Security Module / Módulo de Seguridad de Hardware) Dispositivo resistente a manipulación almacenando claves criptográficas y realizando operaciones en hardware.

HSTS (HTTP Strict Transport Security) Encabezado forzando navegadores a usar HTTPS para un dominio.

I

Intermediate CA (CA Intermedia) Certificado CA firmado por CA raíz, usado para emitir certificados de entidad final.

Issuer (Emisor) DN de la CA que firmó un certificado.

J

JWKS (JSON Web Key Set) Conjunto de claves públicas en formato JSON, a menudo usado con OAuth/OpenID Connect.

JWT (JSON Web Token) Formato de token compacto para transmitir claims; puede firmarse con RSA/ECDSA.

K

Key Escrow (Custodia de Clave) Práctica de almacenar claves privadas con tercero; controversial para privacidad de usuario.

Key Usage (Uso de Clave) Extensión X.509 definiendo operaciones criptográficas permitidas (digitalSignature, keyEncipherment, etc.).

Keystore Archivo almacenando claves privadas y certificados (ej., Java JKS, PKCS#12).

L

LDAP (Lightweight Directory Access Protocol) Protocolo para acceder servicios de directorio; a menudo usado para publicar certificados y CRLs.

M

mTLS (Mutual TLS / TLS Mutuo) TLS donde tanto cliente como servidor presentan certificados para autenticación bidireccional.

N

NSS (Network Security Services) Biblioteca crypto de Mozilla usada por Firefox; mantiene su propio almacén de confianza.

O

OCSP (Online Certificate Status Protocol) Protocolo en tiempo real (RFC 6960) para verificar estado de revocación de certificado.

OCSP Stapling El servidor incluye respuesta OCSP fresca en handshake TLS, mejorando privacidad y rendimiento.

OID (Object Identifier / Identificador de Objeto) Identificador numérico único en ASN.1 (ej., 2.5.29.17 para extensión SAN).

P

PEM (Privacy Enhanced Mail) DER codificado en Base64 con encabezados -----BEGIN CERTIFICATE-----.

PFX Ver PKCS#12.

PIN (Public Key Pinning / Anclaje de Clave Pública) Mecanismo para asociar dominio con clave(s) pública(s) específica(s); obsoleto en navegadores debido a riesgos operacionales.

PKI (Public Key Infrastructure / Infraestructura de Clave Pública) Sistema de hardware, software, políticas y procedimientos para gestionar certificados digitales.

PKCS (Public-Key Cryptography Standards) Familia de estándares por RSA Labs (PKCS#1–15).

PKCS#7 Formato contenedor para certificados y CRLs (sin clave privada).

PKCS#12 Formato archivo empaquetando certificado + clave privada + cadena, protegido por contraseña (.p12, .pfx).

R

RA (Registration Authority / Autoridad de Registro) Entidad validando identidad antes de reenviar CSR a CA.

Root CA (CA Raíz) CA autofirmada en cima de jerarquía; embebida en almacenes de confianza OS/navegador.

RSA (Rivest–Shamir–Adleman) Algoritmo de clave pública ampliamente usado basado en factorización de enteros.

S

SAN (Subject Alternative Name / Nombre Alternativo del Sujeto) Extensión X.509 listando identidades adicionales (nombres DNS, IPs, URIs).

SCT (Signed Certificate Timestamp) Prueba de log CT de que certificado ha sido registrado.

Self-Signed Certificate (Certificado Autofirmado) Certificado donde emisor == sujeto; no confiable por defecto.

Serial Number (Número Serial) Identificador único asignado por CA a cada certificado.

SHA-256 / SHA-384 Funciones hash criptográficas (parte de familia SHA-3).

SPIFFE (Secure Production Identity Framework For Everyone) Estándar para identidad de carga de trabajo en entornos dinámicos; usa SANs URI (spiffe://trust-domain/workload).

SSL (Secure Sockets Layer) Predecesor obsoleto de TLS.

T

TLS (Transport Layer Security) Protocolo criptográfico para comunicación de red segura (versiones actuales: 1.2, 1.3).

TPM (Trusted Platform Module / Módulo de Plataforma Confiable) Chip de hardware para almacenamiento seguro de clave en dispositivos.

Trust Anchor (Ancla de Confianza) Certificado raíz implícitamente confiable por un sistema.

Almacén de Confianza (Trust Store) Colección de certificados CA raíz confiables (ej., /etc/pki/ca-trust, Windows Certificate Store).

V

VA (Validation Authority / Autoridad de Validación) Componente manejando consultas OCSP/CRL.

W

Wildcard Certificate (Certificado Comodín) Certificado cubriendo *.example.com (coincide app.example.com, no sub.app.example.com).

X

X.509 Estándar ITU-T definiendo formato de certificado (RFC 5280 es versión IETF).

Z

Zero Trust (Confianza Cero) Modelo de seguridad asumiendo ninguna confianza implícita; cada solicitud autenticada y autorizada.

Apéndice J: Referencias

Referencias y Lectura Adicional

Lista curada de recursos autoritativos para profundizar tu conocimiento de PKI y certificados.

Estándares y RFCs

Estándares PKI Core

TLS/SSL

Algoritmos Criptográficos

Guías de Industria

CA/Browser Forum

Publicaciones NIST

Estándares ETSI

Libros

Fundamentales

  • “Network Security with OpenSSL” por Pravir Chandra, Matt Messier, John Viega O’Reilly, 2002 — Guía integral de OpenSSL

  • “PKI Uncovered” por Andre Karamanian, Siva Sathianathan Cisco Press, 2011 — Patrones de diseño PKI empresarial

  • “Bulletproof SSL and TLS” por Ivan Ristić Feisty Duck, 2022 — Guía autoritativa para desplegar TLS correctamente

Avanzados

  • “Serious Cryptography” por Jean-Philippe Aumasson No Starch Press, 2017 — Algoritmos y protocolos criptográficos modernos

  • “Applied Cryptography” por Bruce Schneier Wiley, 1996 — Texto clásico sobre protocolos criptográficos

Recursos en Línea

Documentación

Herramientas de Prueba

Tutoriales y Blogs

Videos y Cursos

  • “Public Key Cryptography” (Khan Academy) Introducción a RSA e intercambio de clave

  • “How HTTPS Works” (Cloudflare YouTube) Explicación animada de handshake TLS

  • Pluralsight — “PKI Architecture and Implementation” Curso de video comprehensivo sobre PKI empresarial

Software y Herramientas

Software CA

Gestión de Certificados

Bibliotecas

Comunidades y Foros

Artículos de Investigación

  • “The Most Dangerous Code in the World” (Martin et al., 2012) Análisis de vulnerabilidades de validación de certificado SSL

  • “Analysis of the HTTPS Certificate Ecosystem” (Durumeric et al., IMC 2013) Estudio a gran escala de despliegue TLS

  • “SoK: SSL and HTTPS Revisiting past challenges and evaluating certificate trust model enhancements” (Clark & van Oorschot, S&P 2013)

Marcos de Cumplimiento


Mantenerse Actualizado: Los estándares PKI y TLS evolucionan continuamente. Suscríbete a la lista de correo del grupo de trabajo TLS de IETF y sigue avisos de seguridad de tu CA y proveedores de software.