Revocación de certificados SSL: CRL y OCSP en nginx y Apache
Si revocaste un certificado SSL y pensás que con eso ya está resuelto, malas noticias: el navegador del visitante puede seguir confiando en ese certificado durante horas o días. La revocación de certificados SSL no se valida sola como sí pasa con uno expirado. Necesita que el cliente consulte un servidor externo, vía CRL u OCSP, y ahí es donde la mayoría de las configuraciones fallan en silencio.
El 25 de junio de 2026, el desarrollador detrás de la serie “From Root CA to User Authorization in nginx+apache” publicó la segunda parte, dedicada a revocación, CRL y OCSP sobre una PKI de dos niveles (un Root CA y tres CAs intermedias: Person, Server y Code). Tomamos esa guía como base y te la traducimos a algo accionable para tu servidor.
La revocación de certificados SSL es el mecanismo por el cual una Autoridad de Certificación (CA) invalida un certificado antes de su fecha de vencimiento, por ejemplo si se filtró la clave privada o el dominio cambió de dueño. Para que un navegador se entere, existen dos protocolos: CRL (una lista descargable de seriales revocados) y OCSP (una consulta en línea por certificado individual). Ambos rompen la cadena de confianza, pero de forma distinta.
En 30 segundos
- Expirado vs revocado: lo expirado se valida por fecha en local; lo revocado obliga a una consulta externa (CRL u OCSP).
- CRL: una lista completa de seriales revocados que el cliente descarga; puede pesar varios MB si la CA es grande.
- OCSP: consulta el estado de un solo certificado; con OCSP stapling el servidor adjunta la respuesta y evita la latencia del cliente.
- CDP y AIA: extensiones que le dicen al verificador dónde está la CRL y el responder OCSP; sin ellas, nadie chequea revocación.
- Comandos clave:
openssl ca -revoke,openssl ca -gencrlyopenssl crl -text -noout.
¿Por qué un certificado revocado es diferente a uno expirado?
Ponele que tenés un certificado válido hasta 2027, pero te filtraron la clave privada hoy. El certificado sigue “vigente” según su fecha. Si solo dependés del vencimiento, cualquiera con esa clave puede suplantar tu sitio durante un año largo.
Ahí está la diferencia de fondo. Un certificado expirado lo detecta el cliente solo: compara la fecha del campo notAfter contra el reloj del sistema y listo, verificación 100% local, sin red. El navegador te tira un NET::ERR_CERT_DATE_INVALID y se acabó.
Un certificado revocado es otra historia. La fecha está perfecta, así que el cliente no tiene forma de saber que la CA lo invalidó salvo que pregunte afuera. Por eso necesitamos dos mecanismos de consulta externa. Sin ellos, la revocación existe en los papeles de la CA pero no llega al navegador.
¿Y qué ve el usuario cuando la cosa funciona? En Chrome, un NET::ERR_CERT_REVOKED. El problema es que muchos navegadores hacen “soft-fail”: si no pueden contactar al servidor de revocación, asumen que el certificado está bien y siguen. Esa es la grieta que un atacante puede explotar bloqueando la consulta. Relacionado: plataformas principales en desarrollo.
CRL: cómo funciona la lista de revocación de certificados
Una CRL (Certificate Revocation List) es un archivo firmado por la CA que lista todos los números de serie revocados. El cliente lo descarga, lo cachea y chequea si el serial del certificado que está validando aparece en la lista.
¿Dónde lo encuentra? En el campo CDP (CRL Distribution Points), una extensión que va dentro del certificado emitido y apunta a una URL tipo http://pki.tusitio.com/crl/server.crl. Si el certificado no trae ese campo, el cliente ni se entera de que existe una CRL para consultar.
El punto débil de CRL es el tamaño. En una CA con muchos certificados emitidos, la lista puede crecer a varios MB, y el cliente la baja entera aunque solo le interese un serial. Eso es ancho de banda y latencia para una respuesta que casi siempre es “no, no está revocado”.
Por eso la CRL se regenera de forma programada (a diario o semanal según el campo nextUpdate), nunca a mano cada vez que revocás algo. Si servís estas listas, conviene hacerlo desde infraestructura con buen ancho de banda; si alojás tu propia PKI, un servidor en donweb.com con la CRL detrás de cache HTTP resuelve bien el reparto.
OCSP: verificación de estado en tiempo real
OCSP (Online Certificate Status Protocol) le da la vuelta al problema. En vez de bajar la lista completa, el cliente le pregunta a un responder por un solo certificado: “¿el serial X está bien?”. La respuesta es chica y puntual: good, revoked o unknown.
El responder OCSP se publica en la extensión AIA (Authority Information Access) del certificado. Igual que con CDP, si la extensión no está, el cliente no sabe a quién preguntarle.
Ahora bien, OCSP tiene dos costos. Uno es la latencia: cada handshake TLS suma una consulta de red extra. El otro es de privacidad, porque el responder se entera de qué sitios está visitando el usuario. Más contexto en riesgos de seguridad conocidos.
La solución a ambos es OCSP stapling. Acá el servidor web hace la consulta al responder cada tanto, guarda la respuesta firmada y la “engrapa” (staple) dentro del propio handshake TLS. El cliente recibe la prueba de validez sin contactar a nadie. Menos latencia, mejor privacidad, y el responder deja de ser un cuello de botella en cada visita.
CDP y AIA: cómo decirle al navegador dónde buscar
Estas dos extensiones son lo que conecta el certificado con los mecanismos de revocación. Van definidas en el archivo de configuración de OpenSSL, en la sección de extensiones que aplicás al emitir el certificado del servidor.
- crlDistributionPoints: indica la URL de la CRL. Ejemplo:
crlDistributionPoints = URI:http://pki.tusitio.com/crl/server.crl - authorityInfoAccess: indica el responder OCSP (y opcionalmente la URL del certificado de la CA emisora). Ejemplo:
authorityInfoAccess = OCSP;URI:http://ocsp.tusitio.com
Un detalle de la guía original que conviene tener en cuenta: OpenSSL cambia opciones entre ramas. Lo marcado como “OpenSSL 4.0 / master” (por ejemplo cierta sintaxis de authorityKeyIdentifier) todavía no está en la línea estable 3.x. Si corrés OpenSSL 3.0 a 3.6, verificá las opciones dudosas con la documentación de tu versión antes de copiar y pegar. Los códigos de error numéricos por encima de 40 también se movieron entre ramas.
Cómo revocar un certificado con OpenSSL
La revocación se apoya en la base de datos de la CA: el archivo index.txt (estado de cada certificado) y serial (próximo número de serie). Sin esa base, OpenSSL no sabe qué revocar.
El comando central es directo:
openssl ca -config ca.cnf -revoke certs/server.crt.pem \
-crl_reason keyCompromiseEso marca el certificado como revocado en index.txt con una R. El parámetro -crl_reason es opcional pero recomendado. Los motivos válidos según el estándar incluyen:
- keyCompromise: se filtró o sospechás de la clave privada. El caso más grave.
- cessationOfOperation: el sitio o servicio dejó de operar.
- certificateHold: suspensión temporal; es el único motivo reversible.
- superseded: se emitió un certificado nuevo que reemplaza a este.
- affiliationChanged: cambiaron datos de la organización dueña.
Para confirmar que quedó marcado, inspeccioná el certificado o revisá la línea correspondiente en index.txt. La R al inicio te dice que está revocado y la fecha de revocación queda registrada. Ya lo cubrimos antes en pipelines de despliegue con seguridad.
Generar e inspeccionar una CRL
Revocar marca la base de datos, pero el cliente no ve nada hasta que regenerás la lista. Ese paso lo hace:
openssl ca -config ca.cnf -gencrl -out crl/server.crl.pemPara leer lo que generaste en formato humano:
openssl crl -in crl/server.crl.pem -text -nooutAhí ves el emisor, el número de la CRL, la fecha de emisión (Last Update), la próxima actualización (Next Update) y la lista de seriales revocados con su fecha y motivo. Si tu serial revocado aparece en esa lista, el mecanismo funciona.
El campo Next Update importa más de lo que parece. Si vence y no regeneraste la CRL, los clientes estrictos la tratan como inválida y pueden rechazar conexiones. Programá la regeneración para que siempre haya una CRL fresca, aunque no hayas revocado nada nuevo.
Configurar CRL y OCSP en nginx y Apache
Acá viene lo que más se usa en el día a día. La configuración mínima difiere entre los dos servidores.
¿Cómo habilitar OCSP stapling en nginx?
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/ca-chain.pem;
resolver 1.1.1.1 valid=300s;El ssl_trusted_certificate tiene que apuntar a la cadena que incluye la CA emisora, porque nginx la necesita para verificar la respuesta del responder. Con ssl_stapling_verify on, nginx valida la firma de esa respuesta antes de engraparla. Si querés evitar que nginx haga la consulta en vivo, podés precargar la respuesta con ssl_stapling_file.
¿Cómo configurar OCSP stapling en Apache?
SSLUseStapling on
SSLStaplingCache "shmcb:/var/run/ocsp(128000)"
SSLCACertificateFile /etc/ssl/ca-chain.pemEn Apache, SSLStaplingCache es obligatorio para que el stapling funcione: ahí guarda las respuestas OCSP entre handshakes. Si vas a usar autenticación de cliente con verificación de revocación, sumás SSLVerifyClient require y apuntás la cadena con SSLCACertificateFile. En herramientas de integración continua profundizamos sobre esto.
Para chequear que el stapling está activo, desde tu máquina:
openssl s_client -connect tusitio.com:443 -status < /dev/null \
2>&1 | grep -A 17 "OCSP response"Si ves OCSP Response Status: successful, el servidor está engrapando bien. OCSP stapling es opcional, pero te lo recomiendo por performance: le sacás al cliente una consulta de red en cada conexión.
CRL vs OCSP: tabla comparativa
| Aspecto | CRL | OCSP (con stapling) |
|---|---|---|
| Qué consulta | Lista completa de seriales revocados | Estado de un certificado individual |
| Tamaño de la respuesta | Varios MB en CAs grandes | Unos pocos KB |
| Extensión que la publica | CDP (crlDistributionPoints) | AIA (authorityInfoAccess) |
| Actualidad | Según Next Update (horas o días) | Más fresca, configurable |
| Latencia para el cliente | Descarga periódica cacheada | Cero extra si hay stapling |
| Privacidad | Buena (no revela qué visita) | El responder ve la consulta (salvo stapling) |
| Comando OpenSSL | openssl ca -gencrl | openssl ocsp |

