The Linux installer pins RADIUS server certificate validation to a CA bundle embedded in the
script at generation time (Config.CA, passed as 802-1x.ca-cert). When the certificate
chain presented during EAP-TLS ends up not covered by that embedded bundle, EAP authentication
fails instantly and 100% reproducibly with no useful error surfaced to the user —
NetworkManager just reports no-secrets, which misleadingly suggests a credentials problem.
We've confirmed this on Ubuntu 26.04 (NetworkManager 1.54.3); given the mechanism is generic
(OpenSSL/wpa_supplicant chain-building from a standalone ca-cert file), we'd expect it to
reproduce on any recent Linux distro shipping current NetworkManager/wpa_supplicant.
This is a regression, not a longstanding issue: the same installer, same embedded CA
bundle, and same credentials work correctly without any changes on older Ubuntu releases and
on many older Linux distro/NetworkManager/wpa_supplicant combinations we tested against. The
failure only shows up on recent versions, which points at a behavior change somewhere in how
newer OpenSSL/wpa_supplicant build the trust chain from a standalone ca-cert PEM file (rather
than at anything wrong with the embedded bundle itself, which validates fine elsewhere).
This is distinct from #354 (NUL-terminated file:// URIs) — we found this with the NUL fix
applied and it still failed, confirming it's a separate root cause. See our writeup in that
PR thread.
Important environment detail: in our deployment, this failure only happens when the client
authenticates through a RADIUS proxy on an AP controller — specifically Extreme Networks
XCC and Identity Engines sitting in front of our RADIUS backend. Access points from other
vendors on the same network (Aerohive and Juniper/Mist) connect successfully with the
same installer, same embedded CA bundle, same credentials — the only difference being
those APs don't route authentication through that proxy layer. This strongly suggests the issue
is in how the certificate chain is presented/reconstructed by the Extreme RADIUS proxy
(possibly re-signing or forwarding a different/longer chain than the backend RADIUS server
would present directly), not in the RADIUS backend itself or in the client's EAP config.
Environment
- Fails on: Ubuntu 26.04 LTS, NetworkManager 1.54.3 (netplan-managed), wpa_supplicant 2.11.
- Works fine on: older Ubuntu releases and other, older Linux/NetworkManager/wpa_supplicant
combinations, with the exact same installer and CA bundle — narrowing this down to a change
in recent NM/wpa_supplicant/OpenSSL versions, not the institution's cert setup.
- Institution realm
urjc.es, EAP-PEAP/MSCHAPv2.
- Fails: APs behind Extreme Networks XCC / Identity Engines RADIUS proxy.
- Works: APs behind Aerohive and Juniper controllers (no RADIUS proxy hop for auth).
Evidence
CTRL-EVENT-EAP-PEER-CERT depth=1 subject='/C=AT/O=ZeroSSL GmbH/CN=ZeroSSL RSA DV SSL CA 2'
CTRL-EVENT-EAP-PEER-CERT depth=0 subject='/CN=europa.urjc.es'
CTRL-EVENT-EAP-TLS-CERT-ERROR reason=1 depth=1 subject='...ZeroSSL...' err='unable to get local issuer certificate'
CTRL-EVENT-EAP-FAILURE EAP authentication failed
The server's cert chains through a ZeroSSL intermediate to Sectigo Public Server
Authentication Root R46. The bundle embedded in our institution's installer (Comodo AAA +
Sectigo R46 + HARICA) technically already includes that same Sectigo root — yet
The server's cert chains through a ZeroSSL intermediate to Sectigo Public Server
Authentication Root R46. The bundle embedded in our institution's installer (Comodo AAA +
Sectigo R46 + HARICA) technically already includes that same Sectigo root — yet
wpa_supplicant/OpenSSL fails to build the trust chain when it's supplied as a loose ca-cert
file, but only for the APs whose auth goes through the Extreme XCC/Identity Engines proxy, and
only on recent NM/wpa_supplicant versions. We haven't fully pinned down why (possibly the proxy
presents a different/incomplete chain, or newer OpenSSL is stricter about chain building from a
standalone PEM), but the failure is deterministic and 100% reproducible on that path.
What worked
Using the OS's own trust store instead of the embedded bundle:
s_8021x_data = {
'eap': [Config.eap_outer.lower()],
'identity': self.user_data.username,
- 'ca-cert': dbus.ByteArray(f"file://{self.cacert_file}\0".encode()),
+ 'system-ca-certs': True,
match_key: match_value}
Ubuntu already trusts Sectigo R46 by default, so this validates correctly and connects in ~5s,
including through the Extreme proxy path that previously failed. Tested end-to-end (profile
deleted and recreated from scratch).
Discussion
We understand system-ca-certs=True trades "pin exactly the CA the institution intended" for
"trust whatever the OS trusts", which is a real regression in strictness — we've paired it with
domain-suffix-match on our end to limit the blast radius. But this still doesn't explain why
only the Extreme XCC/Identity Engines proxy path fails, only on recent NM/wpa_supplicant, while
direct-to-backend paths (Aerohive, Juniper) and older client versions succeed with the exact
same embedded bundle. Options we can see:
- Default to system-ca-certs=True and drop the embedded bundle entirely — simplest, works
around the issue regardless of which proxy/controller or client version is involved, but
loses the pinning CAT is presumably designed to provide.
- Keep the embedded bundle as the primary ca-cert, but fall back to system-ca-certs if the
embedded one fails to validate — closer to current behavior, but adds installer complexity.
- If this turns out to be specific to how Extreme XCC/Identity Engines proxies present the
chain (truncated/reordered intermediates) combined with stricter chain-building in recent
OpenSSL/wpa_supplicant, that may warrant a separate report to Extreme rather than a CAT-side
fix — but from the client's perspective the installer's rigid pinning to a single embedded
bundle is what turns a proxy quirk (that only newer clients are sensitive to) into a hard
authentication failure, so we think it's still worth CAT being more resilient here regardless
of root cause on the network side.
Happy to open a PR for whichever direction maintainers think fits CAT's design goals, and can
gather more diagnostics on the proxy side if useful (e.g. packet capture of the EAP-TLS
handshake through the Extreme proxy vs. direct, and on older vs. newer clients).
Reproduction
- Generate an installer for an institution whose deployment includes a RADIUS proxy layer on
the AP controller (in our case Extreme XCC / Identity Engines) in front of the actual RADIUS
backend.
- Connect via an AP that routes authentication through that proxy, from a recent Linux client
(e.g. Ubuntu 26.04) — observe instant CTRL-EVENT-EAP-TLS-CERT-ERROR /
unable to get local issuer certificate in wpa_supplicant debug logs despite correct
credentials.
- Connect via an AP that does not route through the proxy (in our case Aerohive/Juniper), or
from an older Linux client — same installer, same credentials, connects successfully.
- Reconfigure the NetworkManager profile with 802-1x.system-ca-certs=yes and no ca-cert —
connects successfully through both paths.
The Linux installer pins RADIUS server certificate validation to a CA bundle embedded in the
script at generation time (
Config.CA, passed as802-1x.ca-cert). When the certificatechain presented during EAP-TLS ends up not covered by that embedded bundle, EAP authentication
fails instantly and 100% reproducibly with no useful error surfaced to the user —
NetworkManager just reports
no-secrets, which misleadingly suggests a credentials problem.We've confirmed this on Ubuntu 26.04 (NetworkManager 1.54.3); given the mechanism is generic
(OpenSSL/wpa_supplicant chain-building from a standalone
ca-certfile), we'd expect it toreproduce on any recent Linux distro shipping current NetworkManager/wpa_supplicant.
This is a regression, not a longstanding issue: the same installer, same embedded CA
bundle, and same credentials work correctly without any changes on older Ubuntu releases and
on many older Linux distro/NetworkManager/wpa_supplicant combinations we tested against. The
failure only shows up on recent versions, which points at a behavior change somewhere in how
newer OpenSSL/wpa_supplicant build the trust chain from a standalone
ca-certPEM file (ratherthan at anything wrong with the embedded bundle itself, which validates fine elsewhere).
This is distinct from #354 (NUL-terminated file:// URIs) — we found this with the NUL fix
applied and it still failed, confirming it's a separate root cause. See our writeup in that
PR thread.
Important environment detail: in our deployment, this failure only happens when the client
authenticates through a RADIUS proxy on an AP controller — specifically Extreme Networks
XCC and Identity Engines sitting in front of our RADIUS backend. Access points from other
vendors on the same network (Aerohive and Juniper/Mist) connect successfully with the
same installer, same embedded CA bundle, same credentials — the only difference being
those APs don't route authentication through that proxy layer. This strongly suggests the issue
is in how the certificate chain is presented/reconstructed by the Extreme RADIUS proxy
(possibly re-signing or forwarding a different/longer chain than the backend RADIUS server
would present directly), not in the RADIUS backend itself or in the client's EAP config.
Environment
combinations, with the exact same installer and CA bundle — narrowing this down to a change
in recent NM/wpa_supplicant/OpenSSL versions, not the institution's cert setup.
urjc.es, EAP-PEAP/MSCHAPv2.Evidence
CTRL-EVENT-EAP-PEER-CERT depth=1 subject='/C=AT/O=ZeroSSL GmbH/CN=ZeroSSL RSA DV SSL CA 2'
CTRL-EVENT-EAP-PEER-CERT depth=0 subject='/CN=europa.urjc.es'
CTRL-EVENT-EAP-TLS-CERT-ERROR reason=1 depth=1 subject='...ZeroSSL...' err='unable to get local issuer certificate'
CTRL-EVENT-EAP-FAILURE EAP authentication failed
The server's cert chains through a ZeroSSL intermediate to Sectigo Public Server
Authentication Root R46. The bundle embedded in our institution's installer (Comodo AAA +
Sectigo R46 + HARICA) technically already includes that same Sectigo root — yet
The server's cert chains through a ZeroSSL intermediate to Sectigo Public Server
Authentication Root R46. The bundle embedded in our institution's installer (Comodo AAA +
Sectigo R46 + HARICA) technically already includes that same Sectigo root — yet
wpa_supplicant/OpenSSL fails to build the trust chain when it's supplied as a loose
ca-certfile, but only for the APs whose auth goes through the Extreme XCC/Identity Engines proxy, and
only on recent NM/wpa_supplicant versions. We haven't fully pinned down why (possibly the proxy
presents a different/incomplete chain, or newer OpenSSL is stricter about chain building from a
standalone PEM), but the failure is deterministic and 100% reproducible on that path.
What worked
Using the OS's own trust store instead of the embedded bundle:
s_8021x_data = { 'eap': [Config.eap_outer.lower()], 'identity': self.user_data.username, - 'ca-cert': dbus.ByteArray(f"file://{self.cacert_file}\0".encode()), + 'system-ca-certs': True, match_key: match_value}Ubuntu already trusts Sectigo R46 by default, so this validates correctly and connects in ~5s,
including through the Extreme proxy path that previously failed. Tested end-to-end (profile
deleted and recreated from scratch).
Discussion
We understand system-ca-certs=True trades "pin exactly the CA the institution intended" for
"trust whatever the OS trusts", which is a real regression in strictness — we've paired it with
domain-suffix-match on our end to limit the blast radius. But this still doesn't explain why
only the Extreme XCC/Identity Engines proxy path fails, only on recent NM/wpa_supplicant, while
direct-to-backend paths (Aerohive, Juniper) and older client versions succeed with the exact
same embedded bundle. Options we can see:
around the issue regardless of which proxy/controller or client version is involved, but
loses the pinning CAT is presumably designed to provide.
embedded one fails to validate — closer to current behavior, but adds installer complexity.
chain (truncated/reordered intermediates) combined with stricter chain-building in recent
OpenSSL/wpa_supplicant, that may warrant a separate report to Extreme rather than a CAT-side
fix — but from the client's perspective the installer's rigid pinning to a single embedded
bundle is what turns a proxy quirk (that only newer clients are sensitive to) into a hard
authentication failure, so we think it's still worth CAT being more resilient here regardless
of root cause on the network side.
Happy to open a PR for whichever direction maintainers think fits CAT's design goals, and can
gather more diagnostics on the proxy side if useful (e.g. packet capture of the EAP-TLS
handshake through the Extreme proxy vs. direct, and on older vs. newer clients).
Reproduction
the AP controller (in our case Extreme XCC / Identity Engines) in front of the actual RADIUS
backend.
(e.g. Ubuntu 26.04) — observe instant CTRL-EVENT-EAP-TLS-CERT-ERROR /
unable to get local issuer certificate in wpa_supplicant debug logs despite correct
credentials.
from an older Linux client — same installer, same credentials, connects successfully.
connects successfully through both paths.