fix: update eduroam CA certificates and improve connection handling - #110
Merged
Conversation
added 3 commits
August 31, 2026 13:56
…tlopen Twee gebreken die het onderzoeken van #109 onmogelijk maakten. run_nmcli() gaf bij 'Failed to recognize certificate' meteen False terug zonder res.stderr te printen. Dat is precies het pad waarop de aanroeper zegt 'See the terminal output above for what nmcli reported' - terwijl dat de enige tak was die niks logde. De stderr wordt nu altijd eerst gelogd, daarna pas op certificaatfouten getest. 'nmcli connection up' draaide met capture_output en zonder timeout. nmcli wacht standaard 90 seconden, dus bij een falende EAP-handshake zag de gebruiker anderhalve minuut lang helemaal niets - het symptoom dat in #109 als 'stuck on loading' gemeld is. Er wordt nu vooraf een regel geprint, --wait begrenst nmcli zelf, en een subprocess-timeout vangt af als nmcli dat negeert. De timeout-tak verwijst naar de journalctl-regel die de werkelijke oorzaak laat zien. Refs #109
De hash in beide installatiepagina's hoort bij de vorige versie van het script, dus sha256sum -c faalt nu en blokkeert de installatie. Deze checksum wordt handmatig onderhouden - update-checksums.yml dekt alleen de vastgezette CI-tools op Renovate-branches, niet dit bestand. Refs #109
Sluit #109. De gepinde keten klopte niet. Het script legde USERTrust RSA Certification Authority en GEANT OV RSA CA 4 vast, maar GEANT heeft zijn Trusted Certificate Service naar HARICA verhuisd en die twee komen in de handshake helemaal niet meer voor. Een live PEAP-handshake tegen ise.infra.saxion.net levert: depth=3 Hellenic Academic and Research Institutions RootCA 2015 depth=2 HARICA TLS RSA Root CA 2021 (cross-signed door de 2015-root) depth=1 GEANT TLS RSA 1 depth=0 ise.infra.saxion.net wpa_supplicant liep daardoor vast op 'error 19 (self-signed certificate in certificate chain) depth 3' gevolgd door 'SSL3 alert: fatal: unknown CA'. NetworkManager bleef opnieuw proberen, dus de gebruiker zag een verbinding die eindeloos bleef laden. Vastgelegd worden nu de 2015-root, die byte-voor-byte gelijk is aan het depth=3 certificaat dat de server stuurt, en de self-signed HARICA TLS RSA Root CA 2021, zodat validatie blijft werken zodra GEANT de cross-signature laat vallen. De GEANT TLS RSA 1 intermediate wordt bewust niet vastgelegd: de server stuurt hem mee, en intermediates roteren vaker dan roots. Het CA-bestand krijgt 0644 in plaats van 0600. Het zijn publieke roots en geen sleutel, en NetworkManager leest dit pad als systeemdienst bij elke verbinding. De SELinux-context van ~/.config bleek geen rol te spelen: er zijn geen AVC denials en wpa_supplicant las het bestand zonder problemen. De locatie blijft dus ongewijzigd en het script heeft nog steeds geen root nodig.
CodeQL markeert de wijziging naar 0644 als py/overly-permissive-file (high). Terecht: de mode was cosmetisch bedoeld, niet functioneel. De reden om het te verruimen is er ook niet. Uit de logs bij #109 blijkt dat wpa_supplicant het bestand op 0600 gewoon leest - de fout daar was een certificaatverificatie, geen leesfout, en er stonden geen AVC denials tegenover ondanks SELinux enforcing. NetworkManager leest dit pad als root, en dat trekt zich van de mode niets aan. Daarmee blijft de diff beperkt tot wat #109 daadwerkelijk oplost.
Member
Author
|
@Hintenhaus04, you can test if you want. |
added 2 commits
August 31, 2026 14:30
51 naar 27 regels commentaar. De uitleg bij de gepinde keten was langer dan de code eromheen en las als een essay. Wat blijft: welke roots, hoe je ze naleest van een echte handshake, en waarom pinning de moeite waard is. Wat weg is: de herhaling en het filosoferen. Geen functionele wijziging - certificaten en gedrag zijn identiek.
Als de gepinde keten niet meer klopt, zoals in #109, valt er zonder ontsnappingsluik weinig te onderzoeken. Deze vlag slaat CA-validatie over en drukt af welke keten de server werkelijk stuurde, zodat de pin te repareren is in plaats van alleen omzeild. De vlag schreeuwt wat hij weggeeft, op de terminal en in de GUI: zonder validatie wordt elk access point dat zich eduroam noemt vertrouwd, en dat kan de MSCHAPv2-uitwisseling opvangen en offline kraken. domain-suffix-match helpt daar niet tegen, want die controleert een naam op een certificaat dat niemand geverifieerd heeft. Gedocumenteerd in beide talen, met dezelfde waarschuwing. De callouts gebruiken de bestaande **Bold:** conventie - deze site draait Hugo, dus Starlight-achtige ::: blokken zouden als platte tekst renderen.
7 tasks
Stensel8
added a commit
that referenced
this pull request
Aug 31, 2026
…connect race (#111) Follow-up to #110. Pins the HARICA ECC roots alongside the RSA pair, documents where every trusted certificate comes from and why, removes the ~32 second stall on first connect. ## Type of change - [x] `feat` — new page or feature - [x] `fix` — bug fix (broken link, incorrect command, layout issue) - [x] `content` — update or improve existing content ## Details ### Autoconnect race (`1629ad4`) Measured on a real connection: ``` 16:45:30.700 CTRL-EVENT-EAP-STARTED (nothing — no success, no failure) 16:46:02.340 SME: Trying to authenticate 31.6s later, retry 16:46:02.475 CTRL-EVENT-EAP-STARTED 16:46:02.577 CTRL-EVENT-EAP-SUCCESS 102ms ``` The handshake itself takes ~100 ms including four-deep chain validation. The 32 seconds before it is NetworkManager autoconnecting the moment the profile is added — before the user has typed anything — stalling in `EAP-STARTED` until it times out, and asking for the password a second time on the way. That was the double keyring prompt users saw. The profile is now created with `connection.autoconnect no` so only the script activates it, then autoconnect is restored in a `finally` so a failed or timed-out activation does not leave a profile that never reconnects on its own. ### Self-diagnosis when the pin goes stale (`7d362a8`) A stale pin looked like a hang: NetworkManager kept retrying and nothing on screen said the certificate was the problem. On activation failure the script now reads the journal for certificate errors and, if it finds them, prints the error, the chain the server actually served, and what to do about it. Without journal access it falls back to the command the user can run themselves. Also adopted from the GÉANT CAT installer: `connection.permissions` so the profile belongs to whoever ran the script rather than every account on the machine, and `802-1x.auth-timeout` to bound a stalled EAP exchange. Trust-on-first-use was considered and rejected: it would make the first connection rely on the system trust store (~150 CAs) where the official CAT method trusts two. Wider than what Saxion prescribes, so it stays out. ### HARICA ECC roots (`da9569a`) Four pinned roots instead of two. The RSA pair is what the server serves today; the ECC pair covers a move off RSA. All four are HARICA roots, so this remains a single CA operator. HARICA publishes the cross certificate as expiring **2029-08-31**. After that the chain must terminate at the self-signed 2021 root, which is already pinned — that transition is handled, and it is a date rather than a guess. Dialogs now match the desktop: `kdialog` on KDE, `zenity` elsewhere. KDE installs frequently have zenity pulled in as somebody's dependency, which previously produced a GTK dialog on a Qt desktop. Python requirement raised from 3.10 to 3.11 with a startup check so the stated minimum means something. This is a support decision, not a technical floor — the code runs on older versions. ### Provenance of the pinned certificates (`ac2d9ce`) All four roots were verified against HARICA's own repository at repo.harica.gr. Every SHA-1 fingerprint matched the bytes in the script. The comment block now states which source does which job: CAT supplies the connection parameters (verified to agree), the live handshake shows which roots are in use, and HARICA supplies the certificates. None is trusted on its own. Both guides gained a section letting readers verify this themselves — HARICA's fingerprints next to a command that prints what is actually installed locally. The command was run; it returns exactly the four values in the table. ## Checklist - [x] PR title follows the commit convention - [x] Both EN and NL versions updated - [x] No broken image references - [x] `flake8` and `bandit -ll` clean; published SHA256 matches the script in both guides Closes #109
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Updates the pinned RADIUS CA certificates from the outdated USERTrust/GEANT chain to the current HARICA roots that Saxion's server actually uses, and improves the connection activation flow with explicit timeouts and better error messaging.
Type of change
fix— bug fix (broken link, incorrect command, layout issue)content— update or improve existing contentDetails
Script Changes (
saxion-eduroam.py)Certificate Update:
ise.infra.saxion.net:Connection Handling Improvements:
CONNECT_TIMEOUT = 45constant to prevent the script appearing frozen during the 90-second default nmcli wait--waitflag to nmcli with explicit timeoutFile Permissions:
Documentation Changes
English (
eduroam-network-installation.md):Dutch (
eduroam-network-installation.nl.md):Checklist
https://claude.ai/code/session_012kJxRh5QAtaz86aPkQLqpr