Comment diviser la logique de connexion et de jeu lors de l'écriture de serveurs?

9

Je construis un serveur de jeu de type poker, j'allais avoir toutes les logins et la logique de jeu à gérer sur un seul serveur, mais à partir de mes recherches sur le Web, j'apprends que cela ne serait pas évolutif, et il serait logique de diviser le travail dans un serveur de connexion et de jeu. Mais ce que je n'obtiens pas, c'est après avoir géré l'authentification sur le serveur de connexion et demandé au client d'établir une nouvelle connexion avec le serveur de jeu, comment savoir quel client est lequel? Ne serais-je pas obligé de me reconnecter à nouveau et de vaincre ainsi l'objectif d'avoir un serveur pour la connexion? Existe-t-il un moyen de passer une connexion entre des processus et des machines que je ne connais pas? Excusez ma petite connaissance du réseautage.

user342580
la source
4
YAGNI: vous n'en aurez pas besoin. N'implémentez pas une optimisation prématurée. La connexion sonne comme une partie très triviale du jeu, il est peu probable qu'elle se divise en procurant un avantage; une fois que votre jeu a suffisamment d'utilisateurs dont vous vous souciez (vous devriez être en mesure de prendre en charge des milliers d'utilisateurs sur un seul serveur, avec d'autres uniquement pour la redondance), vous pourrez embaucher des ingénieurs logiciels qui comprennent ce genre de chose.
MarkR
Vous avez accepté une réponse trompeuse, vous devriez reconsidérer cela avec soin, ou vous vous retrouverez avec de mauvaises notions dans votre tête et avec un faux sentiment de sécurité dans votre code.
o0 '.
J'ai aimé la réponse de Kylotan car je n'ai pas besoin d'avoir une connexion supplémentaire entre les serveurs de jeu et le serveur de connexion, je peux également voir le point de Philip selon lequel un compromis de la clé secrète est un compromis sur tous les comptes qui sont transportés. Je vais implémenter les deux versions de connexion et demander à un expert en sécurité lorsque j'obtiendrai mon code audité. Ma question semble assez simple et je m'attendais à ce que ce soit une solution standard sur laquelle tout le monde s'accorde. Allez comprendre. Si seulement un expert en sécurité pouvait venir dans cette discussion et prendre une décision.
user342580
À strictement parler, le passage du jeton de connexion entre vos serveurs est plus sécurisé, à condition que vous disposiez d'un canal sécurisé pour le faire. Il est également plus difficile à mettre en œuvre, ce qui augmente le risque de vous tromper. Un système d'authentification de message basé sur le hachage devrait être parfaitement sûr à moins que quelqu'un puisse mettre la main sur votre clé secrète - et s'il peut mettre la main sur votre clé via l'accès à vos systèmes internes, vous avez des problèmes qui ne seront pas résolus en envoyant la connexion jetons manuellement.
Kylotan

Réponses:

3

