Sooner or later a VPN user offers to email a private key so the administrator can make a certificate, and that offer is the thing to refuse. The workable flow keeps the key on the client from the first command: the client generates it, sends a certificate signing request, the issuer verifies and authorizes it, and the signed certificate comes back to sit beside the key that created it. The checklist below fails closed at each step, which is the point, because two of the five steps are the ones people skip when they are in a hurry.

Step 1: generate the key where it will live

Generate on the machine that will hold the key, and keep it there. A software key goes into a file with restrictive permissions; a hardware-backed or managed-store key never becomes a file at all, and its enrollment path is usually a separate tool rather than an OpenSSL command. Either way, nobody needs to see the private half.

A software flow looks like this, with the key and the request created in one session:

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"

The umask line matters more than it looks. Without it the key is written world-readable on a default-permissive system, and copying the file around later spreads that. Reusing an existing key is legitimate when it is already protected and matches your policy; generating a fresh one per device is easier to reason about.

Step 2: put the identity in the request, not in the email

Decide what the VPN actually authenticates before the request is created, because that answer belongs inside the CSR. OpenVPN traditionally keys client identity off the certificate common name, and tools such as strongSwan match an identity string against the subject or a subject alternative name. An email that says my name is alice is not evidence, and a request whose subject says the same thing is only slightly better.

Add a subject alternative name when your verifier checks one, since modern matching often ignores the legacy CN:

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

Keep the CN short, stable and tied to the account rather than to a laptop model. A name containing the user device serial number is a support problem waiting for the first hardware replacement.

Step 3: verify the request before you sign it

The issuer verifies two different things, and conflating them is the classic mistake. First, that the request is internally consistent: the signature verifies against the public key it carries. Second, that the requester is entitled to what the request asks for, which no cryptographic check can answer.

The mechanical part is one command, and it should print a verification result along with the subject:

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

Note what that proves. A request that verifies only shows the sender held the matching private key at submission time; it does not prove the sender is the person named in the subject, and it does not authorize the group or route access being requested. Enrolment review is a separate gate, and a request asking for a group nobody approved should be rejected rather than quietly edited.

Step 4: authorize, then sign with explicit extensions

Signing is where the CA decides policy rather than accepting the request verbatim. Validity, key usage and the role extension belong in an extension file, not in defaults you cannot recall six months later. A client certificate for VPN authentication needs client authentication as its purpose.

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 with the existing serial file if one is already in use, and keep the CA key offline or in whatever protected store your policy names. Certificate serial numbers have to be unique per issuer; recreating the serial file from scratch risks collisions that make revocation ambiguous.

Record what was issued: serial, subject, requested identity, approving person and expiry. That record is what a revocation decision later depends on, and it cannot be rebuilt from the certificate alone if the enrolment trail lives only in a mailbox.

Step 5: install it beside the matching key and prove the pairing

The client receives the certificate and the issuer chain, never a key. Before connecting, confirm that the certificate actually pairs with the key already on disk, because a mismatched pair produces a confusing handshake failure much later:

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

The two digests must match. Then connect and confirm the identity the server logs is the one you authorized, not merely that the tunnel came up. If the key is lost or the device is replaced, the answer is revocation plus a new request from the new device; asking the administrator to send back a key from somewhere else does not recover the original and quietly breaks the model that made the request safe.

ସମ୍ପର୍କିତ ପ୍ରବନ୍ଧ