Skip to main content
XAuth is an IKEv1-only feature. For IKEv2 connections, use EAP authentication instead — it is the standardized equivalent and offers stronger security guarantees.
XAuth (Extended Authentication, also called Mode Config Authentication) extends IKEv1/ISAKMP with an additional username/password exchange after the initial IKE Phase 1 negotiation completes. It is widely supported by legacy clients including Cisco VPN Client, Apple’s built-in IPsec client, and many mobile devices.

How XAuth Works

  1. Phase 1 completes using either PSK or public key authentication (Main Mode or Aggressive Mode).
  2. The gateway initiates an XAuth exchange, sending a CFG_REQUEST payload asking for username and password.
  3. The client responds with a CFG_REPLY containing the credentials.
  4. The gateway validates the credentials and sends a CFG_SET acknowledging success or failure.
  5. If successful, IKEv1 Phase 2 (CHILD_SA) negotiation proceeds.

Authentication Modes

Modelocal authremote authDescription
XAuth (PSK + XAuth)pskpsk + XAuth roundPSK Phase 1, then XAuth credentials
Hybrid ModepubkeyxauthGateway uses certificate; client uses only XAuth
XAuth + pubkeypubkeypubkey + XAuth roundBoth peers use certificates, then XAuth

Basic Configuration

# /etc/swanctl/swanctl.conf
connections {
  ikev1-xauth {
    version = 1

    local_addrs  = 203.0.113.1
    remote_addrs = %any

    # Round 1: PSK
    local {
      auth = psk
      id   = vpn.example.org
    }
    remote {
      auth = psk
      id   = %any
    }

    # Round 2: XAuth (server requests credentials from client)
    local2 {
      auth = xauth
    }

    children {
      rw {
        local_ts  = 0.0.0.0/0
        remote_ts = dynamic
      }
    }
  }
}

secrets {
  ike-psk {
    secret = "PhaseOneSecret!"
  }

  eap-alice {
    id     = alice
    secret = "AliceXAuthPw"
  }
  eap-bob {
    id     = bob
    secret = "BobXAuthPw"
  }
}

Key Configuration Options

local / remote auth Values

ValueRoleDescription
xauthlocal (server)Server will request XAuth from client
xauthremote (client)Client will respond to XAuth requests
xauth-genericlocalExplicitly use the xauth-generic backend
xauth-pamlocalUse PAM for credential validation
xauth-eaplocalUse EAP/RADIUS backend for validation

xauth_id

The xauth_id option in the local section of a client connection sets the username sent during the XAuth exchange:
local {
  auth     = psk
  xauth_id = alice
}
This allows the IKEv2 identity (id) and the XAuth username to differ — useful when the IKE identity is an IP address or FQDN but the XAuth credential is a username.

XAuth Secrets

XAuth credentials are stored in the secrets section under eap or xauth prefixes (they are aliases for one another):
secrets {
  # 'xauth' prefix is an alias for 'eap'
  xauth-alice {
    id     = alice
    secret = "AlicePassword123"
  }

  eap-bob {
    id     = bob
    secret = "BobPassword456"
  }
}
The xauth and eap secret prefixes are interchangeable. Secrets defined under either prefix are used for both XAuth and EAP authentication.

XAuth Backends

strongSwan provides multiple backends for validating XAuth credentials:

xauth-generic

Validates credentials against secrets defined in swanctl.conf (or ipsec.secrets). Best for simple, self-contained deployments.

xauth-pam

Delegates credential validation to Linux PAM. Enables integration with OS user accounts, LDAP, or any PAM-compatible backend.

xauth-eap (via eap-radius)

The eap-radius plugin registers an XAuth backend named radius. Use auth = xauth-radius to forward XAuth credentials to a RADIUS server.

Using xauth-generic

This is the default backend when auth = xauth is configured. Credentials are checked against shared secrets in swanctl.conf:
local2 {
  auth = xauth           # uses xauth-generic by default
  # or explicitly:
  # auth = xauth-generic
}
The server requests XAUTH_USER_NAME and XAUTH_USER_PASSWORD attributes from the client. It then looks up the provided username in the credential manager and performs a constant-time comparison of the password.

Using xauth-pam

local2 {
  auth = xauth-pam
}
Configure the PAM service in strongswan.conf:
# /etc/strongswan.conf
charon {
  plugins {
    xauth-pam {
      pam_service = ipsec   # PAM service name (default: ipsec)
    }
  }
}
Create the corresponding PAM service file at /etc/pam.d/ipsec.

Using xauth-radius

Requires the eap-radius plugin to be loaded and configured:
local2 {
  auth = xauth-radius
}
Configure the RADIUS server in strongswan.conf as described in the EAP-RADIUS documentation.

Comparison with EAP (IKEv2)

FeatureXAuth (IKEv1)EAP (IKEv2)
Protocol versionIKEv1 onlyIKEv2 only
StandardizationCisco proprietary extensionRFC 3748, RFC 5996
Method negotiationNone (fixed username/password)Flexible (MD5, MSCHAPv2, TLS, etc.)
Mutual authenticationNo (server not authenticated via XAuth)Yes (with EAP-TLS, EAP-MSCHAPv2)
MSK generationNoYes (with most methods)
Multiple roundsVia IKEv1 Mode Config onlyRFC 4739 Multiple Authentication
Recommended for new deploymentsNoYes
If you are deploying a new VPN infrastructure, use IKEv2 with EAP. XAuth support is primarily provided for compatibility with existing clients and legacy infrastructure.

Build docs developers (and LLMs) love