openvpn icon indicating copy to clipboard operation
openvpn copied to clipboard

Client is not properly notified with AUTH_FAILED when using auth-gen-token and reneg-sec

Open inclementweather opened this issue 2 years ago • 8 comments

Describe the bug AUTH_FAILED message not sent from server to client after token expiration when using auth-gen-token and reneg-sec settings on the server. Instead it is sent after auth-gen-token + (reneg-sec * 2) which leads to a stalled client until AUTH_FAILED is received.

To Reproduce use both auth-gen-token and reneg-sec

Expected behavior The AUTH_FAILED message should be sent to the client as soon as the token is expired, or ideally the the client would be asked to re-authenticate before the old token expires and a new token is pushed to the client (as the man page eludes to).

Version information (please complete the following information):

  • OS: Debian 11 server, MacOS 13.0.1 and Windows 10 22H2 clients
  • OpenVPN version: 2.5.1-3 server, 2.5.7 (Viscosity) clients

Additional context The 2.5 openvpn man page states for auth-gen-token: "The token will expire either after the configured lifetime of the token is reached or after not being renewed for more than 2 * reneg-sec seconds."

The token still expires after the specified auth-gen-token lifetime so reneg-sec should not be factored into the AUTH_FAILED control message unless there's a way to prompt for re-authentication before expiration. Perhaps these two options should be completely independent.

inclementweather avatar Jan 21 '23 03:01 inclementweather

I am trying to understand what the core problem is that you are trying to solve. The auth-token are replacing other authentication like MFA or user/password. So as long as the auth-token is valid renegotiation will work. After it is expired the renegotiation will no longer work. We also only check if the user is still allowed on these renegotiations.

If I understand your issue correctly you want the auth-token lifetime to double as session time? So the user gets kicked off after the auth-token expired?

schwabe avatar Jan 21 '23 14:01 schwabe

If I understand your issue correctly you want the auth-token lifetime to double as session time? So the user gets kicked off after the auth-token expired?

I suppose I am, yes. That's currently what I'm using reneg-sec for on a different server, not utilizing tokens at all. I don't want my clients permanently connected so reneg-sec is set to 24 hours, they auth once and have to reconnect every 24 hours.

After reading through the docs it seemed like using auth tokens was the proper way to limit session time, and reneg-sec is meant to rotate the data channel keys. I don't see any other way to limit "sessions" specifically.

Since I'm setting up a new server I've been testing out tokens and so I don't have to wait forever between tests I've purposefully made these lifetimes very short. Currently they are: auth-gen-token 300 reneg-sec 60

What I'm seeing: Renegotiation works properly every 60 seconds until the token expiration at 300 seconds. At the 360 mark the server logs note the reauth failed because of an expired token, but the client is never notified. The client still thinks its connected at this point while the server rejects the traffic, logs indicate the TLSs keys are out of sync. At the 420 mark reauth fails again but but this time the AUTH_FAILED is sent and the client finally disconnects.

The core problem is this results in the client appearing connected but not able to actually pass traffic. The server doesn't send the client AUTH_FAILED until the second failed attempt to reauth with an expired token.

I suppose I may be misusing these settings as well so please let me know if I am.

inclementweather avatar Jan 22 '23 00:01 inclementweather

Hi,

On Sat, Jan 21, 2023 at 04:07:52PM -0800, inclementweather wrote:

After reading through the docs it seemed like using auth tokens was the proper way to limit session time, and reneg-sec is meant to rotate the data channel keys. I don't see any other way to limit "sessions" specifically.

OpenVPN 2.6 brings "--session-timeout 86400", which will kick out a client instance after this time.

This said...

Since I'm setting up a new server I've been testing out tokens and so I don't have to wait forever between tests I've purposefully made these lifetimes very short. Currently they are: auth-gen-token 300 reneg-sec 60

... this should still work (60 seconds is lower than recommended 2x --hand-window = 120, so it might break due to this).

What I'm seeing: Renegotiation works properly every 60 seconds until the token expiration at 300 seconds. At the 360 mark the server logs note the reauth failed because of an expired token, but the client is never notified. The client still thinks its connected at this point while the server rejects the traffic, logs indicate the TLSs keys are out of sync. At the 420 mark reauth fails again but but this time the AUTH_FAILED is sent and the client finally disconnects.

... this is not correct behaviour, plain and simple.

OTOH, you are using 2.5.1, which is old - and I see a number of auth-token related server side changes in the 2.5 tree after that. Can you please re-test this with 2.5.8 (current 2.5 release) or 2.6_rc2?

gert

"If was one thing all people took for granted, was conviction that if you feed honest figures into a computer, honest figures come out. Never doubted it myself till I met a computer with a sense of humor." Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany @.***

cron2 avatar Jan 22 '23 06:01 cron2

OTOH, you are using 2.5.1, which is old

Yeah this is the latest version in the Debian 11 stable repo. Looks like 2.6.0-rc1 is in backports so I may try that unless there is something important between rc1 and rc2 I should consider.

Thanks for the feedback

inclementweather avatar Jan 23 '23 21:01 inclementweather

Following up. This same behavior is present in 2.5.8-bullseye0 from the openvpn.net apt repo but when using version 2.6.0-bullseye0 the client is notified immediately after the server rejects the auth token.

inclementweather avatar Feb 04 '23 01:02 inclementweather

@inclementweather there have been a lot of improvement in the TLS state machine during 2.6 development, so that 2.6 shows better behaviour is not unexpected. There some states that are kind of fine and are theoretically recoverable but in reality are not recovered so we error out in them earlier now and send the client quickly a fail message.

schwabe avatar Feb 04 '23 02:02 schwabe

Good to know. I'll deploy 2.6 and test with a few clients before rolling it out to a wider user base and fall back to 2.5.8 without auth-token if there are other issues. Feel free to close this ticket. Thank you for your attention on this.

inclementweather avatar Feb 06 '23 17:02 inclementweather

@schwabe shall we try to fix this in 2.5.8? I've seen the same behaviour (but not always) on token expiry / AUTH_FAILED in earlier versions - but all my servers have been running git master for a while, and those got it fixed...

OTOH we can just document this as "everything before 2.6.0 can get desynchronized on renegotiation, leading to partial outages, please upgrade"

cron2 avatar Mar 20 '23 21:03 cron2