Opened 2 years ago
Last modified 2 years ago
#1447 new Bug / Defect
Cannot reauthenticate clients using auth-token with management-client-auth
Reported by: | jermy | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | Generic / unclassified | Version: | OpenVPN 2.5.4 (Community Ed) |
Severity: | Not set (select this one, unless your'e a OpenVPN developer) | Keywords: | |
Cc: |
Description
In order to implement MFA with both static and dynamic challenges, I've implemented a daemon to read CLIENT notifications from the Management Interface and send appropriate client-auth / client-deny responses.
To allow MFA clients to start logged in for a long time, I've also set auth-gen-token.
Basic/relevant lines of the server config are:
reneg-sec 3600 auth-gen-token 172800 management "/var/run/openvpn/vpn3.sock" unix management-client-auth
Relevant lines from the client config are:
auth-user-pass static-challenge "Enter Verification Code" 1 auth-retry interact
The issue is that on token refresh, clients that support auth-token fail to re-authenticate. The server reports the token as valid, but also as deferred without notifying the management interface and the client connection is lost.
Typical server logs (verb 3) look like:
Jan 27 11:53:41 vpnserver ovpn-vpn3[11627]: xxx.xxx.xxx.xxx:32819 TLS: Username/auth-token authentication succeeded for username 'vpnuser' Jan 27 11:53:41 vpnserver ovpn-vpn3[11627]: xxx.xxx.xxx.xxx:32819 TLS: Username/Password authentication deferred for username 'vpnuser' Jan 27 11:53:41 vpnserver ovpn-vpn3[11627]: xxx.xxx.xxx.xxx:32819 Control Channel: TLSv1.2, cipher TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, peer certificate: 2048 bit RSA, signature: RSA-SHA256 Jan 27 11:53:41 vpnserver ovpn-vpn3[11627]: xxx.xxx.xxx.xxx:32819 [vpnuser_profile] Peer Connection Initiated with [AF_INET6]::ffff:xxx.xxx.xxx.xxx:32819 Jan 27 11:53:42 vpnserver ovpn-vpn3[11627]: xxx.xxx.xxx.xxx:32819 PUSH: Received control message: 'PUSH_REQUEST' Jan 27 11:53:47 vpnserver ovpn-vpn3[11627]: xxx.xxx.xxx.xxx:32819 PUSH: Received control message: 'PUSH_REQUEST' Jan 27 11:53:53 vpnserver ovpn-vpn3[11627]: xxx.xxx.xxx.xxx:32819 PUSH: Received control message: 'PUSH_REQUEST' Jan 27 11:53:58 vpnserver ovpn-vpn3[11627]: xxx.xxx.xxx.xxx:32819 PUSH: Received control message: 'PUSH_REQUEST' Jan 27 11:54:03 vpnserver ovpn-vpn3[11627]: xxx.xxx.xxx.xxx:32819 PUSH: Received control message: 'PUSH_REQUEST' Jan 27 11:54:08 vpnserver ovpn-vpn3[11627]: xxx.xxx.xxx.xxx:32819 PUSH: Received control message: 'PUSH_REQUEST' Jan 27 11:54:13 vpnserver ovpn-vpn3[11627]: xxx.xxx.xxx.xxx:39075 [vpnuser_profile] Inactivity timeout (--ping-restart), restarting
In ssl_verify.c / verify_user_pass it looks like the token is validated...
else if (ks->auth_token_state_flags == AUTH_TOKEN_HMAC_OK) { /* * We do not want the EXPIRED or EMPTY USER flags here so check * for equality with AUTH_TOKEN_HMAC_OK */ msg(M_WARN, "TLS: Username/auth-token authentication " "succeeded for username '%s'", up->username); skip_auth = true; }
...which the causes the management interface not to be notified...
if (!skip_auth) { #ifdef ENABLE_MANAGEMENT if (man_def_auth == KMDA_DEF) { man_def_auth = verify_user_pass_management(session, multi, up); } #endif ... }
...but man_def_auth == KMDA_DEF
means authenticated is set to the KS_AUTH_DEFERRED state...
ks->authenticated = KS_AUTH_TRUE; if (plugin_status == OPENVPN_PLUGIN_FUNC_DEFERRED || script_status == OPENVPN_PLUGIN_FUNC_DEFERRED) { ks->authenticated = KS_AUTH_DEFERRED; } #ifdef ENABLE_MANAGEMENT if (man_def_auth != KMDA_UNDEF) { ks->authenticated = KS_AUTH_DEFERRED; } #endif
...and the connection is not re-authenticated.
It seems like an easy fix would be changing the last bit to:
if (man_def_auth != KMDA_UNDEF && !skip_auth) { ks->authenticated = KS_AUTH_DEFERRED; }
But there may be a cleaner way to handle this.
In the circumstances, I'm now using auth-gen-token 172800 external-auth
which sends all re-authentication requests to the daemon which can then be handled appropriately.
Change History (5)
comment:1 Changed 2 years ago by
comment:2 Changed 2 years ago by
I did try that (pushing an auth-token
) earlier in development, but my main test client at the time was network-manager-openvpn (Ubuntu 20.04, version 1.8.12-1) which doesn't return auth-ticket to the server anyway. At the time, the sanitisation of auth-token
/session_id
values in logs separately made it difficult to work out if this handling was a server or client issue!
I was hoping to use auth-gen-token
to shift the onus of re-authenticating clients away from my daemon and having to maintain its own state of authenticated sessions, but if I'm going to have to do that anyway, using external-auth
until this issue is resolved works for me.
comment:3 Changed 2 years ago by
For testing purposes, you do not need Network-Manager. Simply run each Openvpn process via a systemd-unit file, openvpn-server@.service
and openvpn-client@.service
.
comment:4 Changed 2 years ago by
This was more for integration tests - a lot of our users will be connecting through Ubuntu/Debian? so making sure those work straight up was important. Other users are using the standard client, and those are much more straightforward generally (apart from the usual issues with DNS updates on linux).
comment:5 Changed 2 years ago by
Auth-Tokens with Network-Manager do work, but NM has... ideas... on how things are supposed to work. The problem is when you do suspend/resume or change networks, NM will shutdown and restart openvpn - and there is no way to save the received auth-token anywhere in this case, so "back to 2FA".
The combined use of
--auth-gen-token
and--management-client-auth
probably has never been tested and the behaviour reported here looks like a bug.Have you tried pushing the auth-token from the
management-client-auth
handler (i.e the python script in this case) via the client-auth response, so that the entire auth process including reauth is handled in one place? That was the only way to useauth-token
prior to the introduction of--auth-gen-token
in 2.4. REAUTH vs CONNECT is indicated in the >CLIENT notification.