Skip to content

duplicate-cn ineffective when combined with override-username in SSO/OAuth2 scenarios #1078

Open

Description

@Smiley-k

Problem

When OpenVPN is used with OAuth2/SSO authentication (e.g., via openvpn-auth-oauth2), the duplicate-cn option becomes ineffective. Here's why:

The .ovpn config is shared across all users and contains an inline auth-user-pass block with a placeholder username — this is the recommended approach per OpenVPN documentation for SSO scenarios (see --auth-user-pass in client-options.rst):

<auth-user-pass>
username
no_password
</auth-user-pass>

Since all users share the same placeholder credentials:

  • Every client connects with CN=username (the placeholder)
  • duplicate-cn check runs at connect time — sees CN=username, allows the connection (it's the same CN after all)
  • The plugin then sends client-auth with override-username: true, changing CN to the real user (e.g. alice)
  • But by now duplicate-cn has already done its check and has no effect

Result: the same user can have multiple active OpenVPN sessions simultaneously (from different devices), with no built-in mechanism to prevent it.

Why this matters

  • Orphaned sessions accumulate, consuming server resources
  • No security enforcement of "one session per user"
  • The workaround (duplicate-cn) exists in OpenVPN but is broken in SSO flows by design, since the real identity is only known after authentication completes

Suggested options for OpenVPN core

  1. Deferred duplicate check — run duplicate-cn check after client-auth / override-username has set the final CN, not at connect time
  2. client-kill on duplicate CN — when a new connection completes with a real CN that already has an active session, automatically client-kill the old one
  3. duplicate-cn re-evaluation — when CN changes via management interface (client-auth with override), re-evaluate the duplicate-cn constraint

Related

  • openvpn-auth-oauth2 issue #992 — same problem from auth-plugin perspective
  • PR #993 — proposed kill-duplicate-username feature
  • OpenVPN docs --auth-user-pass: the username-only flag and inline dummy password approach are both documented as valid SSO patterns

Activity

  1. schwabe commented on Jul 19, 2026

    @schwabe
    Contributor

    I am confused here --duplicate-cn allows duplicate common names and does not prevent them and you are here complaining that duplicate usernames are allowed.

  2. Smiley-k commented on Jul 19, 2026

    @Smiley-k
    Author

    Let me clarify the actual flow:

    1. Every client uses the same shared .ovpn config with this block hardcoded (it's the recommended SSO pattern per OpenVPN docs):
    username no_password

    This is the root cause — every client literally sends CN=username on connect. The real identity (e.g. alice, bob) simply doesn't exist yet at the TLS/auth level.

    1. Without --duplicate-cn (default): only one user in total can ever connect. Alice connects first → OK. Bob tries → rejected because CN=username is already taken — even though they are different people.

    2. With --duplicate-cn: everyone allowed, unlimited connections per user, no enforcement possible.

    The real identity only arrives later via client-auth / override-username through the management interface — after OpenVPN already checked the CN for duplicates. By then, there's no mechanism to go back and enforce any per-user session limit.

    So the core ask is: a way to defer or re-evaluate the duplicate-CN check after override-username applies the real identity from the management interface.

  3. schwabe commented on Jul 19, 2026

    @schwabe
    Contributor

    it's the recommended SSO pattern per OpenVPN docs

    Could you point me where we are recommending that? I don't think we recommend doing that.

    Without --duplicate-cn (default): only one user in total can ever connect. Alice connects first → OK. Bob tries → rejected because CN=username is already taken — even though they are different people.

    so --duplicate-cn is working as expected.

    With --duplicate-cn: everyone allowed, unlimited connections per user, no enforcement possible.

    As expected.

    So the core ask is: a way to defer or re-evaluate the duplicate-CN check after override-username applies the real identity from the management interface.

    if you have such an advanced auth flow that you have management interface and manage all the user by this way, why not manage duplicate there as well.

    You basically want all the user authentication outside OpenVPN anyway by not giving OpenVPN anythhing to authenticate and even using duplicate username and then still expect that OpenVPN behaves like you need for your setup. To me this is a corner case that probably not many people will run into. So deferred duplicate CN check might be something we might implement at some point, there are currently things with higher priority that need to be fixed first.

  4. Smiley-k commented on Jul 19, 2026

    @Smiley-k
    Author

    Thanks for the response! Let me explain our actual setup and maybe you can tell me if we're doing something wrong.

    Our stack: OpenVPN server + openvpn-auth-oauth2 plugin + Keycloak (OAuth2). The plugin acts as both --auth-user-pass-verify hook and management interface client.

    How it works: Client connects → plugin intercepts → opens browser for OAuth2 login → after success, plugin sends client-auth override-username with the real identity.

    Why the embedded : Auth happens in the browser, not at the OpenVPN prompt. So we embed a placeholder to trigger the plugin without any interactive prompt. The docs mention this exact fallback under --auth-user-pass for when username-only can't be used.

    The core problem: After override-username replaces the placeholder CN with the real identity, the duplicate-CN check already ran and can't be re-evaluated. OpenVPN's native session control is bypassed in this flow.

    You mentioned managing duplicates in the plugin — fair point, PR #993 does that. I just wanted to highlight the gap in case it's worth addressing in OpenVPN core (e.g., re-evaluate constraints when override-username changes the identity).

    But maybe there's a simpler setup we're missing? Genuinely asking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions