Usernames appear in the new directory, the migration is declared finished, and logins keep failing anyway. The gateway still needs a supported authentication path and a correct authorization result, and neither one follows from a directory that now contains the accounts. A backend move is a cutover with a lifecycle, not a copy job. The symptom below is the one that usually reveals the difference.

The symptom: accounts exist and sessions do not

The new directory holds every username, a test bind succeeds, and the VPN client still returns an authentication failure. That combination means the identity exists but the verification path the gateway uses is not reaching it, or reaching it with a method it cannot satisfy. Both are configuration, and they are different problems.

The first is plumbing: the gateway points at a backend that does not answer, uses a shared secret the other side does not expect, or asks for an attribute the new service does not return. The second is cryptographic: the method requires the original secret, and the new store holds only a hash of it. The error text looks similar in both cases, which is why the two get treated as one problem.

Separating those two before touching accounts saves a week. One is a routing and trust question, the other is a decision about resetting credentials, and mixing them produces changes nobody can attribute.

Map the chain before moving anyone

Write down six things for each client profile: the outer authentication method, any inner method, the server identity the client expects, the interface between gateway and backend, the attribute the gateway maps to group membership, and the resource policy that results. Reading them in order shows which link nobody owns. Each item has an owner, and the cutover fails at whichever one nobody checked.

LinkQuestion it answers
Client profileWhich method and server name does the client use?
Inner methodIs there a second authentication step?
Server identityWhich certificate or name must the client accept?
Gateway to backendWhich protocol, port and shared secret?
Attribute mappingWhich returned value becomes group membership?
Resource policyWhat the resulting session may reach

An ordinary directory login exercises almost none of that chain. It proves the account exists and the password works, which is the part that was never in doubt.

Hashes do not travel between methods

Credential compatibility has to be checked once, before any cohort moves. FreeRADIUS documents the split clearly: a CHAP check that the server performs itself needs the actual password, and MS-CHAP accepts that password or suitable NT material. A hash produced for some other purpose fits neither case, however strong it is.

The distinction is about who computes the proof. A method that verifies by binding to the directory lets the directory check whatever it can check. A method that verifies by recomputing a challenge response needs the secret itself, because the server has to perform the same computation.

Where the material is missing, the honest options are a supported reset, re-enrollment, an external verification service or a change of method. A temporary export of recoverable passwords is not on that list. It creates a plaintext credential store during the most chaotic week of the project, and it usually outlives the migration.

Pilot cohort, then lifecycle changes

Move a small cohort of approved identities with the real client, and test four things: a fresh login, a deliberately wrong credential, the resources the session may reach, and the resources it must not. Check the server identity the client accepted as well, because a certificate name mismatch is invisible until someone reads the client log.

Then exercise the changes the deployment actually depends on. Change a password, renew or re-enroll a certificate, and remove access from one pilot account. After each, confirm which verifier handled the attempt, since a session created before the cutover can keep working and prove nothing about the next login.

Separate profile delivery from the identity switch. Each cohort needs its intended profile, its credential or enrollment state, the authentication service it should use and a support contact, and none of that record should contain a secret.

If old and new paths coexist, bound them with an end date. An automatic fallback can admit an account through an old credential after the new owner has removed access, and that is a security regression disguised as availability.

Rollback cannot restore a credential

Reversing the cutover leaves the directory exactly as it stands now. A reset password stays reset, a revoked certificate stays revoked, and a changed credential format stays changed. Those are events in the directory, and the gateway was never their source. Recovery has to be defined per event, and none of it can depend on reconstructing a secret from an incompatible hash.

Keep an administrative path that does not use the connection being migrated. When the new authentication fails, pause the cohort and use its documented recovery route instead of weakening authentication for everyone to keep a deadline.

After the cohorts are covered, retire the old backend credentials, profiles and trust relationships through their owners. Confirm the old path no longer admits users, and keep the non-secret identity-to-policy mapping that support still needs. A migration is finished when the new lifecycle works and nobody can enter through the old path any more, not when the account list looks complete.

Mikanda mikatakata