Skip to main content
RunBook Academy

OPNsenseXXIII · VPN TroubleshootingAuthentication and certificates

VPN authentication and certificate failures — diagnosing AUTHENTICATION_FAILED, expiry, and chain errors

Advanced⏱ ~14 min🧪 Lab requiredswanctlopensslwgdmesg

What you'll learn

  • Diagnose IPsec AUTHENTICATION_FAILED errors and recover from PSK mismatches
  • Verify X.509 certificate chains and identify common validation failures
  • Manage certificate expiry and rotation on OPNsense IPsec tunnels
  • Diagnose WireGuard public-key handshakes that fail to complete
  • Recognise identifier mismatches and certificate attribute failures

Prerequisites

Verified against OPNsense 25.x · FreeBSD 14.x · PF (FreeBSD packet filter) FreeBSD 14.x · Unbound 1.20+ · Kea DHCP OPNsense 25.x plugin · WireGuard in-kernel + OPNsense plugin · strongSwan (IPsec plugin) OPNsense 25.x plugin · OpenVPN 2.6.x · Suricata 7.x · 2026-08-15

Not yet marked complete on this device.

A negotiated tunnel that fails authentication is a half-working tunnel. Phase 1 SA established, the operator sees ESTABLISHED briefly, and then the SA closes with an AUTHENTICATION_FAILED or a chain-validation error. The cause sits in the credential the peers are exchanging — a PSK that’s drifted between the two sides, an expired certificate, a CA chain that one side does not trust. This lesson covers the recurring authentication failures, the log patterns and commands that diagnose each, and the operational patterns that prevent the failure from recurring.

The authentication failure landscape

Three families of failure, each with its own diagnostic:

FamilySymptomLog pattern
PSK mismatchAUTHENTICATION_FAILED after IKE_AUTHcharon: authentication of <peer> with pre-shared key failed
Certificate expiryIKE_AUTH fails; works again once renewedcharon: certificate has expired (NotAfter: ...)
Chain validationOne side rejects the certificate as untrustedcharon: no trusted certificate found or unable to get local issuer certificate
Identifier mismatchCertificate or PSK authenticated, but ID does not match expectedcharon: ID of <cert> does not match expected ID
WireGuard public-key mismatchHandshake does not progress; wg show shows peer listed but no handshakeThe peer’s UDP 51820 packets arrive but the handshake fails

Each family produces a specific error pattern, and each has a specific fix.

Diagnosing AUTHENTICATION_FAILED on PSK

The signature log pattern for a PSK mismatch:

charon:  16[IKE] peer supports 1 PSK authentication method
charon:  16[IKE] found 1 matching PSK config
charon:  16[IKE] authentication of '203.0.113.1' with pre-shared key failed
charon:  16[IKE] IKE_AUTH response contained AUTHENTICATION_FAILED

The strongSwan daemon found a PSK config entry, attempted authentication, and failed. The two possible causes:

  • The local PSK does not match the peer’s PSK. (Most common.)
  • The PSK matches but the hash is computed against a wrong identifier (rare; usually a sanity-check failure on both sides).

The diagnostic:

  1. Verify the local PSK. Under VPN → IPsec → Pre-Shared Keys, find the entry that matches the peer’s identifier. Check the value. Did the operator mistype, copy-paste with trailing whitespace, or store the wrong secret?
  2. Verify the peer’s PSK. Have the peer operator confirm their entry. If the two sides differ, update the wrong side.
  3. Check that the PSK entry is referenced correctly in Phase 1. The Phase 1 entry’s “Pre-Shared Key” dropdown must select the right PSK entry. An entry without an associated PSK — or pointing at a different entry by mistake — is the same as a PSK mismatch.

After alignment, configctl ipsec reload re-reads the configuration; strongSwan re-initiates the negotiation; the tunnel comes up.

Diagnosing certificate expiry

A certificate has a NotAfter field. StrongSwan validates the certificate against the current time during IKEv2 IKE_AUTH. The signature log pattern:

charon:  16[LIB]   NotAfter: '2026-08-15 12:00:00 UTC'
charon:  16[LIB]   NotBefore: '2025-08-15 12:00:00 UTC'
charon:  16[LIB] no cached subject found, parsing certificate
charon:  16[LIB] certificate has expired
charon:  16[IKE] IKE_AUTH response contained AUTHENTICATION_FAILED

The certificate worked last week; it does not work today; the NotAfter field tells you why. The fix is to renew the certificate.

Read-only / Safeopenssl certificate dates
$ openssl x509 -in /var/etc/cert.pem -noout -dates -subject
notBefore=Aug 15 12:00:00 2025 GMT
notAfter=Aug 15 12:00:00 2026 GMT
subject=CN = edson@example.com, O = Example Corp, C = US

Illustrative output

The operational pattern:

  • Track every certificate’s NotAfter. OPNsense lists certificates under System → Trust → Certificates with their expiry dates; export that list to a calendar event for 90, 60, 30, and 7 days before each expiry.
  • Renew 30 days early. Don’t wait until the day before expiry to renew. A renewal that fails (e.g., the CA is unreachable) needs time to resolve before the tunnel goes down.
  • Install the new certificate and update Phase 1. The new certificate is imported under System → Trust → Certificates; the Phase 1 entry’s authentication-field certificate reference is updated; configctl ipsec reload; the tunnel comes up using the new certificate.

Diagnosing certificate chain failures

The chain validation pattern:

