En corto

System → Certificates → Certificate Revocation → lápiz sobre la CRL que usa el servidor OpenVPN → Lifetime (Days) = 730 → Save. Guardar regenera la CRL con fechas válidas. Después, Status → Services → OpenVPN → Restart. Los clientes vuelven a entrar sin cambiar nada de su lado.

Si la GUI no te deja poner una vida sensata (versiones anteriores a 2.7 / 23.01), primero System → Patches (paquete System Patches) → aplica Fix for CRL expiration lifetime default and maximum values (a3c1589086ea67d25a28ec14ab95d7fd9ab25fa2), y luego el paso anterior. O actualiza pfSense: las versiones actuales ya lo llevan.

El error

En el log del servidor (Status → System Logs → OpenVPN) y en el cliente:

1
2
3
4
VERIFY ERROR: depth=0, error=CRL has expired: CN=client1, serial=3
OpenSSL: error:0A000086:SSL routines::certificate verify failed
TLS_ERROR: BIO read tls_read_plaintext error
TLS Error: TLS handshake failed

La pista es que fallan todos los clientes a la vez. Un certificado caducado tumba a un cliente; una CRL caducada tumba al servidor entero, porque la revisa en cada handshake.

Por qué pasa

Dos caminos llevan aquí:

  1. La CRL caducó de verdad. Cada CRL tiene un nextUpdate; pasada esa fecha OpenSSL la trata como inválida y OpenVPN rechaza a todos. Una CRL creada hace años con vida corta y nunca tocada acaba así.
  2. La CRL nació caducada. pfSense generaba CRLs con 9999 días por defecto, lo que las llevaba más allá de 2050. X.509 codifica las fechas hasta 2049 como UTCTime con año de dos cifras, y pfSense escribía 50 donde tocaba GeneralizedTime: OpenSSL lo lee como 1950 y la CRL “expiró” hace 75 años. Es el bug #13424 de Redmine, y explica por qué instalaciones sanas empezaron a fallar en 2022–2023 sin que nadie tocara nada: las CRLs regeneradas por cualquier cambio cruzaron el 2050.

El arreglo de Netgate bajó la vida por defecto a 730 días, limitó el máximo (2050 en 64 bits, 2038 en 32 bits) y va incluido en las versiones actuales; para las viejas quedó como parche del paquete System Patches.

Comprobarlo

pfSense escribe la CRL de cada servidor OpenVPN en su directorio de configuración:

1
2
ls /var/etc/openvpn/server1/
openssl crl -in /var/etc/openvpn/server1/crl-verify -noout -lastupdate -nextupdate

Un nextUpdate en el pasado, o un año 1950, es el diagnóstico completo.

Arreglo

  1. Identifica qué CRL usa el servidor: VPN → OpenVPN → Servers → editar → Peer Certificate Revocation list.
  2. Regenérala: System → Certificates → Certificate Revocation → lápiz sobre esa CRL → Lifetime (Days) 730 → Save. Cualquier guardado la reescribe con lastUpdate = ahora.
  3. Reinicia OpenVPN: Status → Services. OpenVPN relee crl-verify al detectar el cambio, pero el reinicio evita esperar a que lo note.
  4. Vuelve a comprobar con el openssl crl de arriba.

En una versión sin el fix, entre el paso 1 y el 2: System → Package Manager → instalar System_Patches → System → Patches → el parche aparece en la lista de recomendados → Apply. Sin él, la GUI vuelve a escribir 9999 y el problema se repite en cuanto guardes.

Trampas

  • No borres la CRL para “arreglarlo”: sin CRL, los certificados que revocaste vuelven a ser válidos. Edítala.
  • Una CRL por CA: si tienes varios servidores OpenVPN con CAs distintas, revisa cada una.
  • Las CRLs importadas (de una CA externa) no se pueden regenerar desde pfSense; pide una nueva a tu CA y vuelve a importarla.
  • 730 días también se acaban. Cualquier revocación, edición de la CRL o cambio en el servidor OpenVPN la regenera; si no tocas nada en dos años, vuelves aquí. Un aviso en el calendario cuesta poco.
  • Pasado 2038 en hardware de 32 bits aplica el otro límite; en la práctica, ninguno de esos equipos debería seguir siendo tu firewall.

Referencias: Certificate Revocation List Management en la documentación de Netgate y el análisis de Pasquale Fiorillo.