Bien que la réponse de Philipp soit parfaitement bonne, il existe une manière légèrement différente qui ne nécessite pas de connexion entre le serveur de connexion et le serveur de jeu, ce qui est utile si une telle connexion est difficile.

  1. Lorsque l'utilisateur s'authentifie avec succès sur le serveur de connexion, il reçoit une adresse de serveur de jeu et un jeton de connexion comme ci-dessus. Cependant, ce jeton se compose de 2 parties: l'heure sur le serveur de connexion et un hachage de ce numéro plus leur nom d'utilisateur, leur adresse IP, l'adresse IP ou l'ID du serveur de jeu et une clé secrète que vous seul connaissez.
  2. Le client tente de se connecter au serveur de jeu fourni en envoyant ce jeton. Le serveur forme le même hachage que précédemment, sur la base des informations contenues dans le jeton de connexion plus sa propre adresse IP / ID et la clé secrète. Si ce hachage correspond à celui du jeton, vous savez que le joueur s'est correctement authentifié. Vérifiez ensuite que la date n'est pas trop ancienne (par exemple, plus d'une minute).

Cela fonctionne parce que:

  • Il ne peut pas être copié et réutilisé car la date expirera.
  • Il ne peut pas être construit sans une nouvelle connexion sans connaître la clé secrète.
  • Il ne peut pas être facilement intercepté par quelqu'un d'autre (par exemple avec un renifleur de paquets) et utilisé parce que l'adresse IP d'origine est utilisée pour le construire.
  • Il ne peut pas être utilisé pour un autre compte car le nom d'utilisateur fait partie du hachage.
  • Il ne peut pas être utilisé pour des connexions simultanées sur différents serveurs de jeu car l'ID / l'adresse IP du serveur fait partie du hachage.

Ou, pour le dire plus simplement, le hachage garantit qu'il est presque impossible pour l'expéditeur d'avoir falsifié son jeton de connexion et que les informations contenues dans le jeton peuvent être fiables.

Comme pour tout hachage axé sur la sécurité, utilisez la meilleure fonction de hachage que vous pouvez obtenir - pour le moment, les gens semblent aimer bcrypt, PBKDF2 et scrypt - et assurez-vous que votre clé secrète est très longue afin de rendre la reproduction en force brute moins pratique.

Kylotan
la source
Très intelligent, je préfère de beaucoup cette solution. Ma question est alors la clé secrète. Cela devrait-il être comme une phrase de passe ou quelque chose? Et cela devrait-il être différent pour chaque utilisateur?
user342580
Cela ne fonctionne pas ou c'est en fait une ré-implémentation cachée de la réponse de @ Philipp. Il échoue car il suppose que le serveur de connexion et le serveur de jeu connaissent la même clé secrète. S'ils connaissent tous les deux la clé, l'un d'eux doit contacter l'autre pour la lui fournir. Ou vous avez besoin d'un tiers pour l'envoyer aux deux. Quoi qu'il en soit, il est aussi sniffable qu'avant.
o0 '.
@Lohoris, l'idée est que vous possédez à la fois la connexion et le serveur de jeu et que vous pouvez leur fournir la clé secrète. Si vous ne possédiez pas les deux serveurs, comment le serveur de jeu pourrait-il de toute façon faire confiance à l'authentification du serveur de connexion?
Kylotan
@ user342580: J'utiliserais une longue phrase en quelque sorte. Cela ne doit pas différer selon l'utilisateur, mais si c'était le cas, cela ne ferait pas de mal. Tant que la fonction de hachage cryptographique est suffisamment puissante et que vous la modifiez périodiquement, cela ne devrait pas avoir d'importance.
Kylotan
@Kylotan exactement, et comment leur fournissez-vous la clé? Pourquoi considérez-vous la connexion plus sécurisée entre vous et les serveurs que celle entre serveurs?
o0 '.
8
  1. Une fois que l'utilisateur s'est authentifié auprès du serveur de connexion, donnez-lui un jeton (une chaîne unique générée de manière aléatoire trop longue pour être devinée).

  2. Le serveur de connexion sélectionne un serveur de jeux. Envoyez le jeton, le nom d'utilisateur et toutes les autres données pertinentes sur l'utilisateur du serveur de connexion au serveur qu'il a choisi.

  3. Envoyez le jeton et le nom d'hôte du serveur de jeux au client. Déconnectez-le ensuite du serveur de connexion.

  4. Le client se connecte ensuite au serveur de jeux avec son nom d'utilisateur et son jeton.

  5. Lorsque le jeton du client correspond à celui qui vient d'être signalé par le serveur de connexion, vous l'acceptez.

Notez que pour que cela soit sécurisé, les jetons doivent être créés à partir d'un générateur de nombres aléatoires cryptographiquement sécurisé, chaque jeton ne peut être accepté qu'une seule fois par le serveur de jeu et les jetons inutilisés doivent être jetés après quelques minutes.

Philipp
la source
Alors, utiliser bcrypt suffirait-il? Je pense à créer un jeton à partir du hachage du temps + nom d'utilisateur + mot de passe en utilisant bcrypt.
user342580
Je suppose que oui. On pourrait deviner un jeton en connaissant le mot de passe, mais lorsque vous connaissez le mot de passe, vous pouvez simplement vous connecter de la manière normale.
Philipp
1
bcrypt fonctionne tant que l'entrée est convenablement aléatoire et indéchiffrable. Si vous utilisez simplement l'heure, l'attaquant peut essayer de prédire l'heure, puis exécuter bcrypt et obtenir le jeton. Assurez-vous d'utiliser un sel secret avec l'heure ou un randomiseur sécurisé (par exemple / dev / random sur les systèmes UNIX / Linux).
Sean Middleditch
Le mot de passe a peut-être été compromis sur un autre site, donc j'éviterais de supposer qu'il s'agit d'un secret approprié.
Sean Middleditch
1
@SeanMiddleditch Lorsque le mot de passe est compromis, toute sécurité est de toute façon perdue. Un attaquant qui a obtenu le mot de passe n'a aucune raison de deviner un jeton, car il pourrait simplement en obtenir un en se connectant normalement.
Philipp