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:
| Amenaza | Qué ocurre | Ejemplo real |
|---|---|---|
| Espionaje | El atacante lee tus datos | Captura de contraseñas en Wi-Fi público |
| Alteración | El atacante modifica datos en tránsito | Inyección de malware en descarga de software |
| Suplantación | El atacante finge ser otra persona | Sitio bancario falso recopilando credenciales |
| Repudio | El remitente niega haber enviado un mensaje | Negar 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
| Pilar | Pregunta que responde | Implementado por | Protege contra |
|---|---|---|---|
| Confidencialidad | ¿Alguien más puede leerlo? | Cifrado (AES, RSA) | Espionaje |
| Integridad | ¿Ha sido modificado? | Hashes (SHA-256), HMAC | Alteración |
| Autenticidad | ¿Quién lo envió? | Certificados, firmas | Suplantación |
| No repudio | ¿Puede el remitente negarlo? | Firmas digitales | Repudio |
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:
| Algoritmo | Tamaño de Salida | Estado | Por qué |
|---|---|---|---|
| MD5 | 128 bits | ROTO | Colisiones encontradas en segundos. Nunca usar para seguridad. |
| SHA-1 | 160 bits | ROTO | Google demostró colisión práctica en 2017 (SHAttered). |
| SHA-256 | 256 bits | SEGURO | Sin ataques prácticos conocidos. Estándar actual. |
| SHA-384 | 384 bits | SEGURO | Mayor margen de seguridad. |
| SHA-512 | 512 bits | SEGURO | Seguridad máxima de la familia SHA-2. |
| SHA-3 | 256+ bits | SEGURO | Diseño diferente (Keccak). Alternativa a prueba de futuro. |
| BLAKE2 | 256+ bits | SEGURO | Muy 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 uso | Cómo | Ejemplo |
|---|---|---|
| Almacenamiento de contraseñas | Almacena el hash, no la contraseña | /etc/shadow en Linux |
| Integridad de archivos | Compara hash antes/después | sha256sum paquete.rpm |
| Firmas digitales | Firma el hash, no los datos | Firma de certificados |
| Deduplicación | Identifica archivos idénticos | Sistemas de respaldo |
| Blockchain | Cadena de hashes | Prueba 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.
| Propiedad | Valor |
|---|---|
| Velocidad | Muy rápida (AES acelerado por hardware) |
| Tamaño de clave | 128 o 256 bits |
| Problema | ¿Cómo compartir la clave de forma segura? |
| Ejemplos | AES-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).
| Propiedad | Valor |
|---|---|
| Velocidad | Lenta (1000x más lenta que la simétrica) |
| Tamaño de clave | 2048–4096 bits (RSA) o 256 bits (ECC) |
| Ventaja | No necesita compartir clave secreta previamente |
| Ejemplos | RSA, 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 Colores | Equivalente 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étodo | Cómo funciona | Compensación |
|---|---|---|
| LCR (Lista de Certificados Revocados) | La CA publica lista de números de serie revocados | Puede 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 real | Requiere red, preocupación de privacidad |
| OCSP Stapling | El servidor obtiene su propia respuesta OCSP y la adjunta al handshake | Lo 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:
| Concepto | Resumen en una frase |
|---|---|
| Hashes | Huellas digitales unidireccionales que detectan cualquier cambio (usa SHA-256+). |
| Cifrado simétrico | La misma clave cifra y descifra — rápido, pero distribución de clave es difícil. |
| Cifrado asimétrico | Pares de claves pública/privada — resuelve distribución, pero es lento. |
| Cifrado híbrido | Usa asimétrico para intercambiar claves, luego simétrico para datos (TLS hace esto). |
| Firmas digitales | Hash + clave privada = prueba de identidad e integridad. |
| Certificados | Vinculan una clave pública a una identidad, firmados por una CA de confianza. |
| PKI | La arquitectura de confianza: CA Raíz → CA Intermedia → Certificado entidad final. |
| Handshake TLS | Autentica servidor, intercambia claves, luego cifra todo. |
| Secreto hacia adelante | Usa 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:
- Prueba identidad (“Soy example.com”)
- Habilita cifrado (comunicación segura)
- 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
-
Certificado (
.crt,.pem)- Información pública: “Soy server.example.com”
- Contiene la clave pública
- Almacenado en
/etc/pki/tls/certs/en RHEL
-
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!)
-
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:
- El servidor envía su certificado
- El cliente verifica la cadena de firmas hasta una CA raíz confiable
- Si la cadena es válida → la conexión procede
- 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 RHEL | Característica Clave | Enfoque de Solución de Problemas |
|---|---|---|
| RHEL 7 | Enfoque tradicional | Configuración manual, problemas TLS heredados |
| RHEL 8 | Crypto-policies | Conflictos de políticas, integración certmonger |
| RHEL 9 | OpenSSL 3.x | Problemas de proveedores, validación más estricta |
| RHEL 10 | Valores predeterminados fortalecidos | Solo 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
| ← Anterior: Capítulo 1 - Criptografía, Estructura PKI y Fundamentos | Siguiente: Capítulo 3 - Resumen de Herramientas de Certificados en RHEL → |
|---|
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:
| Herramienta | Uso Principal | Versiones RHEL | Cuándo Usar |
|---|---|---|---|
| openssl | Operaciones de certificados, pruebas | Todas | Generar claves/CSRs, inspeccionar certs, probar conexiones |
| certutil | Gestión de base de datos NSS | Todas | BDs de cert estilo Firefox/Mozilla |
| update-ca-trust | Gestión de almacén de confianza | Todas | Agregar/eliminar CAs confiables |
| certmonger | Renovación automática | Todas | Rastrear y renovar certificados automáticamente |
| crypto-policies | Seguridad en todo el sistema | RHEL 8+ | Controlar versiones TLS y cifrados |
| getcert | CLI de certmonger | Todas | Solicitar y gestionar certs rastreados |
| trust | Gestión de confianza P11-kit | Todas (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
.dben/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ística | LEGACY | DEFAULT | FUTURE | FIPS |
|---|---|---|---|---|
| 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ín | 1024 bits | 2048 bits | 3072 bits | 2048 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
| Herramienta | RHEL 7 | RHEL 8 | RHEL 9 | RHEL 10 | Notas |
|---|---|---|---|---|---|
| openssl | 1.0.2k | 1.1.1k | 3.5.5 | 3.5.5 | Herramienta principal |
| certutil | ✅ | ✅ | ✅ | ✅ | Herramienta NSS |
| update-ca-trust | ✅ | ✅ Mejorado | ✅ Mejorado | ✅ Mejorado | Gestión confianza |
| certmonger | ✅ | ✅ Mejorado | ✅ ACME | ✅ ACME | Renovación auto |
| crypto-policies | ❌ | ✅ | ✅ Subpolíticas | ✅ Mejorado | Política sistema |
| getcert | ✅ | ✅ | ✅ | ✅ | CLI certmonger |
| trust | ✅ Básico | ✅ | ✅ | ✅ | Herramienta 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
| ← Anterior: Capítulo 2 - Introducción a los Certificados en RHEL | Siguiente: Capítulo 4 - Criptografía Básica para Administradores RHEL → |
|---|
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
- Selecciona dos números primos grandes p y q.
- Calcula el módulo
n = p × q. - Deriva el exponente público
ey el exponente privadodtal quee × d ≡ 1 (mod φ(n)). - 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.
| Algoritmo | Tamaño de clave para seguridad de 128 bits |
|---|---|
| RSA | 3072 bits |
| ECC | 256 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 RHEL | RSA Mínimo | ECC Mínimo | Aplicado Por |
|---|---|---|---|
| RHEL 7 | Ninguno (débil permitido) | Ninguno | Configuración manual |
| RHEL 8 | 2048 bits | P-256 | crypto-policy DEFAULT |
| RHEL 9 | 2048 bits | P-256 | crypto-policy DEFAULT |
| RHEL 10 | 2048 bits | P-256 | crypto-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
| ← Anterior: Capítulo 3 - Resumen de Herramientas de Certificados en RHEL | Siguiente: Capítulo 5 - Certificados X.509 en RHEL → |
|---|
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
| Campo | Propósito |
|---|---|
| Version | Usualmente v3 (agrega extensiones) |
| Serial Number | Único por CA |
| Signature Algorithm | ej. sha256WithRSAEncryption |
| Issuer | Nombre Distinguido (DN) de CA |
| Validity | Fechas Not Before y Not After |
| Subject | DN de la entidad (CN, O, C…) |
| Subject Public Key Info | Algoritmo + Clave |
| Extensions | Key Usage, SAN, CRL DP, etc. |
| Signature | Firma 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 RHEL | OpenSSL | Rigurosidad de Validación | Cambios Clave |
|---|---|---|---|
| RHEL 7 | 1.0.2k | Estándar | SANs recomendados |
| RHEL 8 | 1.1.1k | Más estricto | SANs fuertemente recomendados |
| RHEL 9 | 3.5.5 | Muy estricto | SANs requeridos, SHA-1 bloqueado |
| RHEL 10 | 3.5.5 | Muy estricto | Igual 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
| ← Anterior: Capítulo 4 - Criptografía Básica para Administradores RHEL | Siguiente: Capítulo 6 - Inmersión Profunda en el Almacén de Confianza de RHEL → |
|---|
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 contrust 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:
- Verificar firma del certificado usando la clave pública del emisor
- Encontrar certificado del emisor en el almacén de confianza
- Repetir hasta alcanzar la CA raíz confiable
- 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:
| Componente | Rol |
|---|---|
p11-kit | Middleware que carga módulos de confianza y los expone vía PKCS#11 |
p11-kit-trust | El módulo de confianza (/usr/lib64/pkcs11/p11-kit-trust.so) que lee los certificados fuente |
update-ca-trust | Script de shell que invoca p11-kit extract para regenerar los paquetes extraídos |
trust | Interfaz 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 yblocklist/se refiere al nombre de directorio en RHEL 9/10+. Ambos cumplen el mismo propósito. Cuando veas una ruta comosource/blacklist/, sustitúyela porsource/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:
| Prioridad | Directorio | Gestionado 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 confiablesblacklist/(RHEL 7/8) oblocklist/(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 archivoca-bundle.trust.p11-kitincluido con el paqueteca-certificates.
Crítico: Los formatos
BEGIN TRUSTED CERTIFICATEyBEGIN CERTIFICATEno son intercambiables. Un archivoBEGIN TRUSTED CERTIFICATElleva 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 comoBEGIN CERTIFICATEsimple (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) elBEGIN TRUSTED CERTIFICATEtiene 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:
-
La desconfianza prevalece sobre la confianza. Si un certificado aparece tanto en
anchors/como enblacklist//blocklist/, se desconfía de él. -
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/. -
Los atributos explícitos anulan los predeterminados. Un archivo
.p11-kitcon restricciones de propósito específicas anula la confianza general otorgada a un PEM simple enanchors/. -
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 comoBEGIN CERTIFICATE, la desconfianza ocurre en dos casos:- El
BEGIN TRUSTED CERTIFICATEtiene usos rechazados explícitos — el rechazo contradice la confianza implícita total del PEM simple. - El
BEGIN TRUSTED CERTIFICATEtiene 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.
- El
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 enca-bundle.trust.p11-kitcon atributos de uso rechazado o confianza vacía. El resultado: la CA queda desconfiada después deupdate-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 RHEL | Comando trust | Desconfianza | Directorio de Desconfianza | Notas |
|---|---|---|---|---|
| RHEL 7 | Básico | Limitada | blacklist/ | Gestión manual |
| RHEL 8 | Mejorado | Soporte completo | blacklist/ | Integración p11-kit |
| RHEL 9 | Mejorado | Soporte completo | blocklist/ | Renombrado de blacklist/ |
| RHEL 10 | Mejorado | Soporte completo | blocklist/ | 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 PEM | Datos de Confianza | Dónde Aparece |
|---|---|---|
-----BEGIN CERTIFICATE----- | Ninguno — solo certificado X.509 sin procesar | Archivos descargados, respuestas CSR, exportaciones manuales |
-----BEGIN TRUSTED CERTIFICATE----- | Embebidos — incluye listas auxiliares de OIDs de confianza/rechazo | Paquete 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 fino | ca-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 Coincidencia | Qué Significa | Cómo lo Trata p11-kit |
|---|---|---|
| Codificación DER idéntica, mismo formato | Certificado idéntico byte por byte, misma envoltura de confianza | Deduplicado — aparece una vez en la salida |
| Codificación DER idéntica, diferente formato de confianza | Mismo certificado pero uno tiene atributos BEGIN TRUSTED CERTIFICATE / .p11-kit y el otro tiene BEGIN CERTIFICATE | DESCONFIADO 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 DER | Mismo certificado lógico pero recodificado | Se tratan como objetos separados — ambos se cargan |
| Mismo Subject DN, diferente Serial | Certificados 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 CERTIFICATEcon 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 CERTIFICATEcon 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 listlo muestra contrust: 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 unBEGIN CERTIFICATEsimple enanchors/, 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únBEGIN TRUSTED CERTIFICATEsin 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 listcon 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ón | Explicación Probable | Impacto |
|---|---|---|
| Misma huella digital, mismo formato PEM | Duplicado inofensivo — p11-kit deduplica | Ninguno |
| 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 total | Certificado marcado como DESCONFIADO |
| Mismo subject + serial, diferente huella digital | Certificado recodificado o manipulado | Ambos cargados como objetos separados |
| Mismo subject, diferente serial | Certificado CA reemitido (nuevo par de claves o renovado) | Ambos cargados independientemente |
Mismo subject + serial + huella digital, diferente salida de trust list | Mismo certificado con diferentes atributos de confianza aplicados | Posible 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
| Campo | Significado |
|---|---|
pkcs11:id=... | URI PKCS#11 que identifica únicamente este objeto |
type | Siempre certificate para certificados CA |
label | Nombre legible (CN del subject del certificado) |
trust: anchor | El certificado es confiable como CA |
trust: distrusted | El certificado está explícitamente desconfiado |
category: authority | El certificado es una CA (tiene Basic Constraints CA:TRUE) |
category: other-entry | El 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 en | Significado | Acción |
|---|---|---|
/etc/pki/ca-trust/source/blacklist/ (RHEL 7/8) o blocklist/ (RHEL 9+) | El administrador lo desconfió explícitamente | Intencional — 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 desconfianza | Mozilla eliminó la confianza aguas arriba | Normal — la CA fue desconfiada por el programa de raíz de Mozilla NSS |
| No en ningún directorio de desconfianza | Probablemente un conflicto de formato de confianza — el mismo cert existe como BEGIN CERTIFICATE y como BEGIN TRUSTED CERTIFICATE / .p11-kit | Verificar 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
| Problema | Causa | Solución |
|---|---|---|
| CA no encontrada después de agregarla a anchors/ | Olvidó ejecutar update-ca-trust | Ejecutar 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ía | Eliminar 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 desconfiada | Comparar huellas digitales; asegurar certificado idéntico |
| Aplicación Java no confía en la CA | Keystore de Java no regenerado | Ejecutar sudo update-ca-trust (reconstruye cacerts) |
| Confianza restaurada después de reiniciar | El administrador agregó el cert en /usr/share/ (sobrescrito por actualizaciones RPM) | Usar siempre /etc/pki/ca-trust/source/anchors/ |
trust list muestra entradas duplicadas | Misma CA de subject desde múltiples fuentes con diferente contenido DER | Identificar y eliminar el archivo fuente redundante |
update-ca-trust falla silenciosamente | Archivo de certificado corrupto en las fuentes | Verificar 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
| ← Anterior: Capítulo 5 - Certificados X.509 en RHEL | Siguiente: Capítulo 7 - Firmas Digitales y Verificación en RHEL → |
|---|
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:
- Deterministas
- Resistencia a preimagen
- Resistencia a colisiones
- Efecto avalancha
Algoritmos populares: SHA-256, SHA-3, BLAKE2.
7.2 Construir Firmas
- Calcular hash del mensaje.
- Cifrar hash con clave privada → firma.
- 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
| Algoritmo | RHEL 7 | RHEL 8 | RHEL 9 | RHEL 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
| ← Anterior: Capítulo 6 - Inmersión Profunda en el Almacén de Confianza de RHEL | Siguiente: Capítulo 8 - Versiones de RHEL y Evolución de Certificados → |
|---|
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 RHEL | Fecha GA | Fin de Soporte | Versión OpenSSL | Característica Clave de Certificados |
|---|---|---|---|---|
| RHEL 7 | Junio 2014 | Junio 2024 | 1.0.2k-26 | Gestión manual tradicional |
| RHEL 8 | Mayo 2019 | Mayo 2029 | 1.1.1k-14 | Introducción de crypto-policies |
| RHEL 9 | Mayo 2022 | Mayo 2032 | 3.5.5-2 | OpenSSL 3.x, valores predeterminados más estrictos |
| RHEL 10 | Mayo 2025 | Mayo 2035 | 3.5.5-2 | Fortalecimiento continuo, preparación PQC |
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 TLS | RHEL 7 | RHEL 8 | RHEL 9 | RHEL 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
| Herramienta | RHEL 7 | RHEL 8 | RHEL 9 | RHEL 10 |
|---|---|---|---|---|
openssl | 1.0.2k | 1.1.1k | 3.5.5 | 3.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ística | RHEL 7 | RHEL 8 | RHEL 9 | RHEL 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:
- Auditar versiones TLS en uso
- Actualizar configuraciones de cifrado
- Probar aplicaciones con TLS 1.2+
- 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:
- Probar todas las operaciones de certificados
- Actualizar scripts personalizados usando OpenSSL
- Validar integridad de cadena de certificados
- 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:
- Revisar documentación de RHEL 10.x
- Probar compatibilidad de crypto-policy
- 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
- Siempre verificar versión RHEL primero al resolver problemas
- RHEL 8 introdujo crypto-policies - cambio de juego para gestión de certificados
- RHEL 9 usa OpenSSL 3.x - cambios significativos en API y comportamiento
- RHEL 10 continúa la base de RHEL 9 - mejoras incrementales
- Algoritmos legacy eliminados progresivamente a través de versiones
- 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
| ← Anterior: Capítulo 7 - Firmas Digitales y Verificación en RHEL | Siguiente: Capítulo 9 - Gestión de Certificados en RHEL 7 → |
|---|
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
| Error | Causa | Solución |
|---|---|---|
| “certificate verify failed” | CA faltante en almacén de confianza | Agregar CA a /etc/pki/ca-trust/source/anchors/ |
| “permission denied” en clave | Permisos incorrectos | chmod 600 en archivo .key |
| “certificate has expired” | Certificado expirado | Renovar certificado manualmente |
| “no shared cipher” | Desajuste de cifrado cliente/servidor | Actualizar SSLCipherSuite |
| “wrong version number” | Desajuste de versión TLS | Actualizar 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
- RHEL 7 es manual - Sin crypto-policies, se necesita configuración cuidadosa
- OpenSSL 1.0.2k - Sintaxis antigua, sin TLS 1.3
- TLS 1.0/1.1 habilitado por defecto - Deshabilitarlos manualmente
- SHA-1 aún funciona - Pero no después de migración a RHEL 8+
- certmonger disponible - Pero básico comparado con RHEL 8+
- Planificar migración - El soporte de RHEL 7 está terminando
- 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
| ← Anterior: Capítulo 8 - Versiones de RHEL y Evolución de Certificados | Siguiente: Capítulo 10 - RHEL 8 y Crypto-Policies → |
|---|
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ística | RHEL 7 | RHEL 8 |
|---|---|---|
| OpenSSL | 1.0.2k | 1.1.1k-14 |
| TLS 1.3 | ❌ No | ✅ Sí |
| Crypto-Policies | ❌ No | ✅ ¡NUEVO! |
| TLS 1.0/1.1 | ✅ Habilitado | ❌ Deshabilitado (DEFAULT) |
| certmonger | Básico | Mejorado |
| Seguridad Predeterminada | Mixta | Má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ítica | Versiones TLS | RSA Mín | SHA-1 | 3DES | Caso de Uso |
|---|---|---|---|---|---|
| DEFAULT | 1.2, 1.3 | 2048 | ❌ No | ❌ No | Estándar (recomendado) |
| LEGACY | 1.0+, todas | 1024 | ⚠️ Sí | ⚠️ Sí | Compatibilidad sistemas antiguos |
| FUTURE | 1.2, 1.3 | 3072 | ❌ No | ❌ No | Seguridad más estricta |
| FIPS | 1.2, 1.3 | 2048 | ❌ No | ❌ No | Cumplimiento 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)
- Crypto-policies son LA característica - Apréndelas bien
- La política DEFAULT es buena - No cambiar sin razón
- TLS 1.3 ahora disponible - Más rápido y más seguro
- OpenSSL 1.1.1 - Características modernas, mejor sintaxis
- certmonger mejorado - Mejor automatización
- Migración desde RHEL 7 - Probar exhaustivamente
- 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
| ← Anterior: Capítulo 9 - Gestión de Certificados en RHEL 7 | Siguiente: Capítulo 11 - Seguridad Moderna en RHEL 9 → |
|---|
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ística | RHEL 8 | RHEL 9 |
|---|---|---|
| OpenSSL | 1.1.1k | 3.5.5 |
| Arquitectura | Tradicional | Basada en proveedores |
| TLS 1.0/1.1 | Política LEGACY | ❌ Completamente eliminado |
| Crypto-Policies | Básicas | Subpolíticas |
| Validación | Estándar | Más Estricta |
| SHA-1 | Obsoleto | Bloqueado |
| certmonger | Mejorado | Flujos 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
| Error | Causa | Solución |
|---|---|---|
| “CA md too weak” | Firma SHA-1 | Reemitir con SHA-256+ |
| “Provider not available” | Algoritmo legacy usado | Agregar -provider legacy o actualizar a algoritmo moderno |
| “unsupported” en comando openssl | Algoritmo deshabilitado | Usar alternativa moderna o proveedor legacy |
| “no shared cipher” (app migrada) | Cliente usa cifrados antiguos | Actualizar cliente o usar política LEGACY temporalmente |
| “certificate verify failed” | Validación más estricta | Verificar 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
- Arquitectura de proveedores OpenSSL 3.5.5 - Entender proveedores
- Validación más estricta - Captura problemas de seguridad (¡bien!)
- SHA-1 completamente bloqueado - Reemitir certificados antiguos
- Subpolíticas de crypto-policy - Afinar seguridad
- certmonger sigue siendo valioso para IPA y flujos de renovación con seguimiento
- Soporte obligatorio TLS 1.3 - Más rápido, más seguro
- 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
| ← Anterior: Capítulo 10 - RHEL 8 y Crypto-Policies | Siguiente: Capítulo 12 - Características Actuales de RHEL 10 → |
|---|
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ística | RHEL 9 | RHEL 10 |
|---|---|---|
| OpenSSL | 3.5.5 | 3.5.5 (misma base) |
| Crypto-Policies | Subpolíticas | Subpolíticas mejoradas |
| Versiones TLS | 1.2, 1.3 | 1.3 preferido, 1.2 soportado |
| FIPS | Módulos 140-2 | Transición 140-3 |
| Valores Predeterminados de Seguridad | Estricto | Más Estricto |
| Soporte de Contenedores | Bueno | Mejorado |
| Post-Cuántico | Fundamento | Preparació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
| Escenario | RHEL 9 | RHEL 10 | Recomendación |
|---|---|---|---|
| Nuevo despliegue 2025+ | ✅ Bueno | ✅ Mejor | RHEL 10 |
| RHEL 9 existente | ✅ Mantener | ⏸️ Esperar | Quedarse en 9 por ahora |
| Migrando desde RHEL 8 | ✅ Sí | ✅ Considerar | Cualquiera (9 es más seguro) |
| Migrando desde RHEL 7 | ✅ Sí | ⚠️ Gran salto | Ir a 9 primero |
| Horizonte 10+ años | ⏸️ Soporte 2032 | ✅ Soporte 2035 | RHEL 10 |
| Seguridad de vanguardia | ✅ Bueno | ✅ Mejor | RHEL 10 |
| Producción crítica | ✅ Probado | ⏸️ Más nuevo | RHEL 9 (más seguro) |
12.16 Conclusiones Clave
- RHEL 10 = RHEL 9 + mejoras incrementales
- Misma base OpenSSL 3.5.5 - Sin cambios API mayores
- Valores predeterminados de seguridad más estrictos - Bueno para seguridad
- Preparación post-cuántica - Infraestructura lista para el futuro
- Sin cambios urgentes de certificados - La transición es suave
- Conocimiento de RHEL 9 se transfiere - Mismas herramientas y comandos
- 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
| ← Anterior: Capítulo 11 - Seguridad Moderna en RHEL 9 | Siguiente: Capítulo 13 - Compatibilidad Entre Versiones → |
|---|
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 7 | Servidor 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
| Error | Causa | Solución |
|---|---|---|
| “wrong version number” | Desajuste versión TLS | Actualizar cliente a TLS 1.2+ |
| “no shared cipher” | Incompatibilidad de cifrado | Verificar crypto-policy o configuración de cifrado |
| “certificate verify failed” | Problema de confianza o validación | Verificar confianza CA, validez de certificado |
| “sslv3 alert handshake failure” | Incompatibilidad de protocolo | Actualizar versiones TLS |
| “unsafe legacy renegotiation” | OpenSSL antiguo en cliente | Actualizar 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
- Los entornos mixtos son normales - Planificar para compatibilidad
- TLS 1.2+ es el mínimo para sistemas modernos
- Firmas SHA-256+ requeridas para RHEL 8+
- Crypto-policies cambiaron todo (RHEL 8+)
- Probar en todas las versiones antes de desplegar
- Documentar todo - especialmente excepciones
- 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
| ← Anterior: Capítulo 12 - Características Actuales de RHEL 10 | Siguiente: Capítulo 14 - Apache httpd en RHEL → |
|---|
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 RHEL | Versión Apache | OpenSSL | Enfoque de Config |
|---|---|---|---|
| RHEL 7 | 2.4.6 | 1.0.2k | Configuración SSL manual |
| RHEL 8 | 2.4.37+ | 1.1.1k | Manual + crypto-policies |
| RHEL 9 | 2.4.53+ | 3.5.5 | Crypto-policies preferido |
| RHEL 10 | 2.4.62+ | 3.5.5 | Crypto-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 Error | Causa | Solución |
|---|---|---|
| “SSLCertificateFile: file does not exist” | Ruta incorrecta | Corregir ruta en ssl.conf |
| “Permission denied” en archivo de clave | Permisos incorrectos | chmod 600 en clave |
| “certificate verify failed” | Problema de cadena | Instalar certs intermedios |
| “SSLCertificateKeyFile: file does not exist” | Clave faltante | Generar o restaurar clave |
| “Private key does not match certificate” | Desajuste cert/clave | Regenerar CSR con clave correcta |
| “SSL Library Error” | mod_ssl no cargado | Instalar paquete mod_ssl |
| “ca md too weak” (RHEL 9+) | Firma SHA-1 | Reemitir con SHA-256+ |
| “name mismatch” | Hostname no coincide CN/SAN | Corregir 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
- Apache + mod_ssl es el servidor web estándar de RHEL
- RHEL 7: Configuración TLS manual requerida
- RHEL 8/9/10: Crypto-policies simplifican la configuración
- Integración con certmonger habilita automatización
- certbot requiere EPEL (no soportado oficialmente)
- Siempre usar SANs en certificados
- 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 RHEL | Fuente NGINX | Cómo Instalar |
|---|---|---|
| RHEL 7 | EPEL (comunidad) | Habilitar EPEL, luego yum install nginx |
| RHEL 8 | AppStream (oficial) | dnf module install nginx:1.20 |
| RHEL 9 | AppStream (oficial) | dnf install nginx |
| RHEL 10 | AppStream (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
| Error | Causa | Solución |
|---|---|---|
| “SSL: error:0200100D…” | Permission denied en clave | chmod 600 en archivo de clave |
| “no ssl configured for the server” | Falta ssl en listen | Agregar listen 443 ssl; |
| “cannot load certificate” | Archivo no encontrado o inválido | Verificar ruta y formato cert |
| “PEM_read_bio:no start line” | Formato incorrecto | Asegurar que cert esté en formato PEM |
| “key values mismatch” | Cert/clave no coinciden | Regenerar con clave correcta |
| “nginx: [emerg] bind() failed” | Puerto ya en uso | Verificar 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
- NGINX disponible en AppStream (RHEL 8+) o EPEL (RHEL 7)
- Crypto-policies simplifican config en RHEL 8/9/10
- certmonger se integra bien con recarga automática
- certbot requiere EPEL en todas las versiones RHEL
- SNI habilita múltiples certs en la misma IP
- mTLS posible para autenticación de cliente
- 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
| ← Anterior: Capítulo 14 - Apache httpd en RHEL | Siguiente: Capítulo 16 - TLS en Servidor de Correo Postfix → |
|---|
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:
| Nivel | Comportamiento | Caso de Uso |
|---|---|---|
none | TLS deshabilitado | No recomendado |
may | TLS opcional (oportunista) | Estándar (compatible) |
encrypt | TLS requerido | Entornos de alta seguridad |
dane | Validación basada en DNSSEC | Configuraciones 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
| Error | Causa | Solución |
|---|---|---|
| “SSL_accept error” | Problema certificado/clave | Verificar coincidencia par cert/clave |
| “No shared cipher” | Incompatibilidad de cifrado | Verificar crypto-policy o cliente |
| “certificate verify failed” | Cadena de confianza rota | Instalar certs intermedios |
| “Permission denied” en clave | Permisos incorrectos | chmod 600 en archivo de clave |
| “TLS is required but not available” | TLS no habilitado | Establecer smtpd_tls_security_level = may |
| “STARTTLS failed” | Problema TLS del cliente | Verificar 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ística | RHEL 7 | RHEL 8 | RHEL 9 | RHEL 10 |
|---|---|---|---|---|
| Versión Postfix | 2.10.x | 3.3.x+ | 3.5.x+ | 3.8.x+ |
| OpenSSL | 1.0.2k | 1.1.1k | 3.5.5 | 3.5.5 |
| Config TLS | Manual | Crypto-policies | Crypto-policies | Crypto-policies |
| TLS Predeterminado | Puede incluir 1.0/1.1 | TLS 1.2+ | TLS 1.2+ | TLS 1.3 preferido |
| certmonger | Básico | Mejorado | Soporte ACME | Soporte 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
- Postfix soporta TLS en puertos 25 (STARTTLS), 465 (SMTPS), 587 (Submission)
- RHEL 7 requiere configuración TLS manual (protocolos, cifrados)
- RHEL 8+ usa crypto-policies (¡mucho más simple!)
- Niveles de seguridad:
none,may,encrypt,dane - certmonger funciona excelente con Postfix
- Siempre probar con
openssl s_client -starttls smtp - 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
| ← Anterior: Capítulo 15 - NGINX en RHEL | Siguiente: Capítulo 17 - OpenLDAP y Servicios de Directorio → |
|---|
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étodo | Puerto | Cifrado | Caso de Uso |
|---|---|---|---|
| LDAP | 389 | ❌ Ninguno | Legacy, no recomendado |
| LDAPS | 636 | ✅ TLS desde el inicio | Preferido, cifrado |
| LDAP+STARTTLS | 389 | ✅ Actualizar a TLS | Alternativa 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
| Error | Causa | Solución |
|---|---|---|
| “TLS: can’t connect” | Certificado/clave no legible | Verificar ownership: chown ldap:ldap |
| “TLS: hostname does not match” | Desajuste CN/SAN | Regenerar cert con hostname correcto |
| “Certificate verification failed” | CA no confiable | Agregar CA al almacén de confianza del cliente |
| “Permission denied” en clave | Ownership/permisos incorrectos | chmod 600, chown ldap:ldap |
| “TLS engine not initialized” | TLS no configurado | Agregar directivas TLS a configuración |
| “error:14094410:SSL routines” | Desajuste protocolo/cifrado | Verificar 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
- LDAPS (puerto 636) es más simple que STARTTLS
- Ownership del certificado crítico - Debe ser legible por usuario
ldap - cn=config preferido sobre slapd.conf (RHEL moderno)
- FreeIPA maneja LDAPS automáticamente - ¡Mucho más fácil!
- Configuración de cliente importa - Establecer TLS_CACERT correctamente
- Probar exhaustivamente - Usar
openssl s_clientyldapsearch -ZZ - 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
| ← Anterior: Capítulo 16 - TLS en Servidor de Correo Postfix | Siguiente: Capítulo 18 - TLS en Bases de Datos (PostgreSQL, MySQL) → |
|---|
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 SSLhostssl: Requerir SSLhostnossl: Prohibir explícitamente SSL
Opciones de Cert de Cliente:
md5: SSL requerido, autenticación por contraseñacert: SSL + certificado de cliente requeridoclientcert=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 SSLallow: Intentar SSL, volver a no-SSLprefer: Preferir SSL, fallback permitidorequire: Requerir SSL (no verificar cert)verify-ca: Requerir SSL, verificar CAverify-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 RHEL | PostgreSQL | Soporte SSL | Notas |
|---|---|---|---|
| RHEL 7 | 9.2 | ✅ Sí | Config manual versión TLS |
| RHEL 8 | 10.x+ | ✅ Sí | Crypto-policy del sistema |
| RHEL 9 | 13.x+ | ✅ Sí | Mejorado, crypto-policy |
| RHEL 10 | 15.x+ | ✅ Sí | Último, crypto-policy |
Versiones MySQL/MariaDB en RHEL
| Versión RHEL | Base de Datos | Soporte SSL | Notas |
|---|---|---|---|
| RHEL 7 | MariaDB 5.5 | ✅ Sí | Config manual |
| RHEL 8 | MariaDB 10.3+ | ✅ Sí | Compatible crypto-policy |
| RHEL 9 | MariaDB 10.5+ | ✅ Sí | TLS moderno |
| RHEL 10 | MariaDB 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
- PostgreSQL y MySQL soportan SSL/TLS
- Ownership de archivo crítico - postgres:postgres o mysql:mysql
- Permisos: 600 para claves, 644 para certs
- pg_hba.conf controla acceso PostgreSQL (hostssl)
- sslmode importante para clientes PostgreSQL
- Certificados de cliente habilitan autenticación fuerte
- Probar exhaustivamente antes de forzar TLS
- 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
| ← Anterior: Capítulo 17 - OpenLDAP y Servicios de Directorio | Siguiente: Capítulo 19 - Servicios de Certificados FreeIPA → |
|---|
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
- Navegar a https://ipa.example.com/
- Identidad → Hosts → Seleccionar host → Acciones → Nuevo Certificado
- 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
- FreeIPA es la CA interna recomendada de Red Hat
- Combina identidad + certificados + autenticación
- Integración con certmonger es automática
- Los certificados se renuevan automáticamente (¡sin trabajo manual!)
- Usar principales de servicio (HTTP/host, ldap/host)
- Soporte ACME en RHEL 9+ (puede reemplazar Let’s Encrypt para interno)
- UI Web y CLI ambos disponibles
- 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
| ← Anterior: Capítulo 18 - TLS en Bases de Datos (PostgreSQL, MySQL) | Siguiente: Capítulo 20 - Otros Servicios RHEL con Certificados → |
|---|
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
| Servicio | CN/SAN | Cert Cliente | Renovación Auto | Notas Especiales |
|---|---|---|---|---|
| Apache | Requerido | Opcional (mTLS) | certmonger | Más común |
| NGINX | Requerido | Opcional (mTLS) | certmonger | Alto rendimiento |
| Postfix | Requerido | Opcional | certmonger | SMTP/SMTPS |
| OpenLDAP | Requerido | Opcional | certmonger | Debe ser legible por usuario ldap |
| PostgreSQL | Requerido | Opcional | Manual o script | Ownership usuario postgres |
| MySQL | Requerido | Opcional | Manual o script | Ownership usuario mysql |
| FreeIPA | Automático | N/A | Automático | Auto-gestionado |
| Cockpit | Requerido | No | certmonger | Archivo cert+clave combinado |
| OpenVPN | Requerido | Requerido | Manual | PKI complejo |
| strongSwan | Requerido | Requerido | Manual | Específico IPsec |
| HAProxy | Requerido | No | certmonger | Formato PEM combinado |
| Registry | Requerido | Opcional | Manual | Especí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
- Muchos servicios usan certificados más allá de servidores web
- Cada servicio tiene requisitos únicos - Verificar ownership, permisos
- certmonger funciona con la mayoría de servicios para automatización
- Certificados comodín pueden simplificar configuraciones multi-servicio
- Probar cada servicio independientemente
- Rastreo centralizado con certmonger recomendado
- 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
| ← Anterior: Capítulo 19 - Servicios de Certificados FreeIPA | Siguiente: Capítulo 21 - Mejores Prácticas para Certificados de Servicios → |
|---|
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
- La organización previene confusión - Estructura y nomenclatura consistentes
- Los permisos son críticos - 600 para claves, 644 para certs
- Automatizar renovación - Usar certmonger cuando sea posible
- Respaldar todo - Pero cifrar claves privadas
- Documentar exhaustivamente - Tu yo futuro te lo agradecerá
- Monitorear proactivamente - No esperar a la expiración
- Validar antes de desplegar - Capturar problemas temprano
- 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
| ← Anterior: Capítulo 20 - Otros Servicios RHEL con Certificados | Siguiente: Capítulo 22 - Dominio de certmonger → |
|---|
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ónSUBMITTING: 🔄 Enviando solicitud a CACA_UNREACHABLE: ❌ No se puede alcanzar servidor CACA_REJECTED: ❌ CA rechazó solicitudNEED_KEY_GEN_PIN: ⏸️ Esperando PIN (HSM/token)PRE_SAVE_COMMAND: 🔄 Ejecutando script pre-guardadoPOST_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ón | Propósito | Ejemplo |
|---|---|---|
-f | Ruta de archivo de certificado | /etc/pki/tls/certs/web.crt |
-k | Ruta de archivo de clave privada | /etc/pki/tls/private/web.key |
-K | Principal Kerberos | HTTP/web.example.com@REALM |
-D | SAN DNS | web.example.com |
-N | DN del sujeto | CN=web,O=Example |
-C | Comando post-guardado | systemctl reload httpd |
-B | Comando pre-guardado | systemctl stop httpd |
-c | Nombre CA | IPA o external-ca |
-T | Perfil de certificado | caIPAserviceCert |
-g | Tamaño de clave | 2048 o 4096 |
-G | Tipo de clave | rsa 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ística | certmonger | certbot |
|---|---|---|
| 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ón | 2/3 del tiempo de vida | 30 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
- certmonger es la automatización de certificados de RHEL
- Configúralo y olvídalo - Renovación automática
- Funciona mejor con FreeIPA, CAs internas y renovaciones basadas en helpers
- Comandos post-guardado recargan servicios automáticamente
- Rastrea expiración y renueva a 2/3 del tiempo de vida
- Estado MONITORING significa que todo está bien
- 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
| ← Anterior: Capítulo 21 - Mejores Prácticas para Certificados de Servicios | Siguiente: Capítulo 23 - Inmersión Profunda en Crypto-Policies → |
|---|
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ítica | Versiones TLS | RSA Mín | SHA-1 | 3DES | DH Mín | Caso de Uso |
|---|---|---|---|---|---|---|
| DEFAULT | 1.2, 1.3 | 2048 | ❌ | ❌ | 2048 | ✅ Recomendado |
| LEGACY | 1.0+ | 1024 | ⚠️ | ⚠️ | 1024 | Solo compatibilidad |
| FUTURE | 1.2, 1.3 | 3072 | ❌ | ❌ | 3072 | Alta seguridad |
| FIPS | 1.2, 1.3 | 2048 | ❌ | ❌ | 2048 | Cumplimiento 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ítica | Efecto | Caso de Uso |
|---|---|---|
NO-SHA1 | Deshabilitar completamente SHA-1 | Seguridad extra |
AD-SUPPORT | Habilitar compatibilidad AD | Mixto Windows/Linux |
GOST | Habilitar algoritmos GOST | Requisitos rusos |
NO-CAMELLIA | Deshabilitar cifrado Camellia | Cumplimiento específico |
NO-ENFORCE-EMS | Deshabilitar Extended Master Secret | Compatibilidad |
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 Certificado | DEFAULT | LEGACY | FUTURE | FIPS |
|---|---|---|---|---|
| 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
- Crypto-policies son solo RHEL 8+ (no en RHEL 7)
- Política DEFAULT es recomendada para la mayoría de casos
- Los cambios requieren reinicios de servicio para tener efecto
- Afecta TODAS las aplicaciones crypto en todo el sistema
- Las subpolíticas proporcionan ajuste fino (RHEL 9+)
- Evitar sobrescrituras por app cuando sea posible
- Probar antes de desplegar nuevas políticas
- ¡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 uso | Herramienta recomendada |
|---|---|
| Certificado público de internet de Let’s Encrypt | certbot |
| Certificado interno de FreeIPA / IdM | certmonger con ipa-getcert |
| ACME contra tu propio endpoint IdM ACME | certbot 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ímite | Valor | Período |
|---|---|---|
| Certificados por dominio | 50 | por semana |
| Certificados duplicados | 5 | por semana |
| Validaciones fallidas | 5 | por hora |
| Nuevas cuentas | 10 | por 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
- Let’s Encrypt proporciona certificados gratuitos para dominios públicos
- certbot requiere EPEL en TODAS las versiones RHEL (no soportado oficialmente)
- certbot automatiza configuración de Apache/NGINX
- Validez de 90 días requiere renovación automática
- certmonger sigue siendo la opción nativa para flujos de FreeIPA y CA interna
- Para servicios internos: Usar FreeIPA en su lugar
- Probar con –dry-run para evitar límites de tasa
- 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
| ← Anterior: Capítulo 23 - Inmersión Profunda en Crypto-Policies | Siguiente: Capítulo 25 - Automatización Ansible para Certificados → |
|---|
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
- Ansible habilita despliegue masivo de certificados
- Colección community.crypto esencial para tareas de certificados
- Usar ansible-vault para claves privadas
- Playbooks idempotentes son críticos
- Probar en staging antes de producción
- Combinar con certmonger para mejores resultados
- 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
| ← Anterior: Capítulo 24 - Let’s Encrypt y certbot | Siguiente: Capítulo 26 - Monitoreo y Alertas en RHEL → |
|---|
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
| Herramienta | Complejidad | Costo | Integración | Alertas |
|---|---|---|---|---|
| Scripts simples | Baja | Gratis | Fácil | Email/syslog |
| Nagios/Icinga | Media | Gratis | Buena | Múltiples |
| Prometheus + Grafana | Media-Alta | Gratis | Excelente | Potente |
| Zabbix | Media | Gratis | Buena | Múltiples |
| Comercial (Datadog, etc.) | Baja | $$$ | Excelente | Avanzadas |
| Red Hat Insights | Baja | Suscripción | Nativa | Dashboard |
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
- Monitorear proactivamente - No esperar a la expiración
- Advertencia de 30 días mínimo recomendada
- Estado de certmonger crítico si se usa automatización
- Múltiples canales de alerta (email, Slack, PagerDuty)
- Probar monitoreo - Asegurar que las alertas realmente te alcancen
- Registrar todo para pista de auditoría
- 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
| ← Anterior: Capítulo 25 - Automatización Ansible para Certificados | Siguiente: Capítulo 27 - Metodología de Solución de Problemas de Certificados RHEL → |
|---|
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 Error | Significado | Solución |
|---|---|---|
| 0 | OK | ✅ Sin problemas |
| 19 | Certificado autofirmado en cadena | Agregar CA al almacén de confianza |
| 20 | No se puede obtener cert emisor local | Falta CA o intermedio |
| 21 | No se puede verificar primer certificado | Falta cert intermedio |
| 27 | Certificado no confiable | CA 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
- Siempre seguir la metodología de 7 pasos - no saltar pasos
- Verificar versión RHEL primero - el comportamiento varía significativamente
- Verificar propiedades básicas del certificado antes de solución de problemas compleja
- Problemas de cadena de confianza son el problema más común
- Permisos de archivo causan muchos fallos “misteriosos”
- Crypto-policies (RHEL 8+) afectan todo
- SELinux puede bloquear acceso a certificados
- 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
| ← Anterior: Capítulo 26 - Monitoreo y Alertas en RHEL | Siguiente: Capítulo 28 - Errores Comunes de Certificados en RHEL → |
|---|
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:
- ¿Ves un error? Busca en este capítulo el mensaje de error
- ¿El servicio no inicia? Verifica Sección 28.3 (Errores de Configuración)
- ¿La conexión falla? Verifica Sección 28.4 (Errores de Validación)
- ¿Después de actualización RHEL? Verifica Sección 28.7 (Específico por Versión)
- ¿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
| # | Error | Causa Común | Solución Rápida |
|---|---|---|---|
| 1 | Certificado expirado | Olvidó renovar | Renovar certificado |
| 2 | unable to get local issuer | Falta CA en almacén confianza | Agregar CA a /etc/pki/ca-trust/source/anchors/ |
| 3 | certificate verify failed | Cadena incompleta | Instalar certs intermedios |
| 4 | Permission denied | Permisos de archivo incorrectos | chmod 600 en archivo de clave |
| 5 | hostname does not match | Desajuste CN/SAN | Reemitir con SANs correctos |
| 6 | no shared cipher | Incompatibilidad de cifrado | Verificar crypto-policy (RHEL 8+) |
| 7 | ca md too weak | Firma SHA-1 (RHEL 9+) | Reemitir con SHA-256+ |
| 8 | wrong version number | Desajuste versión TLS | Verificar soporte TLS del cliente |
| 9 | CA_UNREACHABLE | certmonger no puede alcanzar IPA | Verificar conectividad IPA |
| 10 | SELinux denying access | Contexto SELinux incorrecto | restorecon 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 modernoalgo 1— RSA (cifrar o firmar)digest algo 1— MD5 (criptográficamente roto)version 3en la firma — formato de firma antiguosigclass 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
| Campo | Significado |
|---|---|
off | Desplazamiento en bytes en el archivo (posición de inicio de este paquete) |
ctb | Cipher Type Byte (byte de encabezado en hex, codifica formato + tag) |
tag | Tipo de paquete (decodificado — ver tabla abajo) |
hlen | Longitud del encabezado en bytes |
plen | Longitud del contenido en bytes |
Tags de Paquete (tag=)
| Tag | Tipo de Paquete |
|---|---|
| 1 | Clave de Sesión Cifrada con Clave Pública |
| 2 | Firma |
| 3 | Clave de Sesión Cifrada con Clave Simétrica |
| 4 | Firma One-Pass |
| 5 | Clave Pública |
| 6 | Clave Secreta |
| 7 | Subclave Secreta |
| 8 | Datos Comprimidos |
| 9 | Datos Cifrados Simétricamente |
| 10 | Marcador |
| 11 | Datos Literales |
| 12 | Confianza |
| 13 | ID de Usuario |
| 14 | Subclave Pública |
| 17 | Atributo de Usuario |
| 18 | Datos Cifrados + Protección de Integridad |
| 19 | Código de Detección de Modificación |
IDs de Algoritmo de Clave Pública (algo)
| ID | Algoritmo |
|---|---|
| 1 | RSA (cifrar o firmar) |
| 2 | RSA (solo cifrar) |
| 3 | RSA (solo firmar) |
| 16 | Elgamal (solo cifrar) |
| 17 | DSA |
| 18 | ECDH |
| 19 | ECDSA |
| 21 | Diffie-Hellman |
| 22 | EdDSA (Ed25519, etc.) |
IDs de Algoritmo de Digest (Hash) (digest algo)
| ID | Algoritmo | Estado |
|---|---|---|
| 1 | MD5 | Roto — no usar |
| 2 | SHA-1 | Obsoleto — bloqueado en RHEL 9+ |
| 3 | RIPEMD-160 | Heredado |
| 8 | SHA-256 | Recomendado |
| 9 | SHA-384 | Fuerte |
| 10 | SHA-512 | Fuerte |
| 11 | SHA-224 | Aceptable |
Clases de Firma (sigclass)
| Código | Significado |
|---|---|
| 0x00 | Firma de documento binario |
| 0x01 | Firma de texto canónico |
| 0x02 | Firma independiente |
| 0x10 | Certificación genérica de clave |
| 0x11 | Certificación de persona |
| 0x12 | Certificación casual |
| 0x13 | Certificación positiva |
| 0x18 | Vinculación de subclave |
| 0x19 | Vinculación de clave primaria |
| 0x1F | Firma directa de clave |
| 0x20 | Revocación de clave |
| 0x28 | Revocación de subclave |
| 0x30 | Revocación de certificación |
| 0x40 | Marca de tiempo |
| 0x50 | Confirmación de terceros |
Versiones de Paquete de Clave
| Versión | Era | Estado |
|---|---|---|
| 3 | PGP 2.x (1990s) | Obsoleto — usa MD5 internamente, rechazado por GnuPG moderno |
| 4 | OpenPGP RFC 4880 (2007) | Estándar actual |
| 5 | Borrador (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]
| Campo | Significado |
|---|---|
algo 1 | Algoritmo de clave pública utilizado (RSA) |
keyid | Identificador corto de la clave firmante |
version 3 | Versión del formato de firma (v3 = heredado) |
created | Marca de tiempo Unix de creación de firma |
md5len | Longitud del prefijo MD5 (artefacto heredado v3) |
sigclass 0x10 | Tipo de firma (certificación genérica de clave) |
digest algo 1 | Algoritmo de hash (MD5) |
begin of digest | Primeros 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 delgpg-pubkeyde RPM en hexadecimal minúscula (a47e31d2). Sirpm -eindica «not installed», liste todas las claves conrpm -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:
- Eliminar las claves de firma antiguas con SHA-1 e importar las claves actualizadas del proveedor
- Reconstruir la base de datos RPM con
rpm --rebuilddb - 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 Error | Código Error | Causa | Capítulo |
|---|---|---|---|
| “certificate has expired” | - | Cert expirado | 28.4 |
| “unable to get local issuer” | 20 | Falta CA | 28.4 |
| “unable to verify first cert” | 21 | Falta intermedio | 28.4 |
| “self signed certificate” | 18 | Autofirmado no confiable | 28.4 |
| “certificate verify failed” | - | Validación general | 28.4 |
| “ca md too weak” | 3 | Firma SHA-1 | 28.7 |
| “no shared cipher” | - | Desajuste de cifrado | 28.6 |
| “wrong version number” | - | Desajuste versión TLS | 28.6 |
| “Permission denied” | - | Permisos de archivo | 28.3 |
| “key values mismatch” | - | Cert/clave no emparejan | 28.3 |
| “hostname does not match” | - | Desajuste CN/SAN | 28.4 |
| “CA_UNREACHABLE” | - | certmonger no alcanza IPA | 28.9 |
| “CA_REJECTED” | - | IPA rechazó solicitud | 28.9 |
| “skipped PGP-2 keys” | - | Importación GPG clave v3 rechazada | 28.10 |
| “SHA1 is not considered secure” | - | Clave GPG de terceros usa SHA-1 | 28.11 |
| “Malformed MPI” | - | Firma OpenPGP no conforme | 28.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
- La mayoría de errores son predecibles - Patrones comunes
- Siempre verificar expiración primero - Causa #1 de problemas
- Los permisos importan - 600 para claves, 644 para certs
- Cadena de confianza crítica - Falta CA o intermedio
- La versión RHEL importa - Errores diferentes por versión
- crypto-policies afectan todo (RHEL 8+)
- SELinux puede bloquear - Verificar contextos
- 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
| ← Anterior: Capítulo 27 - Metodología de Solución de Problemas de Certificados RHEL | Siguiente: Capítulo 29 - Solución de Problemas Específica por Servicio → |
|---|
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
| Error | Causa | Solución |
|---|---|---|
| “SSLCertificateFile: file does not exist” | Ruta incorrecta | Corregir ruta en ssl.conf |
| “key values mismatch” | Cert/clave no emparejan | Regenerar con clave correcta |
| “unable to load certificate” | Problema formato archivo | Asegurar formato PEM |
| “Syntax error” en ssl.conf | Error de tipeo en config | Ejecutar apachectl configtest |
| “unable to verify certificate” | Problema de cadena | Agregar 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
| Error | Causa | Solución |
|---|---|---|
| “SSL: error:0200100D” | Permission denied en clave | chmod 600 en clave |
| “no "ssl" is defined” | Falta ssl en listen | Agregar listen 443 ssl; |
| “cannot load certificate” | Archivo no encontrado | Verificar ruta |
| “PEM_read_bio:no start line” | Formato incorrecto | Asegurar formato PEM |
| “nginx: [emerg] bind() failed” | Puerto en uso | Verificar 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
| Error | Causa | Solución |
|---|---|---|
| “SSL_accept error” | Problema cert/clave | Verificar par cert/clave |
| “TLS is required but not available” | TLS no habilitado | Establecer security_level = may |
| “no shared cipher” | Desajuste de cifrado | Verificar crypto-policy |
| “certificate verify failed” | Problema de cadena | Instalar intermedio |
| “Permission denied” | Permisos de clave | chmod 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
| Error | Causa | Solución |
|---|---|---|
| “TLS: can’t accept” | Clave no legible | chown ldap:ldap en clave |
| “TLS: hostname does not match” | Desajuste CN/SAN | Reemitir con hostname correcto |
| “certificate verify failed” | CA no confiable | Agregar CA al almacén de confianza |
| “Permission denied” | Ownership incorrecto | chown ldap:ldap |
| “TLS engine not initialized” | TLS no configurado | Agregar 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
| Error | Causa | Solución |
|---|---|---|
| “could not load server certificate” | Permission denied | chown postgres:postgres, chmod 600 |
| “private key file has wrong permissions” | Muy permisivo | chmod 600 en clave |
| “SSL connection has been closed unexpectedly” | Problema de confianza | Verificar confianza CA del cliente |
| “SSL is not enabled” | SSL off en config | Establecer 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
- Cada servicio tiene requisitos únicos - Ownership, ubicación, formato
- Siempre verificar logs específicos del servicio primero
- Probar con comandos específicos del servicio (no solo openssl)
- Permisos críticos - Usuarios diferentes para servicios diferentes
- Las ubicaciones de archivo importan - Rutas dependientes del servicio
- Sintaxis de configuración varía por servicio
- 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
| ← Anterior: Capítulo 28 - Errores Comunes de Certificados en RHEL | Siguiente: Capítulo 30 - Solución de Problemas de certmonger → |
|---|
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
| Estado | Significado | Acción Requerida |
|---|---|---|
MONITORING | ✅ Todo bien - cert emitido, rastreando expiración | Ninguna |
SUBMITTING | 🔄 Solicitando cert de CA | Esperar (usualmente segundos) |
CA_UNREACHABLE | ❌ No se puede contactar servidor CA | Corregir conectividad |
CA_REJECTED | ❌ CA rechazó solicitud | Corregir principal/permisos |
NEED_KEY_GEN_PIN | ⏸️ Esperando PIN (HSM) | Proporcionar PIN |
NEED_GUIDANCE | ⚠️ Necesita intervención manual | Verificar detalles de solicitud |
PRE_SAVE_COMMAND | 🔄 Ejecutando script pre-guardado | Esperar |
POST_SAVE_COMMAND | 🔄 Ejecutando script post-guardado | Esperar |
NEWLY_ADDED | 🆕 Recién agregado, aún no procesado | Esperar |
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
- CA_UNREACHABLE es el problema más común - Verificar conectividad IPA
- CA_REJECTED significa problema de principal - Crear principal de servicio
- Estado MONITORING significa que todo está bien
- Comandos post-guardado críticos - Probarlos independientemente
- Logs de certmonger en journal - Usar
journalctl -u certmonger - Reintentar con resubmit - A menudo corrige problemas transitorios
- 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
| ← Anterior: Capítulo 29 - Solución de Problemas Específica por Servicio | Siguiente: Capítulo 31 - Solución de Problemas de Crypto-Policy → |
|---|
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
- Crypto-policies son solo RHEL 8+ (no RHEL 7)
- Los servicios DEBEN reiniciarse después de cambio de política
- Los cambios de política son en todo el sistema - Afectan todo
- DEFAULT es recomendada para la mayoría de entornos
- LEGACY debería ser solo temporal
- Probar antes de desplegar nuevas políticas
- 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
| ← Anterior: Capítulo 30 - Solución de Problemas de certmonger | Siguiente: Capítulo 32 - Análisis de Informes SOS → |
|---|
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
- Los informes SOS son invaluables para solución de problemas remota
- No incluyen claves privadas (¡seguridad!)
- SÍ incluyen información de certificados (certs públicos, config, logs)
- Estado de certmonger preservado en salida getcert_list
- Crypto-policy registrada (RHEL 8+)
- Usar para análisis post-incidente y auditorías
- 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
| ← Anterior: Capítulo 31 - Solución de Problemas de Crypto-Policy | Siguiente: Capítulo 33 - Procedimientos de Emergencia → |
|---|
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:
-
Evaluar (30 segundos)
openssl x509 -in /etc/pki/tls/certs/server.crt -noout -dates -
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> -
Comunicar (5 minutos)
- Notificar stakeholders
- Actualizar página de estado
-
Solución Apropiada (15-60 minutos)
# Solicitar nuevo cert de CA # O usar certmonger ipa-getcert resubmit -f /etc/pki/tls/certs/server.crt -
Reemplazar cert temp, verificar, documentar
Escenario 2: Certificado Incorrecto Desplegado
Impacto: MEDIO - Servicio activo pero con errores Presión de Tiempo: Moderada Respuesta:
-
Detener el sangrado - Rollback
./emergency-rollback.sh -
Verificar servicio restaurado
-
Identificar certificado correcto
-
Desplegar cert correcto con validación
-
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:
-
Verificar cronología de expiración de cert
openssl x509 -in cert.crt -noout -checkend $((86400*7)) -
Si > 7 días: Esperar recuperación de CA, monitorear
-
Si < 7 días:
- Generar autofirmado temporal
- Contactar soporte CA
- Escalar a gestión
-
Alternativa: Usar CA diferente temporalmente
Escenario 4: SELinux Bloqueando Certificados
Impacto: BAJO-MEDIO - Servicio no inicia Presión de Tiempo: Moderada Respuesta:
-
Verificar denegaciones
ausearch -m avc -ts recent | grep cert -
Solución rápida - Reetiquetar
restorecon -Rv /etc/pki/tls/ -
Si persiste - Permissive temporal
setenforce 0 # ¡TEMPORAL! systemctl restart <service> -
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
- Velocidad sobre perfección en emergencias
- Las soluciones temporales están OK - Corregir apropiadamente después
- La comunicación es crítica - Mantener informados a stakeholders
- Documentar todo - Para post-mortem
- Practicar procedimientos de emergencia - No esperar a incidente real
- Tener respaldos listos - Probarlos regularmente
- Conocer tu ruta de escalación - Cuándo pedir ayuda
- 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
| ← Anterior: Capítulo 32 - Análisis de Informes SOS | Siguiente: Capítulo 34 - Planificación y Preparación de Migración RHEL → |
|---|
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
- Planificar con anticipación - Comenzar 6-8 semanas antes de migración
- Auditar exhaustivamente - Conocer cada certificado
- Corregir problemas temprano - No esperar hasta el día de migración
- Probar extensivamente - Múltiples ejecuciones de prueba
- Respaldar todo - Certificados, configuraciones, DB certmonger
- Documentar claramente - Runbook, rollback, problemas
- 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ística | RHEL 7 | RHEL 8 | Impacto |
|---|---|---|---|
| OpenSSL | 1.0.2k | 1.1.1k | Moderado |
| Versiones TLS | 1.0/1.1/1.2 | 1.2/1.3 (DEFAULT) | ALTO |
| Crypto-Policies | Ninguna | ¡NUEVO! | ALTO |
| Cifrados Predeterminados | Mixtos | Más Estrictos | Moderado |
| certmonger | Básico | Mejorado | Bajo |
| Gestión | Manual | Automatizada (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
- Usar utilidad leapp para migración RHEL 7→8 (método soportado)
- crypto-policies son NUEVAS en RHEL 8 - ¡Cambio mayor!
- TLS 1.0/1.1 deshabilitado por defecto - Probar compatibilidad de cliente
- Eliminar configuraciones TLS manuales - Dejar que crypto-policy gestione
- Probar extensivamente antes de migración de producción
- Política LEGACY disponible para compatibilidad (¡temporal!)
- 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
| ← Anterior: Capítulo 34 - Planificación y Preparación de Migración RHEL | Siguiente: Capítulo 36 - Migración RHEL 8→9 → |
|---|
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ística | RHEL 8 | RHEL 9 | Impacto |
|---|---|---|---|
| OpenSSL | 1.1.1k | 3.5.5 | ALTO |
| Arquitectura | Tradicional | Basada en proveedores | ALTO |
| TLS 1.0/1.1 | Política LEGACY | Completamente eliminado | ALTO |
| SHA-1 | Obsoleto | Bloqueado | ALTO |
| Validación | Estándar | Más Estricta | Moderado |
| Crypto-Policies | Básicas | Subpolíticas | Bajo |
| certmonger | Mejorado | Soporte ACME | Bajo |
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
- OpenSSL 3.x es cambio mayor - La arquitectura de proveedores es nueva
- SHA-1 DEBE eliminarse antes de migración - ¡Sin excepciones!
- Usar leapp para migración (oficialmente soportado)
- Probar aplicaciones personalizadas en RHEL 9 primero
- Validación más estricta captura más problemas (¡bueno para seguridad!)
- certmonger gana soporte ACME en RHEL 9
- 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
| ← Anterior: Capítulo 35 - Migración RHEL 7→8 | Siguiente: Capítulo 37 - Solución de Problemas y Recuperación de Migración → |
|---|
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
| Problema | Síntomas | Causa | Solución Rápida |
|---|---|---|---|
| 1. Servicios no inician | systemctl status falla | Sintaxis config cambió | Restaurar config, actualizar sintaxis |
| 2. Rechazo SHA-1 (RHEL 9) | “ca md too weak” | Firma SHA-1 | Reemitir certificado |
| 3. Desajuste versión TLS | Clientes no pueden conectar | TLS 1.0/1.1 bloqueado | Política LEGACY (temp) |
| 4. Problemas crypto-policy | Varios errores | Nuevo sistema de política | Entender y configurar |
| 5. certmonger perdió rastreo | getcert list vacío | Corrupción DB | Restaurar desde respaldo |
| 6. CAs faltantes | Cert verify failed | Almacén confianza reiniciado | Re-agregar CAs |
| 7. Cambios de permisos | Permission denied | Ownership cambió | Corregir permisos |
| 8. Denegaciones SELinux | Servicio bloqueado | Contexto cambió | Reetiquetar archivos |
| 9. Errores proveedor (RHEL 9) | Algoritmo no soportado | Cambio OpenSSL 3.x | Usar -provider legacy |
| 10. Degradación rendimiento | Conexiones lentas | Crypto más estricta | Esperado, 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
- Tener plan de rollback listo antes de migración
- La mayoría de problemas son corregibles sin rollback
- Cambios de crypto-policy causan la mayoría de problemas de compatibilidad
- Rechazo SHA-1 no es negociable en RHEL 9
- Probar, probar, probar antes de migración de producción
- Documentar todo durante la solución de problemas
- 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 RHEL | Estado FIPS | Estándar | Notas |
|---|---|---|---|
| RHEL 7 | Validado | FIPS 140-2 | Módulos OpenSSL 1.0.2 validados |
| RHEL 8 | Validado | FIPS 140-2 | OpenSSL 1.1.1, NSS, libgcrypt validados |
| RHEL 9 | Validado | FIPS 140-2 | Proveedor OpenSSL 3.x, transición a 140-3 en progreso |
| RHEL 10 | En proceso | FIPS 140-2/140-3 | Transició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
- FIPS 140-2 es el estándar actual en RHEL (transición 140-3 en progreso)
- Habilitar en instalación para estado FIPS más limpio
- Habilitación post-instalación requiere reinicio
- Solo algoritmos aprobados por FIPS permitidos
- Crypto-policy automáticamente establecida a FIPS
- Los servicios cumplen automáticamente
- 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
| ← Anterior: Capítulo 37 - Solución de Problemas y Recuperación de Migración | Siguiente: Capítulo 39 - Certificados Compatibles con FIPS → |
|---|
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
- FIPS 140-2 es el estándar validado actual en RHEL
- Transición FIPS 140-3 está en progreso
- Habilitar en instalación para mejores resultados
- Solo RSA 2048+ o ECC P-256/384
- Firmas SHA-256+ requeridas
- Los servicios cumplen automáticamente con política FIPS
- 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
| ← Anterior: Capítulo 38 - Guía Completa del Modo FIPS | Siguiente: Capítulo 40 - Fortalecimiento de Seguridad RHEL para Certificados → |
|---|
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:
- Permisos de Archivo - Proteger claves privadas
- SELinux - Control de acceso obligatorio
- Firewall - Limitar exposición
- Auditoría - Rastrear acceso
- TPM - Protección de clave por hardware
- Tarjetas Inteligentes - Tokens físicos
- Monitoreo - Detectar problemas
- 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
- Defensa en profundidad - Múltiples capas de seguridad
- SELinux enforcing - Obligatorio para producción
- Permisos de archivo críticos - 400/600 para claves
- Auditar todo - Rastrear acceso a claves
- TPM para alta seguridad - Protección por hardware
- OpenSCAP para cumplimiento - Escaneo automatizado
- 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
| ← Anterior: Capítulo 39 - Certificados Compatibles con FIPS | Siguiente: Capítulo 41 - Cumplimiento y Auditoría → |
|---|
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
| Marco | Enfoque | Requisitos de Certificados |
|---|---|---|
| STIG | Seguridad DoD | FIPS, algoritmos fuertes, auditoría |
| CIS Benchmark | Mejores prácticas industria | TLS 1.2+, cifrados fuertes, permisos |
| PCI-DSS | Industria tarjetas de pago | Crypto fuerte, no TLS/cifrados débiles |
| HIPAA | Salud | Cifrado, control acceso, auditoría |
| NIST 800-53 | Sistemas federales | FIPS, 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
- El cumplimiento es continuo - No es de una sola vez
- Existen múltiples marcos - STIG, CIS, PCI, HIPAA
- OpenSCAP automatiza escaneo en RHEL
- Documentar todo - Requerido para auditorías
- Auditorías regulares esenciales - Trimestral mínimo
- La remediación debe rastrearse - Corregir y verificar
- 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:
-
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
-
Tu Versión RHEL (1-2 horas)
- Cap 9 (RHEL 7), Cap 10 (RHEL 8), Cap 11 (RHEL 9), o Cap 12 (RHEL 10)
-
Tus Servicios (3-4 horas)
- Cap 14-21: Elegir capítulos para servicios que usas
-
Automatización (2-3 horas)
- Cap 22: certmonger
- Cap 23: Crypto-policies (si RHEL 8+)
-
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:
-
Comenzar Aquí (1 hora)
- Cap 27: Metodología de Solución de Problemas de Certificados RHEL ⭐
- Guía de Inicio Rápido de Solución de Problemas
-
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
-
Herramientas (1 hora)
- Cap 3: Herramientas RHEL
- Cap 32: Informes SOS
-
Emergencia (30 min)
- Cap 33: Procedimientos de Emergencia
-
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:
-
Resumen (1 hora)
- Cap 1-2: Fundamentos e introducción
-
CA Empresarial (2 horas)
- Cap 19: FreeIPA
-
Automatización (3 horas)
- Cap 22: certmonger
- Cap 23: Crypto-policies
- Cap 25: Automatización Ansible para Certificados
-
Mejores Prácticas (2 horas)
- Cap 21: Mejores Prácticas de Servicio
- Cap 26: Monitoreo y Alertas en RHEL
-
Seguridad (3 horas)
- Cap 38-41: FIPS, fortalecimiento, cumplimiento
-
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:
-
Fundamento (1 hora)
- Cap 1: Criptografía y Fundamentos de PKI
- Cap 2: Introducción a Certificados en RHEL
-
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 ⭐
-
Crypto-Policies (1 hora)
- Cap 23: Entender controles en todo el sistema
-
Monitoreo (1 hora)
- Cap 26: Monitoreo y Alertas en RHEL
-
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
| Camino | Tiempo | Capítulos |
|---|---|---|
| Inicio Rápido | 3-5 horas | 1, 3, 27 |
| Solución de Problemas | 5-8 horas | 27-33 |
| Principiante Completo | 40-50 horas | Todos en orden |
| Administrador de sistemas | 10-15 horas | Capítulos seleccionados |
| Ingeniero Soporte | 5-8 horas | Enfoque de solución de problemas |
| Cumplimiento | 8-10 horas | Capítulos seguridad |
💡 Consejos de Estudio
- Práctica es esencial - Practicar en VM RHEL
- Seguir ejemplos - Copiar-pegar y entender
- Usar referencias rápidas - Cuando el capítulo las incluya
- Marcar solución de problemas - Capítulos 27-33
- Conocer tu versión RHEL - Enfocarse en capítulos relevantes
- 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 Problema | Ir al Capítulo |
|---|---|
| Solución de problemas general | Capítulo 27 |
| Errores comunes | Capítulo 28 |
| Problemas Apache/NGINX/Postfix | Capítulo 29 |
| Problemas de certmonger | Capítulo 30 |
| Problemas de crypto-policy | Capítulo 31 |
| Análisis de informes SOS | Capítulo 32 |
| Emergencia en producción | Capítulo 33 |
| Específico para RHEL 7 | Capítulo 9 |
| Específico para RHEL 8 | Capítulo 10 |
| Específico para RHEL 9 | Capítulo 11 |
| Específico para RHEL 10 | Capítulo 12 |
| Después de migración | Capí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:
- Certificado expirado → Renovar
- CA faltante → Agregar al almacén de confianza
- Permisos incorrectos → chmod 600
- Desajuste cert/clave → Regenerar CSR
- Desajuste de hostname → Reemitir con SANs
- Versión TLS → Verificar crypto-policy
- SELinux denegando → restorecon
- 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
| RHEL | Lanzado | OpenSSL | Soporte TLS | Crypto-Policies | Característica Principal |
|---|---|---|---|---|---|
| 7 | 2014 | 1.0.2k-26 | 1.0/1.1/1.2 | ❌ No | Configuración manual |
| 8 | 2019 | 1.1.1k-14 | 1.2/1.3 | ✅ ¡NUEVO! | Políticas en todo el sistema |
| 9 | 2022 | 3.5.5-2 | 1.2/1.3 | ✅ Mejorado | OpenSSL 3.x, estricto |
| 10 | 2025 | 3.5.5-2 | 1.3 pref | ✅ Mejorado | Preparació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
| Tarea | RHEL 7 | RHEL 8/9/10 |
|---|---|---|
| Generar Clave | openssl genrsa -out key 2048 | openssl genpkey -algorithm RSA -out key |
| Verificar Política | N/A | update-crypto-policies --show |
| Config TLS | Manual por servicio | Automática vía crypto-policies |
| certmonger | Básico | Mejorado (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 legacypara 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ón | Impacto en Certificados | Cambios Principales |
|---|---|---|
| 7→8 | Moderado-Alto | crypto-policies, TLS 1.0/1.1 bloqueado |
| 8→9 | Alto | OpenSSL 3.x, SHA-1 bloqueado, más estricto |
| 9→10 | Bajo | Mismo 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ón | Propósito |
|---|---|
| SAN: URI:spiffe:// | ID de Carga de Trabajo |
| Key Usage: digitalSignature | AuthN |
| EKU: clientAuth, serverAuth | TLS Mutuo |
| Validity ≤ 24h | Limitar radio de explosión |
4. Puntos de Aplicación de Política
- Gateways terminan TLS y verifican certs de cliente.
- Service Mesh sidecars realizan mTLS transparentemente.
- 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
| Documento | Audiencia | Contenido |
|---|---|---|
| CP | Partes confiantes | Qué aseguramiento proporciona la PKI |
| CPS | Auditores, operadores | Có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
- El dispositivo genera par de claves dentro de ATECC608.
- CSR creado usando clave en chip.
- 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áctica | Razón |
|---|---|
| Usar ECC (P-256, P-384) | Claves más pequeñas, menor consumo de energía |
| Hardware Root of Trust | TPM, ATECC, o TrustZone previenen extracción de clave |
| Validez de Certificado ≤ 1 año | Limitar radio de explosión de compromiso |
| Revocación vía OCSP/CRL | Deshabilitar dispositivos comprometidos remotamente |
| PKI Separada para IoT | Aislar 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
| VPN | Soporte Certificado | Gestión de Claves | Caso de Uso |
|---|---|---|---|
| OpenVPN | PKI X.509 completa | Easy-RSA, manual | Sitio-a-sitio empresarial y acceso remoto |
| WireGuard | Claves públicas (no X.509 por defecto) | Pares de claves simples | Moderno, alto rendimiento, IoT |
| IPsec (strongSwan) | PKI X.509 completa | Herramientas ipsec pki | Conforme a estándares, interop con Cisco/Juniper |
6. Mejores Prácticas
- CA Separada para VPN – Aislar certs VPN de certs TLS web.
- Validez Corta – Emitir certs de cliente VPN con expiración 30-90 días.
- CRL/OCSP – Habilitar verificación de revocación en el servidor.
- 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:
- Qué hace realmente Secure Boot.
- Dónde se usan certificados y claves en la cadena de arranque.
- 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ón | Propósito |
|---|---|
| Variables de firmware UEFI | Almacenan anclas de confianza de la plataforma y revocaciones |
shim | Contiene confianza embebida del proveedor para verificación de la siguiente etapa |
| Keyrings del kernel | Mantienen claves de confianza usadas para autenticar módulos y artefactos relacionados |
| Lista MOK | Añade confianza controlada por el propietario sin reescribir las bases de datos del firmware |
| Bloques de firma en binarios EFI | Demuestran 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 datos | Significado | Rol típico |
|---|---|---|
PK | Platform Key | Propietario de nivel superior de la política de Secure Boot de la plataforma |
KEK | Key Exchange Key database | Autoriza actualizaciones a las bases de datos de firmas permitidas y revocadas |
db | Firmas / certificados permitidos | Lista de confianza para ejecutables y controladores EFI |
dbx | Firmas / certificados / hashes prohibidos | Lista de revocación usada para bloquear binarios o certificados conocidos como maliciosos |
Son conceptualmente simples, pero los administradores los confunden rutinariamente:
PKcontrola la autoridad de Secure Boot de la plataforma.KEKcontrola las actualizaciones de la lista de permitidos y la lista de denegados.dbindica qué está permitido arrancar.dbxindica 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:
- El firmware valida el cargador de arranque EFI de primera etapa contra las claves de confianza en las bases de datos del firmware.
- El cargador de primera etapa es típicamente
shim. shimcontiene un ancla de confianza embebida de Red Hat usada para autenticar la siguiente etapa.shimvalida el binario EFI de GRUB de RHEL.- GRUB valida el kernel que carga usando la clave pública embebida en
shim(GRUB no lleva sus propias claves de confianza). - 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. shimcontiene 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:
- Deshabilitar Secure Boot cada vez que necesites código personalizado.
- 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.
shimyMokManagergestionan 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:
| Keyring | Rol |
|---|---|
.builtin_trusted_keys | Claves de confianza integradas embebidas en el kernel o cargadas como parte de la ruta de arranque de confianza |
.platform | Confianza derivada de la plataforma, incluyendo claves provenientes de las bases de datos de Secure Boot y MOK |
.blacklist | Claves 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_keysy.platform - las entradas revocadas de la blacklist se excluyen de la verificación
- las claves MOK se propagan a
.platformen 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ística | Función principal |
|---|---|
| Secure Boot | Bloquea la ejecución de código no autorizado en la ruta de arranque |
| Measured Boot | Registra mediciones de arranque en los PCRs del TPM |
| TPM | Almacena secretos protegidos y mediciones; puede sellar datos al estado del arranque |
| IMA appraisal | Extiende 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
kexecsin 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:
- El firmware confía en las claves en
dby rechaza claves o hashes endbx. - El firmware autoriza
shim. shimautoriza los componentes de arranque de la siguiente etapa de Red Hat y también soporta operaciones MOK.- MOK te permite añadir certificados públicos controlados por el propietario.
- El kernel confía en claves integradas y derivadas de la plataforma/MOK para la verificación de módulos.
- 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:dbshimembebidoUEFI: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:
| Herramienta | Propósito |
|---|---|
pesign | Firmar e inspeccionar binarios EFI y kernels |
efikeygen | Generar un par de claves X.509 orientado a Secure Boot en la base de datos de pesign |
mokutil | Inscribir e inspeccionar Machine Owner Keys y el estado de Secure Boot |
keyctl | Inspeccionar keyrings del kernel |
sign-file | Añadir firmas a módulos del kernel de Linux |
certutil / pk12util | Exportar claves y certificados desde la base de datos NSS usada por pesign |
openssl | Extraer 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:
shimdetecta la inscripción pendiente.MokManager.efise inicia.- Eliges
Enroll MOK. - Introduces la contraseña que estableciste durante
mokutil --import. - 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
shimembebido - Claves inscritas por el propietario provenientes de
MokListRT - Revocaciones reflejadas en
.blacklist
Eso te da tres fuentes de confianza diferentes en juego:
- Confianza del firmware
- Confianza embebida del proveedor
- 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
- Actualizar
shimen 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. - 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 deshimfirmados solo con la clave 2023 no serán aceptados. - Tener en cuenta el impacto en el TPM: las actualizaciones de UEFI
dbcambiará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 endb. 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. - 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
shimfirmados 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:
shimcomo 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.blacklistefikeygenpesign- 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íntoma | Causa probable |
|---|---|
| El módulo no se carga | Módulo sin firmar o firmante no confiable |
| El módulo muestra firmante pero aún falla | Clave 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 visible | Inscripción no completada en MokManager después del reinicio |
| El binario EFI no arranca | Falta firma de confianza, flujo de trabajo de reemplazo incorrecto o certificado/hash revocado |
| El comportamiento cambió después de una actualización de firmware | Cambios en db/dbx alteraron el estado de confianza o revocación |
| El flujo de trabajo de desbloqueo con TPM falla después de actualizar claves | Las 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:
integrityMokListRTEFI: Loaded certLockdownmodule 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
- Secure Boot es fácil hasta que necesitas código personalizado.
- El código personalizado es fácil hasta que necesitas operaciones de firma duraderas.
- 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
shimvs 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
- Secure Boot es una cadena de autorización basada en certificados para el código de arranque y del espacio del kernel.
- En RHEL,
shimes el puente entre la confianza del firmware y la confianza controlada por Red Hat. - MOK es el mecanismo crítico para añadir confianza controlada por el propietario sin reescribir las bases de datos del firmware.
- La carga de módulos del kernel depende de los keyrings de confianza, no del paquete CA de espacio de usuario.
- La revocación importa tanto como la confianza;
dbxy.blacklistpueden romper artefactos que “antes funcionaban.” - 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
-
RFC 5280 — Internet X.509 Public Key Infrastructure Certificate and CRL Profile https://datatracker.ietf.org/doc/html/rfc5280
-
RFC 6960 — Online Certificate Status Protocol (OCSP) https://datatracker.ietf.org/doc/html/rfc6960
-
RFC 6962 — Certificate Transparency https://datatracker.ietf.org/doc/html/rfc6962
-
RFC 8555 — Automatic Certificate Management Environment (ACME) https://datatracker.ietf.org/doc/html/rfc8555
-
RFC 7030 — Enrollment over Secure Transport (EST) https://datatracker.ietf.org/doc/html/rfc7030
TLS/SSL
-
RFC 8446 — The Transport Layer Security (TLS) Protocol Version 1.3 https://datatracker.ietf.org/doc/html/rfc8446
-
RFC 6125 — Representation and Verification of Domain-Based Application Service Identity https://datatracker.ietf.org/doc/html/rfc6125
Algoritmos Criptográficos
-
RFC 3447 — RSA Cryptography Specifications (PKCS #1 v2.1) https://datatracker.ietf.org/doc/html/rfc3447
-
RFC 6090 — Fundamental Elliptic Curve Cryptography Algorithms https://datatracker.ietf.org/doc/html/rfc6090
-
FIPS 186-5 — Digital Signature Standard (DSS) https://csrc.nist.gov/publications/detail/fips/186/5/final
Guías de Industria
CA/Browser Forum
-
Baseline Requirements for TLS Certificates https://cabforum.org/baseline-requirements-documents/
-
EV SSL Certificate Guidelines https://cabforum.org/extended-validation/
Publicaciones NIST
-
SP 800-57 — Recommendation for Key Management https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final
-
SP 800-207 — Zero Trust Architecture https://csrc.nist.gov/publications/detail/sp/800-207/final
-
SP 800-52 Rev. 2 — Guidelines for TLS Implementations https://csrc.nist.gov/publications/detail/sp/800-52/rev-2/final
Estándares ETSI
- ETSI EN 319 411-1 — Policy and security requirements for Trust Service Providers issuing certificates https://www.etsi.org/standards
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
-
OpenSSL Documentation https://www.openssl.org/docs/
-
Let’s Encrypt Documentation https://letsencrypt.org/docs/
-
cert-manager Documentation https://cert-manager.io/docs/
-
HashiCorp Vault PKI Secrets Engine https://www.vaultproject.io/docs/secrets/pki
-
FreeIPA Documentation https://www.freeipa.org/page/Documentation
Herramientas de Prueba
-
SSL Labs Server Test https://www.ssllabs.com/ssltest/ Probar configuración de servidor HTTPS y cadena de certificado
-
testssl.sh https://testssl.sh/ Herramienta de prueba TLS/SSL de línea de comandos
-
crt.sh — Certificate Search https://crt.sh/ Consultar logs de Certificate Transparency
-
Hardenize https://www.hardenize.com/ Escáner comprehensivo TLS/PKI
Tutoriales y Blogs
-
Cloudflare Learning Center — SSL/TLS https://www.cloudflare.com/learning/ssl/
-
Mozilla SSL Configuration Generator https://ssl-config.mozilla.org/ Generar configuraciones TLS seguras para servidores comunes
-
PKI Solutions Blog https://pkisolutions.com/blog/ Perspectivas PKI empresarial
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
- OpenSSL — https://www.openssl.org/
- FreeIPA — https://www.freeipa.org/
- EJBCA — https://www.ejbca.org/
- step-ca — https://smallstep.com/docs/step-ca
- HashiCorp Vault — https://www.vaultproject.io/
Gestión de Certificados
- cert-manager (Kubernetes) — https://cert-manager.io/
- Certbot (cliente ACME) — https://certbot.eff.org/
- certmonger (RHEL) — https://pagure.io/certmonger
- Venafi (Empresarial) — https://www.venafi.com/
Bibliotecas
- BouncyCastle (Java/C#) — https://www.bouncycastle.org/
- cryptography (Python) — https://cryptography.io/
- Go crypto/x509 — https://pkg.go.dev/crypto/x509
Comunidades y Foros
-
Let’s Encrypt Community Forum https://community.letsencrypt.org/
-
r/crypto (Reddit) https://www.reddit.com/r/crypto/
-
r/netsec (Reddit) https://www.reddit.com/r/netsec/
-
IETF TLS Working Group https://datatracker.ietf.org/wg/tls/about/
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
-
PCI DSS — Payment Card Industry Data Security Standard https://www.pcisecuritystandards.org/
-
HIPAA — Health Insurance Portability and Accountability Act https://www.hhs.gov/hipaa/
-
SOC 2 — Service Organization Control 2 https://www.aicpa.org/
-
eIDAS — EU electronic identification and trust services https://digital-strategy.ec.europa.eu/en/policies/eidas-regulation
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.