Pausing one client's access and removing it for good look like the same task until you try to undo one of them. Revoking a certificate writes a record the server treats as final, and reversing it means editing the issuer's database by hand. Dropping the live tunnel is a management command that changes nothing about trust. Choose the lever by asking whether the key is still trustworthy, not by asking how urgent the request feels.

The belief: revoked and suspended are the same thing

A contractor is paused for a week and the reflex is to revoke, because revocation sounds like switching something off. It looks tidy, it takes ten seconds, and it leaves a database edit as the only way back. The reflex is understandable and it is closer to burning a passport than to closing a door. A paused device and a compromised key need different treatment, and only one of them is cheap to reverse.

The distinction is about the credential rather than about the person. A key that is still in the right hands can be paused and resumed without any loss of trust. A key that may have been copied should never be restored, because restoration asserts that the copy does not exist.

Write the answer down before touching either system. If you cannot say whether the key is exposed, the conservative answer is replacement.

Drop the live session with the management interface

OpenVPN exposes a management interface that can list sessions and kill one of them by common name. Enable it on localhost, keep it away from the public interface, and send the kill command when a session has to disappear now. The command closes that tunnel only, and every other client keeps working.

This is a response to an active problem, not a suspension policy. The same profile can reconnect in a minute, because nothing about its credential changed. Use it when the session must go and the lasting decision is still being made.

Confirm the session was attached before you kill it, so you are not hunting a client that never connected. The status command below prints what is currently attached.

printf 'status 2\nquit\n' | nc 127.0.0.1 7506
printf 'kill kiosk-14\nquit\n' | nc 127.0.0.1 7506

If the kill reports no such client, the common name in the certificate is not the string you typed. Read the status output rather than the profile file name.

What the CRL actually controls

The server does not consult a revocation flag stored on the certificate. It reads the certificate revocation list named by crl-verify, on each new connection, and rejects a certificate whose serial appears in that list. Two consequences follow, and both matter operationally. The file must be readable by the account the server drops privileges to, and an already connected client keeps running until it reconnects.

That second consequence surprises people during incidents. Revoking a certificate does not close the tunnel that is currently using it. Pair the revocation with a management kill if the session has to end immediately, and treat the two actions as separate steps in the runbook.

Inspect the list to see what the server will actually enforce, rather than trusting the timestamp of the last file you copied. The serial count is the part that matters.

openssl crl -in /etc/openvpn/server/crl.pem -noout -text | sed -n '1,14p'
ls -l /etc/openvpn/server/crl.pem

A list with no entries and a list with the right entries look identical in a directory listing, which is why the serial count is worth printing. The permissions line matters just as much, because a file the daemon cannot read produces a failure that looks like a rejected client.

Restoring a record, carefully

Restoring a certificate means reversing a record in the issuance database and publishing a new list. easy-rsa 3 keeps that database as index.txt under the PKI directory, while older layouts used a different arrangement. A row starts with a status letter and an expiry date. A revoked row inserts a timestamp for the revocation before continuing with the serial number, the certificate file name and the distinguished name. Putting a row back means deleting that timestamp and flipping the letter, while leaving everything else alone.

Back up the file first, and script the edit rather than typing into a text editor. A typo that changes how many fields a row carries breaks issuance for every certificate added afterwards. That is the reason to automate the change and copy the file before touching it.

A second revocation of the same name often fails as well, because the first run relocated that certificate and its key out of the directories the tool expects to find them in. The tool then cannot find what it was asked to revoke, and the error message is not always clear about why.

cp /etc/easy-rsa/pki/index.txt /root/index.txt.$(date +%F-%H%M)
grep -c '^R' /etc/easy-rsa/pki/index.txt
easyrsa gen-crl

Publish the new list, fix its ownership, and make the server read it. A reload is enough on most installations, but the confirmation has to come from a fresh connection, since the existing session never re-checked anything.

Check which lever the case deserves

Ask the one question that decides the whole runbook: is the private key still only where it should be. If it is, the session kill plus a documented pause covers the case and leaves no permanent record behind. If it is not, the only safe answer is a new key with the old certificate left revoked.

Then verify the outcome with a connection attempt rather than with a configuration diff. The diff tells you what you intended, and the connection tells you what the server enforces.

openssl crl -in /etc/openvpn/server/crl.pem -noout -text | grep -c 'Serial Number'
printf 'status 2\nquit\n' | nc 127.0.0.1 7506

When a restored client connects and appears in the status output, the record edit worked. When a revoked client is refused and the log names the CRL, the revocation worked. Anything in between is a permissions or reload problem, and it is worth fixing before the next request arrives.

ບົດຄວາມທີ່ກ່ຽວຂ້ອງ