charon:  16[LIB]   Subject:  'CN = gateway@partner.example'
charon:  16[LIB]   Issuer:   'CN = Partner Internal CA, O = Partner'
charon:  16[LIB] unable to get local issuer certificate
charon:  16[IKE] no trusted certificate found
charon:  16[IKE] IKE_AUTH response contained CERTIFICATE_PAYLOAD_REQUIRED

The certificate itself is fine — it has not expired, the issuer DN is correct — but the local side does not trust the issuer. The local side’s CA store under System → Trust → Authorities does not include the partner’s CA.

The fix is to import the partner’s CA certificate:

  1. Obtain the partner’s CA certificate (typically distributed as a PEM file by the partner’s PKI team).
  2. Import under System → Trust → Authorities → Add. Choose “Import an existing Certificate Authority”, paste the PEM, save.
  3. The Phase 1 entry under VPN → IPsec → Tunnel Configuration → Phase 1 of tunnel X has an “Authority” dropdown that selects which CA is the source of trust. Set it to the newly imported partner CA.
  4. configctl ipsec reload.

Diagnosing identifier mismatches on certificate tunnels

A certificate-based tunnel where the certificate is fine, the chain is fine, but the authentication still fails:

charon:  16[IKE] ID of 'gateway@partner.example' (DN) does not match expected ID 'gateway.partner.example' (FQDN)

The peer sent a Distinguished Name (DN); the operator’s Phase 1 entry has “Peer Identifier = FQDN”. Or the peer’s certificate SAN lists an IP address and the operator is comparing against a name.

The fix:

  • Update My Identifier or Peer Identifier on the local side to match the type the peer is sending. For an IP-address-type identifier, choose “IP address”. For a DN, choose “ASN.1 Distinguished Name”. For a hostname, choose “Fully Qualified Domain Name”.
  • Verify the certificate SAN matches the identifier the peer is presenting. openssl x509 -in <cert.pem> -text shows the subjectAltName extension listing all the names and IPs the certificate validates against.

IPsec IKEv1 certificate quirks

IKEv1 with certificates is more brittle than IKEv2. The main failure pattern:

charon:  16[IKE] no private key found for '<cert-id>'

The strongSwan daemon has the certificate but cannot find the matching private key. The two fixes:

  • Re-import both certificate and private key. Under System → Trust → Certificates, ensure the certificate entry has an associated private key (the “Private key” column shows a key count).
  • Verify the certificate was generated for the right key algorithm. RSA certificates need RSA keys; ECDSA certificates need ECDSA keys. A certificate imported as ECDSA but with an RSA private key produces a “no private key found” mismatch.

WireGuard public-key authentication

WireGuard has no peer authentication beyond the public-key handshake. Each side’s configuration has its peer’s public key; the handshake succeeds only when the public keys match.

The diagnostic for a failing WireGuard handshake:

Read-only / Safewg handshake timestamp
$ wg show wg0 latest-handshakes
<peer-key-aaaa>: 0
<peer-key-bbbb>: 1700000000

Illustrative output

A peer-key-aaaa with no recent handshake has either:

  • The peer’s UDP 51820 is unreachable. Capture on the WAN; if no UDP 51820 packets arrive, the path is broken.
  • The peer’s public key is wrong. Compare the local-side wg show listed key against what the peer operator has. A copy-paste of a private key into the public-key field is the most common WireGuard configuration mistake.

A peer-key-bbbb with a recent handshake but zero byte counters has the right key but the AllowedIPs or routing is wrong (a Layer 3 problem, not an authentication problem).

Recovering from a PSK rotation

When a PSK rotation goes wrong:

  1. The old PSK is on the local side; the new PSK is on the peer side. IKE_AUTH fails because they differ.
  2. The operator changes the local side back to the old PSK (or has the peer change back to the new PSK they thought they had).
  3. The tunnel comes up.

The discipline for PSK rotation:

  • Coordinate the change window. Both operators agree on a specific time when both sides will simultaneously update the PSK. The operator who changes early sees an outage; the operator who changes late sees an outage. Coordination is the cure.
  • Keep the old PSK available for some minutes after the switch so the operator can roll back without a recovery process.
  • Verify immediately. After the switch, both sides check the tunnel comes up and traffic flows. A failed switch has to be caught quickly because coordination is hard to assemble twice.

Summary

  • PSK mismatch → AUTHENTICATION_FAILED. Verify both sides have the same secret. Reconfigure on the wrong side.
  • Certificate expiry → certificate has expired. Renew, import, update Phase 1, reload.
  • Chain validation → unable to get local issuer certificate. Import the partner’s CA.
  • Identifier mismatch → ID of X does not match expected ID. Align identifier type and value.
  • WireGuard → latest-handshake: 0. Confirm UDP 51820 reachability and peer public-key correctness.
  • Rotate credentials via coordinated change windows; track expiries in a calendar.

Knowledge check · 4 questions

  1. Q1. charon.log shows "authentication of <peer> with pre-shared key failed" followed by "IKE_AUTH response contained AUTHENTICATION_FAILED". The PSK entries look correct on both sides. What is the next diagnostic step?

  2. Q2. A certificate-based IPsec tunnel has been working for a year and stops connecting at IKE_AUTH. The most likely cause is certificate expiry.

  3. Q3. Which of the following are valid authentication failures on a WireGuard VPN? Select all that apply.

  4. Q4. A certificate-based IPsec tunnel fails with "no trusted certificate found" and "unable to get local issuer certificate". The certificate itself has not expired. What is the fix?

Passing score: 75%. Answers are checked in this browser.