La première session gagne : filtrer les connexions OpenVPN avant l’expulsion
Rejeter une connexion ultérieure n’est pas la même chose que remplacer l’ancienne. La décision doit intervenir avant l’expulsion du même nom, et le contrôle de l’emplacement doit être atomique.
Une politique qui autorise une session par compte semble réglée jusqu’à l’arrivée de la deuxième connexion. Deux issues sont possibles : le nouvel arrivant remplace la session en cours, ou la session en cours conserve l’emplacement et le nouvel arrivant est refusé. Seule la seconde est une politique où la première session gagne. L’option client vers laquelle la plupart se tournent active la concurrence et ne la produit donc pas.
Deux contrats se cachent derrière un seul réglage
Concurrence désactivée, une seconde connexion présentant le même nom de certificat peut déplacer la session déjà en cours. Activer la concurrence autorise plusieurs sessions à la fois, ce qui est l’inverse d’une limite. Aucun des deux états n’est une politique de refus, la décision doit donc être prise ailleurs.
Écrivez le contrat avant d’implémenter quoi que ce soit : qui est refusé, quelle preuve identifie la session en cours et ce qui se passe lorsqu’une session meurt sans déconnexion propre. Une politique que personne n’a formulée ainsi ne peut pas être testée plus tard.
L’expulsion intervient avant votre hook de connexion
Dans le chemin de code du serveur 2.6, la préparation initiale d’un nouveau client supprime les instances existantes portant le même nom lorsque la concurrence est désactivée. Cette suppression a lieu avant l’exécution de la chaîne des gestionnaires de connexion. Un script qui remarque le doublon et renvoie une erreur refuse donc le nouvel arrivant après que la session en cours a déjà été éjectée - exactement le résultat que la politique devait éviter. L’ordre des rappels dans l’implémentation amont est la seule réponse fiable pour votre build.
| Stage | Who can still refuse | Effect on the incumbent |
|---|---|---|
| Certificate check | Server trust configuration | None |
| Authentication decision | The authentication controller | None, because establishment has not run |
| Connect handler | A profile script | Already evicted in the same-name case |
| Post-establishment | Status tooling, monitoring | Both sessions already exist or one is gone |
Interroger le fichier d’état n’est pas non plus une porte. Deux tentatives arrivant ensemble peuvent toutes deux voir un emplacement vide avant qu’aucune ne le valide, et toutes deux continuent.
Déplacez la décision dans l’authentification
L’interface de gestion peut reprendre la décision d’authentification après vérification du certificat. Dans cette disposition, le contrôleur n’est pas un moniteur : il reçoit chaque instance de client qui se connecte et répond si cette instance peut continuer. Comme la réponse arrive avant l’établissement, un refus laisse la session en cours intacte. Le même canal signale les déconnexions, et c’est ainsi que le contrôleur apprend qu’un emplacement a été libéré légitimement.
Chaque nouvelle instance doit franchir cette porte, y compris les reconnexions et tout chemin qui se réauthentifie sans invite. Une porte que certaines instances n’atteignent jamais ne protège rien, et l’omission reste invisible jusqu’à ce que quelqu’un essaie le contournement.
Les jetons peuvent passer devant la porte
Une fois un jeton émis, le serveur peut le valider en interne et sauter l’authentification externe pour cette connexion. L’appel de gestion n’a jamais lieu, donc un contrôle d’emplacement implémenté uniquement là ne voit jamais la nouvelle instance. Ce comportement est une commodité pour les utilisateurs et un trou pour une politique de concurrence. Faites passer les connexions authentifiées par jeton par un contrôle faisant autorité équivalent, ou désactivez le chemin du jeton lorsque la politique exige une décision sur chaque connexion.
Ne compensez pas en acceptant chaque jeton sans condition. Un jeton expiré ou invalide doit toujours échouer, et il doit échouer par le même point de décision que tout le reste.
Liez la réservation à une instance, pas à une adresse
Une adresse est une identité faible : une reconnexion depuis le même portable peut venir d’une autre adresse, et un identifiant copié peut venir de la même. Liez la réservation à l’instance de client que le serveur attribue, afin qu’une réauthentification de l’instance déjà admise soit reconnue comme propriétaire. Un nouvel identifiant d’instance doit acquérir son propre emplacement par la décision du premier arrivé, même lorsqu’il présente le même jeton.
Ne libérez que la réservation de la tentative qui a échoué. Un événement de déconnexion retardé d’une tentative plus ancienne ne doit pas effacer l’emplacement d’un propriétaire plus récent, c’est pourquoi la libération nomme l’instance et non le compte. Après un redémarrage du contrôleur, réconciliez les sessions actives avant d’admettre quiconque, et appliquez la même règle sur chaque passerelle qui sert le compte.
Décidez séparément comment un emplacement vraiment périmé est récupéré. Un administrateur a besoin d’un moyen documenté de le libérer, et ce chemin ne devrait pas être accessible à un utilisateur qui se contente de cliquer sur reconnecter.
Testez les paires qui comptent : deux connexions presque simultanées, une reconnexion après une fermeture propre, une réauthentification de la session en cours, un nouvel arrivant refusé et un redémarrage du contrôleur. Dans chaque cas, la session en cours doit rester utilisable et le nouvel arrivant doit être refusé sans dommage collatéral pour les autres comptes.