From the client's side it looks like a random disconnect an hour into a working session. The tray icon drops, the tunnel rebuilds, and the log shows an authentication failure rather than a network error. What actually happened is that the session renegotiated and the second handshake needed credentials the client no longer had a valid copy of. A one-time code that worked at login cannot work again, so the rekey fails exactly as designed.

The fix is a decision about what the second handshake should present, not a longer retry timer.

Walk the exchange from the client's point of view

At login the client sends the username, the password and a code from the token device, and the server accepts the combination. The session then runs until a renegotiation trigger fires, which starts a fresh TLS handshake inside the existing tunnel. That handshake asks for authentication again. If the server's authentication path expects a password plus a current one-time code, the client has no new code to offer unless the user is present to type one.

Most clients do not open a prompt mid-session, so the handshake times out and the tunnel drops. The user sees a reconnect, not an authentication prompt, which is why the first report usually blames the network.

auth-gen-token changes who answers the second question

The auth-gen-token option lets the server issue a token after a successful login, and later renegotiations present that token instead of repeating the password and code. The manual documents its lifetime and renewal behaviour, and the token has to be treated as a credential with its own expiry. In the default path the server validates the token itself rather than calling the external password authenticator again.

With an external authentication integration, that division changes. The plugin has to understand token state and apply its own checks, because the server is no longer the only component deciding whether the session continues. Treating the token as another numeric one-time code is not an implementation of the feature.

Decide what happens to account status

A token that outlives an account's access is a policy hole. Decide how a disabled account, a removed group membership or a revoked device takes effect while a token is still valid. Short token lifetimes make the window smaller; an explicit revocation path makes it intentional. Write the answer down before enabling the option, because the default path does not consult the external authenticator on every renegotiation.

In a multi-server deployment, the token-signing secret has to be shared or the client can be sent to a node that cannot validate its token.

Test expiry and reconnection, not only login

Lower the renegotiation interval in a test profile so the second handshake happens while you are watching, then follow both logs. Confirm the token is issued at login, presented at rekey, and refreshed or reissued according to the configured lifetime. Then force a token expiry and a full reconnect, because a client that reconnects cleanly can still fail on the rekey path.

Test account removal last. That case tells you whether the policy you wrote is enforced or merely documented.

Do not fix it by disabling renewal

Setting the renegotiation interval to zero on both peers removes the symptom and the key rotation with it. That hides a credential replay problem behind a policy change nobody reviewed. Keep the renewal, and choose between a server-issued token and a fresh interactive challenge based on whether a user is present.

A longer retry timer does not make a spent code valid again. It only delays the disconnect and makes the log harder to read.

مۇناسىۋەتلىك ماقالىلەر