Errores comunes y troubleshooting
Estos son los tropiezos que vemos seguido cuando alguien arma su propia PKI.
- Revocar y no regenerar la CRL: marcás el certificado con
-revokepero te olvidás del-gencrl. La revocación queda enindex.txty el mundo sigue confiando en el certificado. Siempre regenerá la lista después de revocar. - Emitir certificados sin CDP ni AIA: si las extensiones no están en el certificado, ningún cliente sabe dónde verificar. Confirmá con
openssl x509 -in cert.pem -noout -textque aparecen “X509v3 CRL Distribution Points” y “Authority Information Access”. - Dejar que venza el Next Update: una CRL vencida es tratada como inválida por clientes estrictos. Programá la regeneración antes de que llegue la fecha, haya o no revocaciones nuevas.
- Stapling sin la cadena correcta: en nginx, si
ssl_trusted_certificateno incluye la CA emisora,ssl_stapling_verify onfalla y nginx no engrapa nada (sin avisar fuerte). Verificá conopenssl s_client -status.
¿Querés probar el responder OCSP por fuera del servidor web? Este comando consulta directo, sin stapling:
openssl ocsp -issuer ca-chain.pem -cert server.crt.pem \
-url http://ocsp.tusitio.com -resp_textPreguntas Frecuentes
¿Cómo revocar un certificado SSL en nginx o Apache?
La revocación no se hace en el servidor web sino en la CA que emitió el certificado, con openssl ca -revoke cert.pem seguido de openssl ca -gencrl para actualizar la lista. nginx y Apache solo sirven o consultan esa información (vía CRL u OCSP stapling), pero no revocan nada por sí mismos.
¿Qué diferencia hay entre un certificado revocado y uno expirado?
Un certificado expirado se detecta de forma local comparando la fecha de vencimiento con el reloj del sistema, sin red. Uno revocado tiene fecha válida, así que el cliente debe consultar un servidor externo (CRL u OCSP) para enterarse de que la CA lo invalidó antes de tiempo.
¿Cómo configurar OCSP en mi servidor web?
En nginx se activa con ssl_stapling on, ssl_stapling_verify on y ssl_trusted_certificate apuntando a la cadena de la CA. En Apache se usa SSLUseStapling on junto con SSLStaplingCache, que es obligatorio. El certificado además debe traer la extensión AIA con la URL del responder OCSP.
¿Qué es una CRL y cómo verificar si un certificado está revocado?
Una CRL es una lista firmada por la CA con los números de serie de los certificados revocados. Para verificar un certificado, descargás la CRL desde la URL del campo CDP y la inspeccionás con openssl crl -in archivo.crl -text -noout: si el serial aparece en la lista, está revocado.
¿Cómo generar una lista de revocación con OpenSSL?
Con openssl ca -config ca.cnf -gencrl -out archivo.crl, usando la base de datos de la CA (index.txt y serial). El comando genera una CRL fresca con todos los certificados marcados como revocados hasta ese momento, firmada con la clave de la CA emisora.
Conclusión
Montar una CA y emitir certificados es la parte fácil. Lo que separa una PKI seria de una de juguete es la revocación: tener CDP y AIA en cada certificado, regenerar la CRL antes de que venza el Next Update, y dejar OCSP stapling activo para no castigar la latencia de tus visitantes.
Si manejás certificados propios, hacé un checklist mínimo: revocar siempre va con regenerar la CRL, las extensiones se verifican con openssl x509 -text, y el stapling se confirma con openssl s_client -status. Y ojo con las diferencias entre OpenSSL 3.x y la rama 4.0/master antes de copiar configuración de cualquier guía, incluida esta.






