Adding a second authentication backend to a VPN gateway feels like adding a second factor. It usually adds a second check, which is a different object with different failure modes. Whether both must succeed, what each one proves, and what happens when one is unavailable are three separate decisions. Get them wrong and the gateway ends up stricter in the demonstration and weaker during an outage.

What a Second Backend Actually Proves

A local account lookup proves that a name exists in a database and that a password matched it. A RADIUS exchange proves that a RADIUS server returned Access-Accept for the attributes it received. Neither statement mentions a factor type, because both verify knowledge. The NIST digital identity guidance counts distinct factor types and their authenticators, not servers or prompts.

There is a legitimate design where both systems participate. A central service can authenticate the person while the gateway independently checks whether that account is entitled to this tunnel. That is authorization riding beside authentication, and calling it two-factor confuses a policy check with proof of possession.

RADIUS can carry a real second factor when it fronts something that verifies one, such as a push approval or a hardware token. The envelope does not tell you which authenticators the user demonstrated, so read the backend policy rather than the gateway label.

AND, OR and Fallback Are Different Products

Before comparing implementations, decide what both means in your requirement. An AND policy requires every named check to pass, an OR policy accepts whichever one succeeds, and a fallback tries the second only under stated failure conditions. Those three behave in opposite ways during an outage, and only one of them is usually what the review intended.

Adding two backend entries to a configuration screen does not reveal which policy the product implements. Some gateways chain plugins in order and stop at the first reject, which is AND only when every plugin is required. Others treat a local account as an override, which turns a central outage into a bypass. The reliable answer is a documented negative test for each path, run against the build you deploy.

Fallback deserves the most suspicion, because it exists to keep working when something is broken. A fallback that accepts a local password whenever RADIUS is unreachable has converted a central policy into a second, weaker door.

OpenVPN's Double Check Is a Concrete Case

Community OpenVPN 2.6 requires both a client certificate and the configured auth-user-pass-verify script when both are enabled. That is a documented AND between certificate verification and a credential script, and it is genuinely two checks. It is still not automatically two factor types, since the script may only validate a password.

The combination also leaves the association question open. A certificate commonly identifies a device while the credentials identify a person, and nothing in the default flow requires both to refer to the same principal. Decide which pairs are allowed, then enforce that map inside the verify script or in a later authorization step.

Certificate-only mode is a single check, backed by a key that may or may not be protected by a PIN. A PIN turns the same credential into knowledge plus possession only if the key cannot be used without it. Leaving that key unencrypted on disk reduces the second part to a file permission.

Appliance vendors build their own plumbing, often a PAM module or a RADIUS plugin behind a web console. Community behaviour is a reference for what double checks look like, not a description of how an appliance combines them.

Check the Combination on Your Gateway

Read the configuration before trusting the console summary. The lines that decide the policy are the certificate mode, the credential script and the plugin order.

grep -E 'verify-client-cert|auth-user-pass-verify|plugin' /etc/openvpn/server.conf
openssl x509 -in /etc/openvpn/pki/issued/client01.crt -noout -subject -serial
radtest alice 'wrong-password' 127.0.0.1 0 testing123

The grep shows whether a certificate is required and which script runs after it, and the order matters more than the names suggest. The certificate dump gives the identity the gateway will see, including the CN and serial you need for the association map. The RADIUS test is the negative case: a wrong password must produce Access-Reject, and a correct one Access-Accept. If a rejected credential still yields a session, the script is not on the authentication path at all.

Then run the outage case on a lab instance: stop the required backend and connect with valid credentials. The expected result is a refusal, and anything else is the fallback policy nobody documented.

Write the Requirement as Negative Cases

A usable requirement names the proofs, the accounts allowed to present them, and the result when a verifier is missing. It also states the permitted pairing between device identity and person identity. That is more precise than the product names on the purchase order, and it can be tested.

Acceptance should include four refusals: an ineligible local account, a missing required proof, an invalid second factor, and an unreachable required backend. Each refusal needs a log line that distinguishes it from the others, or the next incident opens with guesswork. Record which component made each decision, since the gateway, the RADIUS server and the directory will each blame the other two.

Re-run the four refusals after any plugin or firmware change. They are cheap, and the policy they protect is the part an attacker probes first.

Makomi ya ndenge moko