Opened 5 years ago

Last modified 3 years ago

#1147 assigned Bug / Defect

token authentication issues

Reported by: Gert Döring Owned by: plaisthos
Priority: major Milestone: release 2.5.4
Component: Generic / unclassified Version: OpenVPN git master branch (Community Ed)
Severity: Not set (select this one, unless your'e a OpenVPN developer) Keywords: token, authentication, reconnect
Cc: plaisthos

Description

I'm copying in the content of Arne's long mail in <4c8dbc1b-71c9-6187-
5ecf-f1dbfb957561@…> so it won't get lost:


The discussion has gone on a bit about this patch. I would like to step back and give an overview to make this mess better understandable as we have multiple problem mixed together.

Current client behaviour:

  • (a) OpenVPN 3. Forgets auth-token on reconnect, can be told to forget auth-token during a session with AUTH_FAILED,SESSION
  • (b) OpenVPN 2.x Once it gets an auth-token, the auth-token replace the password and the client will never anything else from that point on

Proposed new behaviour:

  • (c) OpenVPN 2.x should behave exactly like OpenVPN 3
  • (d) OpenVPN 2.x if not intrustucted otherwise will keep auth-token on reconnect but will forget it as soon as it gets an AUTH-FAILED (what my patch proposed)

Current OpenVPN server behaviour:

  • (i) Custom client-connect script with auth-token can send an auth-token and can also check the same token on reconnect
  • (ii) auth-gen-token sends an auth-token but the auth-token is only valid for the session. The token can also set to expiry earlier in which case the server fails to notify the client about th failed auth-token.

Currently working combinations are (i)+(a) and ii+b. OpenVpn? 3 with custom script (i+b) will also work but will query for password/OTP password on every reconnect/network change.

Current problems:

  • (1) OpenVPN 2.x server does only signal AUTH-FAILED on the initial tls session but not on later ones (I am ingoring the management special case here)
  • (2) OpenVPN 2.x client does not understand AUTH_FAILED,SESSION
  • (3) OpenVPN 2.x client (b) against an auth-gen-token server (ii): Client will use the auth-token buth the server does not know anything anymore about the token and the authentication fails

Problem (1) and (2) are unproblematic as far as the discussion goes as there is no doubt that we should "just" implement them in 2.x.

Fixes for (3), client side:

  • Using new behaviour (c), like OpenVPN 3. This will work but will make the custom script solution (i) worse and also has more real authentication on network changes. At least I see no reason why a token after an OTP password should be invalidated after a network change.
  • Using new behaviour (d): Will continue to work with custom script as before. Will also be able to recover when connecting to to an *unpatched* auth-gen-token server but will need two attempts on a reconnect since the first fails with an AUTH_FAILED.
  • In either (c) and (d) as new client behaviour, there should be a pushable option that allows the server to select the auth-token behaviour on reconnect (forget or keep)

Fixes for the server side for (3):

  • implement persistent auth-tokens: Will allow old clients (b) to reconnect. Maybe change expire time to be "after not being used for x hours". Old clients will still fail to reconnect if the server is restarted unless tokens survive server restart.
  • do not send auth-token to client that have behaviour (b). For this to happen the server needs to know if a client has behaviour (b) or not.

My suggestion here was to increase IV_PROTO to 3. The 3 here should only signal that the client has some way of dealng with an expiring token on reconnect and that the current behaviour of auth-gen-token is safe to use. It does not matter if the client recovers from AUTH-FAILED when a token is in use or if the client forgets the token. (minimal common behsaviour). IV_PROTO should also include "understand AUTH_FAILED,SESSION"

This has been a long mail but I hope it clear ups some of the onfusion.

Arne

Change History (10)

comment:1 Changed 5 years ago by Gert Döring

Cc: arne added; plai removed

comment:2 Changed 5 years ago by tct

cc

comment:3 Changed 5 years ago by RemoteOne

I don't quite understand if my scenario is covered by the existing explanation. Using openVPN 2.4.7 with windows GUI 11.13.0

If I set
auth-gen-token 3600
reneg-sec 900

I login the first time and get a token generated. For the first 3 reneg-sec timeouts the VPN automatically accepts the token and continues as normal.

On the 4th one it recognizes that there is a problem of token expiry, and causes a full reconnect. This is where the problems start.

(1) It thinks it has a token so it does not prompt for credentials to be entered
(2) Even though the session expired due to a timeout on the token - there does not seem to be any expiry actually contained in the token - so the client reuses the same supposedly expired token and treats it as being valid for the period of the auth-gen-token timeout from that point on, and the server does not object. It happily accepts the token.
This pattern repeats ad infinitum.

If I set the token expiry to 12 hours for example, and shut down (or sleep) my PC every evening, I would never again be asked for any credentials as the VPN would auto-connect every day thinking it had a valid 12 hour token to use.

The fix for this has to include the client disposing of the token, and being forced to reauthenticate in whatever the normal way is, upon expiration of the auth-gen-token timeout.

Clearly the token should have an identifyable expiry built into it so that both the client and the server can and will reject expired tokens.

Vincent

comment:4 Changed 4 years ago by Gert Döring

The auth-token handling on the server side has been reworked extensively, but this is not being backported to 2.4 (because it is fairly big and intrusive).

Can you retry your setup with git master? It should work nicely now.

comment:5 Changed 4 years ago by RemoteOne

@Gert - I am happy to test the code but I need some help to do so. I run the CentOS EPEL version of openvpn installed with yum install openvpn. Do I need to remove that package to test your code, and if so, what are the steps to install/test/remove so I can go back to the packaged version if needed. Thanks.

comment:6 Changed 4 years ago by tct

Simply git:clone openvpn git:master and follow the usual instructions to build openvpn:
https://github.com/OpenVPN/openvpn/blob/master/README

Once you have the new binary in ./src/openvpn you can use it, instead of the EPEL installed package. You do not need to remove anything but you will need to make sure you start the correct binary ./src/openvpn/openvpn in what ever manner you chose to start openvpn.

On CentOS7 I use a customised systemd unit file, which points to the binary i wish to start.

Version 1, edited 4 years ago by tct (previous) (next) (diff)

comment:7 Changed 4 years ago by Gert Döring

Owner: set to plaisthos
Status: newassigned

comment:8 Changed 4 years ago by Gert Döring

Milestone: release 2.5

comment:9 Changed 3 years ago by Gert Döring

Cc: plaisthos added; arne removed
Milestone: release 2.5release 2.5.3

So, for the record - these token reconnect / expiry issues work "better" in 2.5 than in 2.4, but especially in combination with async authentication plugins still cause weird effects.

This is known and the implementation in master is fixed in that regard (but has *other* unpleasantness).

Keeping this open and bumping the milestone to 2.5.3 to see if we can get this backported to 2.5 in a reasonable way.

comment:10 Changed 3 years ago by Gert Döring

Milestone: release 2.5.3release 2.5.4

Looking at my user reports (talking to a server with 2FA, 10 hour token life time and 1 hour reneg-time) and also at the release/2.5 branch, we seem to have covered most/all of the client side issues in 2.5.x. My servers run -current, though.

We need to test the server side on 2.5.x, though, to see if we have the most important bits covered

  • normal renegotiation with token
  • token expiry
  • server restart with token
  • 2FA (= AUTH_FAIL if the client happens to re-send stale user+password info on token expiry).

Not happening for 2.5.3, though, so bumping the milestone.

Note: See TracTickets for help on using tickets.