PKCS#11 hardware token unreachable when openvpn.exe runs as 'NT SERVICE\OpenVPNService' (2.7 automatic service / PLAP)
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 14.6k
- Forks
- 3.4k
- PR merge metrics
- No merged PRs in 30d
Description
Description:
On OpenVPN 2.7 running on Windows, a connection using a PKCS#11 hardware token fails to find the token when openvpn.exe is launched by the automatic service, because the process now runs as the unprivileged virtual account 'NT SERVICE\OpenVPNService'. That account cannot establish a usable PC/SC context for the reader, so pkcs11-helper reports the token as absent and openvpn emits a token-insertion request ('Please insert token'). The exact same config and 'pkcs11-id' authenticate normally when openvpn.exe is run from the console as the logged-in user.
This is the PKCS#11 counterpart of the documented 2.7 caveat that the unprivileged service account can break cryptoapi setups where certificates are not readable for 'NT SERVICE\OpenVPNService'. The difference is that there is no ACL remedy here: the credential lives on a smartcard, so it cannot be made "readable" to a service SID.
To reproduce (minimal, no GUI/PLAP)
- Place a working PKCS#11 client config ('pkcs11-providers' + a valid 'pkcs11-id') in 'C:\Program Files\OpenVPN\config-auto' so the automatic service starts it directly.
- Insert the token. Start/restart 'OpenVPNService'.
- Connection fails with a token-insertion request; the token is never found.
- Confirm the owner of the spawned process:
'Get-CimInstance Win32_Process -Filter "name='openvpn.exe'" | ForEach-Object { $o = Invoke-CimMethod -InputObject $_ -MethodName GetOwner; '{0} PID={1} Owner={2}{3}' -f $.Name, $.ProcessId, $o.Domain, $o.User }'
Result: 'Owner=NT SERVICE\OpenVPNService'.
Expected behavior
A PKCS#11 token usable by the user should remain usable for service-started and PLAP connections, as it was in 2.6.
Version
- OpenVPN 2.7.4 [git:v2.7.4/8e9e91f4caff9a80] Windows [SSL (OpenSSL)] [LZO] [LZ4] [PKCS11] [AEAD] [DCO]
- Windows version: 10.0.26100.8655, amd64
- OpenSSL 3.6.2
- Token: Gemalto / SafeNet eToken (PKCS#15 emulated), via vendor PKCS#11 middleware
- Worked under 2.6 on the same host with the same config and token.
Secondary symptom (PLAP)
The same failure occurs via the PLAP/SBL pre-logon path, where it is more severe: there is no user session at the secure desktop, and in 2.6 the pre-logon process ran as SYSTEM (the context LSASS uses for smartcard logon), so the card was reachable. Under 2.7 it runs as 'NT SERVICE\OpenVPNService' and cannot reach the card.
Confirmation that the account is the sole variable
Console, running as the user: 'openvpn --config test.ovpn' (management directives removed so the PIN prompt goes to the console) prompts for the PIN and authenticates. Card, middleware, cert, and 'pkcs11-id' are all correct.
Service, running as 'NT SERVICE\OpenVPNService': same config, token-insertion request, no token found.
Setting the service back to SYSTEM ('sc.exe config OpenVPNService obj= LocalSystem') restores token access for both the config-auto and PLAP paths.
Additional Info
This appears to be a direct consequence of the intended 2.7 hardening (unprivileged automatic service). Re-privileging the service to SYSTEM works but undoes that hardening. Is there a supported path for PKCS#11 / PC/SC-dependent setups under the unprivileged account, or should hardware-token and PLAP configs be documented as requiring the service to run as LocalSystem? A documented, supported mechanism (or at least an explicit note in the 2.7 migration guidance, alongside the existing cryptoapi caveat) would help.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the failure with the config-auto path and OpenVPNService account, then compare it with console execution and LocalSystem as described in the issue. Trace the Windows service and PLAP launch paths involved in selecting the process account and the PKCS#11/PC/SC context. Done means establishing a supported behavior or documenting the required service configuration and 2.7 migration guidance.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- authentication, networking, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 43/100