Plenty of teams have a web login that works and a VPN that refuses every password from the same table. The web application compares a hash it computed itself, while the tunnel asks the client to prove possession of a secret in a way the server must be able to check. Those are different requirements on the stored material. The gap between them is where most of these projects stall.

Read the method, then the schema

Write down the proof the chosen method requires before looking at any schema. A challenge-response method needs material from which the server can compute the expected response, which in practice means the password or a compatible derived form. A method that carries a password inside a protected tunnel needs the password itself at the verifier. Read the method documentation for the verifier requirement rather than for the client configuration, because the client requirements are usually the easy part.

A salted hash produced by a modern web framework supplies neither. It verifies one specific comparison and cannot be turned back into the secret it came from.

Challenge-response cannot use a salted hash

MSCHAPv2 is a challenge-response exchange, so the server never receives the password and cannot compare a stored string. It has to derive the expected response from material it already holds, which is why the compatible stored forms are so narrow. A bcrypt or Argon2 value with a per-user salt is one-way in a way that rules the exchange out entirely. The table below starts from the storage form rather than from the method name, because the storage form is what decides the answer.

What the store holdsWhat that material can verifyWhat has to change
A bcrypt or Argon2 value with a per-user saltnothing challenge-response can use, and not the password eitherre-enrol the users, or place a verifying service in front
An unsalted NT-hashMSCHAPv2, and inner PAP through a TLS tunnelnothing, as long as that store is the verifier
A client certificate with a revocation listEAP-TLS onlymove enrolment and revocation to the PKI owner

The SQL plugin documentation for strongSwan defines a schema of its own for configuration and credentials, and the project still marks that plugin experimental. Nothing in it adapts to an application's users table or guesses which hashing scheme produced a stored value. The realistic options are therefore migration to a store the gateway can use, or an authentication service in front of the existing store that can perform the exchange. Anything else is a connector with a hidden assumption inside it.

RADIUS moves the work, not the requirement

Delegating EAP to a RADIUS server changes where verification happens and usually improves the audit trail. It does not recover a password from a one-way hash, so the authentication service still needs material compatible with the method it terminates. Teams find this out after building the RADIUS path and meeting the same wall at the other end.

Where the RADIUS server can read a directory holding a compatible credential, the design works and the VPN gateway stays simple. Where it cannot, the honest answer is an enrolment change rather than another connector. Provisioning and revocation belong to whoever owns the identity, so a copied table without a supported synchronisation process is a second credential lifecycle rather than single sign-on. It drifts the first time someone resets a password in only one place, and the drift is silent until an account that exists in both systems behaves differently in each.

Scope the account that reads the directory to that read, and keep it separate from the account the gateway uses for its own configuration. A shared administrative account turns a read-only design into a much wider blast radius.

Where the account should live

Two architectures remain once the material question is settled. The gateway can own a small credential store that only it reads, or it can delegate to an authentication service that fronts the corporate directory.

The first is easier to reason about and worse for the user, who ends up with a second password to maintain. The second keeps one identity and adds a dependency on a service that now has to be up before anyone can connect. Neither is wrong, but the choice should be recorded next to the gateway configuration, because the next engineer will otherwise assume the other one was chosen. Whatever you pick, the two commands below are the ones that show the current state before you change it.

mysql -N -e "SELECT id, username FROM vpn_users WHERE active = 1 LIMIT 5" vpn
swanctl --list-conns

Account authentication also does not settle authorization. Group membership, device state and network permission still need an explicit mapping once the user has proved the required identity. A connection that authenticates perfectly and authorizes nothing is a policy result, not a bug in the method.

Artitgels cun il medem tema