Tarde o temprano, un usuario de VPN ofrece enviar por correo una clave privada para que el administrador pueda hacer un certificado, y esa oferta es justo la que hay que rechazar. El flujo que funciona mantiene la clave en el cliente desde el primer comando: el cliente la genera, envía una solicitud de firma de certificado, el emisor la verifica y la autoriza, y el certificado firmado vuelve para quedarse junto a la clave que lo creó. La lista de comprobación siguiente falla cerrada en cada paso, y ese es el punto, porque dos de los cinco pasos son los que la gente se salta cuando tiene prisa.

Paso 1: genere la clave donde va a vivir

Genere en la máquina que va a tener la clave y déjela allí. Una clave de software va a un archivo con permisos restrictivos; una clave respaldada por hardware o en un almacén gestionado nunca se convierte en archivo, y su ruta de inscripción suele ser una herramienta aparte y no un comando de OpenSSL. En cualquier caso, nadie necesita ver la mitad privada.

El flujo de software se ve así, con la clave y la solicitud creadas en una sola sesión:

umask 077
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out client.key
openssl req -new -key client.key -out client.csr -subj "/CN=alice-vpn/O=Example"

La línea umask importa más de lo que parece. Sin ella, la clave se escribe legible para todos en un sistema permisivo por defecto, y copiar el archivo después lo propaga. Reutilizar una clave existente es legítimo cuando ya está protegida y encaja con su política; generar una nueva por dispositivo es más fácil de justificar.

Paso 2: ponga la identidad en la solicitud, no en el correo

Decida qué autentica realmente la VPN antes de crear la solicitud, porque esa respuesta pertenece dentro de la CSR. OpenVPN tradicionalmente vincula la identidad del cliente al nombre común del certificado, y herramientas como strongSwan comparan una cadena de identidad con el sujeto o un nombre alternativo del sujeto. Un correo que dice que me llamo alice no es una prueba, y una solicitud cuyo sujeto dice lo mismo es solo un poco mejor.

Añada un nombre alternativo del sujeto cuando su verificador compruebe uno, ya que la coincidencia moderna suele ignorar el CN antiguo:

openssl req -new -key client.key -out client.csr \
  -subj "/CN=alice-vpn/O=Example" \
  -addext "subjectAltName=DNS:alice-vpn"

Mantenga el CN corto, estable y ligado a la cuenta en lugar de a un modelo de portátil. Un nombre que contenga el número de serie del dispositivo del usuario es un problema de soporte esperando el primer reemplazo de hardware.

Paso 3: verifique la solicitud antes de firmarla

El emisor verifica dos cosas distintas, y confundirlas es el error clásico. Primero, que la solicitud sea internamente coherente: la firma se verifica contra la clave pública que lleva. Segundo, que el solicitante tenga derecho a lo que pide la solicitud, y eso ninguna comprobación criptográfica puede responderlo.

La parte mecánica es un solo comando, y debería imprimir un resultado de verificación junto con el sujeto:

openssl req -in client.csr -noout -verify -subject
openssl req -in client.csr -noout -pubkey | openssl pkey -pubin -noout -text

Fíjese en qué demuestra eso. Una solicitud que se verifica solo muestra que el remitente tenía la clave privada correspondiente en el momento del envío; no demuestra que el remitente sea la persona nombrada en el sujeto, ni autoriza el acceso al grupo o la ruta que se solicita. La revisión de inscripción es una puerta aparte, y una solicitud que pide un grupo que nadie aprobó debería rechazarse en lugar de editarse en silencio.

Paso 4: autorice y luego firme con extensiones explícitas

La firma es donde la CA decide la política en lugar de aceptar la solicitud al pie de la letra. La validez, el uso de la clave y la extensión de rol pertenecen a un archivo de extensiones, no a valores por defecto que no recordará seis meses después. Un certificado de cliente para autenticación VPN necesita la autenticación de cliente como propósito.

cat > client.ext <<'EOF'
basicConstraints = CA:FALSE
keyUsage = digitalSignature
extendedKeyUsage = clientAuth
EOF
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -days 365 -extfile client.ext -out client.crt

Use -CAserial con el archivo de serie existente si ya hay uno en uso, y mantenga la clave de la CA fuera de línea o en el almacén protegido que indique su política. Los números de serie de los certificados deben ser únicos por emisor; recrear el archivo de serie desde cero arriesga colisiones que hacen ambigua la revocación.

Registre lo que se emitió: número de serie, sujeto, identidad solicitada, persona que aprobó y caducidad. Ese registro es de lo que depende después una decisión de revocación, y no puede reconstruirse solo a partir del certificado si el rastro de inscripción vive únicamente en un buzón.

Paso 5: instálelo junto a la clave correspondiente y demuestre el emparejamiento

El cliente recibe el certificado y la cadena del emisor, nunca una clave. Antes de conectar, confirme que el certificado se empareja de verdad con la clave que ya está en disco, porque un par que no coincide produce un fallo de handshake confuso mucho más tarde:

openssl x509 -in client.crt -noout -pubkey | openssl pkey -pubin -outform DER | openssl sha256
openssl pkey -in client.key -pubout -outform DER | openssl sha256

Los dos resúmenes deben coincidir. Luego conéctese y confirme que la identidad que registra el servidor es la que usted autorizó, y no solo que el túnel se levantó. Si se pierde la clave o se sustituye el dispositivo, la respuesta es revocación más una solicitud nueva desde el dispositivo nuevo; pedir al administrador que devuelva una clave desde otro sitio no recupera el original y rompe en silencio el modelo que hacía segura la solicitud.

Artículos relacionados