OpenVPN / openvpn

OpenVPN is an open source VPN daemon
http://openvpn.net
Other
10.75k stars 2.99k forks source link

Unable to re-issue new auth-token via auth-gen-token #506

Closed jkroepke closed 7 months ago

jkroepke commented 7 months ago

IMPORTANT NOTE Bugs about OpenVPN Access Server, OpenVPN Connect or any other product by OpenVPN Inc. should be directly reported to OpenVPN Inc. at https://support.openvpn.net

Describe the bug I'm running auth-gen-token <lifetime> external-auth together with reneg-sec.

The authentication via auth-token works fine, even across disconnect with is helpful with mobile clients.

However, if the <lifetime> of auth-gen-token and reached, Expired is reported as session_state to the management-client. Then, the management-client triggers a re-authentication via WEBAUTH. If succeeded, the user is authenticated again. However, on next reneg-sec event, the auth-token is Expired again.

To Reproduce To reproduce quicker, I'm using very low times. But in theory, there should be no difference between very low times, and recommend times.

reneg-sec 60
hand-window 15
auth-gen-token 300 external-auth
auth-user-pass-optional
push "auth-token-user dXNlcg=="
auth-user-pass-optional
script-security 2
auth-user-pass-verify /bin/true via-env

After 300 seconds, the OpenVPN server will report that auth-token is expired.

Expected behavior A clear and concise description of what you expected to happen.

I would expect that I if auth-token is expired and the external-auth decide to continue the session (due additional checks), a new token can be issued for the client.

A current workaround is to terminate the connection.

Version information (please complete the following information):

Additional context Add any other context about the problem here.

schwabe commented 7 months ago

@jkroepke I am not sure if we should consider this a bug at this point. You might be better off using your own auth-token and their generation insteda of relying on the quite simple mechanism that OpenVPN itself provides via the auth-gen-token support. external-auth is not meant to allow such drastic changes as to still allow an expired auth token.

selvanair commented 7 months ago

However, if the of auth-gen-token and reached, Expired is reported as session_state to the management-client. Then, the management-client triggers a re-authentication via WEBAUTH. If succeeded, the user is authenticated again. However, on next reneg-sec event, the auth-token is Expired again

Have you considered failing the authentication and let the client retry? Do a new webauth at that point(you will get session_state=Initial). It won't terminate the client process but cause a SIGUSR1 restart.

That's what happens with token expiry when external-auth is not in use.

I think the man page description of external-auth is a bit misleading. You can delay handling of expiry (like give the user a grace period) but until you fail the authentication, the token remains tied to the initial timestamps. A finer control would require custom tokens managed externally.

jkroepke commented 7 months ago

I believe that the documentation is not 100% accurate in this regard. While reading through the documentation, I thought that renewing a token also extends its lifetime. That appears to be incorrect. I confused the lifetime with idle timeout.

Change:

The token will expire either after the configured lifetime of the token

to

The token will expire either after the configured lifetime of the initial token

would clarify this.

Secondly, I thought that the auth-token could be used for much more than just a "Remember me" function. For example, VPN access requiring MFA. An auth-gen-token has been generated with a lifetime. After 8 hours, the auth-token expires, and the decision falls back to the initial authentication. Currently, one would have to use a "client-deny." It would be preferable to have authentication without a disconnect.

If I were looking for reference examples, I found only the following on GitHub. Here too, when dealing with ExpiredAuth, they simply resort to the 'normal' or 'initial' authentication. It seems the folks at Mozilla made a mistake here as well.

I agree with you if this is currently the expected negotiation. I would rather suggest turning this bug into a feature.

I don't find the auth-gen-token mechanism as simple as presented. It includes several features such as HMAC-based token authentication, lifetime management, and the ability to update the token on the client independently of reneg-sec. Additionally, I hope that the code has been thoroughly reviewed. Considering implementing custom auth-token handling would only come to mind if the discussion fails to reach a consensus.

schwabe commented 7 months ago

Simpe refers to the functionality it gives rather than the way it is implemented. All this fancy HMAC and timer and so is to make auth-token stateless and not require some backend/databse to keep track of valid/invalid tokens and their life time. If you were to implement auth-token with a backend/database it would be very simple.

The idea of auth-token is to give a VPN a lifetime. If that is expires, the token authentication fails. It is very similar to a kerberos ticket in lifetime and reneweal.

jkroepke commented 7 months ago

The idea of auth-token is to give a VPN a lifetime. If that is expires, the token authentication fails. It is very similar to a kerberos ticket in lifetime and reneweal.

Alright, thanks for clarification.