Comment empêcher un serveur piraté d'usurper un serveur maître?

8

Je souhaite configurer un modèle de jeu multicouche basé sur une salle où les joueurs peuvent héberger des matchs et servir d'hôte (IE le serveur avec pouvoir faisant autorité). Je souhaite héberger un serveur maître qui suit les articles des joueurs, leur rang, leur argent, leurs exp, etc.

Dans un tel modèle, comment puis-je empêcher quelqu'un qui héberge un jeu (avec un serveur modifié) d'usurper le serveur maître avec des résultats de correspondance invalides, gagnant ainsi de l'exp, de l'argent ou des classements.

Merci. -Cody

Cody Smith
la source
4
Réponse générique encore plus courte: vous ne pouvez pas. Dès que le code s'exécute sur un système qui n'est pas sous votre contrôle, quelqu'un peut le pirater d'une manière ou d'une autre, comme par exemple exécuter mille correspondances et signaler uniquement celles qui ont des résultats favorables.
Jari Komppa
1
Je suis d'accord avec @JariKomppa. De plus, il n'est pas nécessaire de signer vos messages.
jcora
1
@Cody: J'ai donné deux réponses ci-dessous, basées sur différentes interprétations de votre question. Pourriez-vous s'il vous plaît laissez-moi savoir lequel (le cas échéant) est plus proche de ce que vous vouliez demander?
Ilmari Karonen

Réponses:

4

Il a été souligné que ma réponse précédente était peut-être basée sur une mauvaise compréhension de ce que vous entendiez par "usurpation". (Si oui, faites-le moi savoir et je le supprimerai.)

Si ce que vous voulez empêcher, c'est que les serveurs de jeu envoient de fausses données au serveur maître, alors - comme le note Jari Komppa - c'est généralement impossible à empêcher complètement. En fait, c'est simplement une variante du problème classique de prévention de la triche multijoueur , sauf avec les serveurs intermédiaires plutôt que les clients étant ceux soupçonnés de tricher. Beaucoup des mêmes techniques utilisées pour la prévention de la triche traditionnelle pourraient fonctionner ici aussi, mais comme d'habitude, aucune d'entre elles n'est complètement infaillible.

Cela dit, il y a certaines choses que vous pourriez faire qui aideraient spécifiquement à tromper les serveurs. L'un d'eux serait que chaque joueur d'un match contacte séparément le serveur maître et confirme qu'il participe à ce match. (Vous voudrez probablement le faire avant le début du match, afin que vous puissiez vous assurer que tout le monde est d'accord sur l'identité des participants et que personne ne soit tenté de prétendre qu'il n'a pas participé à un match qu'il a perdu. Vous pouvez utiliser des signatures numériques pour différez cela, cependant; essentiellement, vous pourriez demander à chaque joueur dans un match de signer un message disant " Je suis le joueur X et je participe au match M sur le serveur S au temps T avec les joueurs Y, Z et W."et l'envoyer au serveur de jeu, qui pourra ensuite le relayer au serveur maître.) De cette façon, vous pouvez au moins vous assurer qu'un serveur de triche ne peut pas affecter le classement d'un joueur qui ne joue pas réellement sur ce serveur .

Cela est particulièrement utile si vous utilisez quelque chose comme les notes Elo où le classement des joueurs dépend principalement de leurs performances relatives . Bien sûr, quelqu'un qui exécute un faux serveur peut toujours créer un tas de faux comptes et soumettre des résultats indiquant que son propre compte bat les faux, mais avec un système de classement relatif, tout ce qui va faire est de faire en sorte que le compte du tricheur se classe légèrement au-dessus des faux ( qui à son tour auront des cotes de fond).

Une autre chose évidente à faire pour décourager la triche est de laisser les joueurs vérifier leurs résultats de match directement depuis le serveur maître. Si un joueur gagne un match sur un nouveau serveur, mais que les résultats envoyés au serveur maître indiquent qu'il a perdu (ou si les résultats ne sont jamais envoyés du tout), cela lui fera savoir qu'il se passe quelque chose de louche. Avec un peu de chance, à ce moment-là, ils signaleront le serveur pour tricherie, ou au moins voteront avec leurs pieds et ne joueront plus jamais sur ce serveur.

En fait, vous pouvez rendre cela automatique: après chaque jeu, une fois que les résultats ont été envoyés au serveur maître, demandez aux clients de les récupérer du serveur maître et de les comparer à la façon dont le client pense que le jeu s'est terminé. S'il y a un décalage, signalez-le à la fois au joueur (afin qu'il sache que quelque chose ne va pas) et au serveur maître (afin que vous puissiez détecter les serveurs qui trichent). Bien sûr, en tant qu'opérateur du serveur maître, vous devrez ensuite décider qui ment - le serveur ou le joueur - mais, espérons-le, dans la plupart des cas, cela sera assez évident d'après le schéma des rapports.

Ilmari Karonen
la source
Merci beaucoup Ilmari, les deux réponses étaient fantastiques (veuillez les garder). Désolé pour le retard, j'ai été détourné. -Cody
Cody Smith
5

Remarque: Cette réponse peut être basée sur une mauvaise compréhension de la question - voir les commentaires ci-dessous.


Réponse générique courte: utilisez des signatures numériques .

Plus précisément, le serveur maître doit avoir une clé privée pour un schéma de signature numérique approprié (RSA, DSA, ECDSA, etc.) et doit en quelque sorte relayer en toute sécurité sa clé publique à tous les clients. Ensuite, le serveur peut signer toutes les données qu'il envoie aux clients avec la clé privée (ou éventuellement l'utiliser pour négocier un secret partagé utilisable pour le cryptage et / ou l'authentification symétrique des communications entre lui et ce client particulier) et le client peut utiliser la clé publique pour vérifiez que la signature a été générée par le serveur.

Bien sûr, votre prochain problème est de distribuer la clé publique afin qu'un serveur non autorisé ne puisse pas usurper cela et substituer sa propre clé publique. Cela peut ne pas être si difficile si vous pouvez le faire à l'avance (par exemple, distribuer la clé avec l'exécutable du jeu), mais cela devient difficile si vous devez le faire plus tard, par exemple parce que l'identité du serveur maître n'est pas connue dans avance. Une solution standard consiste à distribuer à l'avance à tous les clients une autre clé publique (dont la clé privée correspondante n'est connue que de vous), puis à signer le message contenant la clé publique du serveur maître avec cette autre clé avant de la diffuser.

En fait, vous pouvez même étendre davantage ces chaînes de signature - disons, avoir une clé privée principale super secrète, qui est gardée verrouillée quelque part et dont la clé publique est connue de tous les clients, et une autre clé privée "à usage quotidien" qui est utilisé pour signer les clés du serveur et dont la clé publique est elle-même signée avec la clé principale super secrète avant d'être enfermée dans le coffre-fort. Ce n'est pas très utile en soi, mais cela devient potentiellement très utile si vous incluez également un mécanisme pour révoquer les clés compromises, de sorte que, par exemple, si votre clé d'utilisation quotidienne est divulguée, vous pouvez simplement la révoquer et en générer une autre.

Ce que je décris ci-dessus est un type rudimentaire d' infrastructure à clé publique . En fait, en implémenter un en toute sécurité peut devenir assez compliqué, mais heureusement, cela a déjà été fait. En fait, chaque fois que vous vous connectez à un site Web (comme Wikipedia ) en utilisant HTTPS , c'est à peu près exactement ce que fait votre navigateur: il reçoit un certificat de clé publique du serveur, vérifie que le certificat correspond au nom du serveur dans l'URL, n'est pas répertorié comme révoqué et a été signé par une autorité de certification connue et approuvée , puis l'utilise pour négocier une clé de chiffrement symétrique temporaireconnu uniquement de lui-même et du propriétaire de la clé privée correspondant au certificat. Cette clé symétrique est ensuite utilisée pour crypter et authentifier toutes les données envoyées entre le client et le serveur.

En particulier, vous devriez vraiment jeter un œil aux bibliothèques SSL / TLS existantes (qui sont généralement fournies avec une implémentation PKI X.509 ), ou éventuellement à SPKI . Celles-ci sont encore quelque peu compliquées, mais probablement plus faciles (et plus sûres) que d'essayer de lancer la vôtre.

Ilmari Karonen
la source
Je me trompe probablement, corrigez-moi s'il en est ainsi, mais je pense que vous manquez l'essentiel de la question. Il veut permettre aux gens de créer leurs propres serveurs, qui rapportent des statistiques à un serveur maître. Quand il fait cela, il n'y a aucun moyen d'empêcher le piratage (@Jari Kompppa a raison). -1 pour l'instant.
jcora
1
@Bane: Vous avez peut-être raison. J'ai interprété l'expression "usurpation du serveur maître" dans la question comme "faire semblant d'être le serveur maître", mais après avoir relu la question, je peux voir qu'il aurait pu vouloir dire " envoyer de fausses données au serveur maître" à la place. Vous avez raison de dire que les signatures numériques ne seront d'aucune façon contre cela.
Ilmari Karonen
2

Cela dépend de la nature du jeu et de la raison pour laquelle vous déchargez le rôle serveur.

Dans certaines circonstances, vous pourriez être en mesure d'atteindre cet objectif principalement avec des journaux d'audit cryptographiques. Par exemple, si c'est un jeu au tour par tour à deux joueurs et que vous pouvez faire en sorte que chaque client ait une clé asymétrique privée à des fins de signature, vous pouvez avoir un protocole dans le sens de

  • L'état initial S0 comprend un identifiant unique pour le jeu (pour empêcher les attaques de rejeu) et est par ailleurs supposé être constant. S'il y a un élément aléatoire, celui-ci devrait être produit par le serveur central et mis en cache pour une future comparaison.
  • P1 fait bouger m1; signe l'état résultant S1, produisant la signature C1; et l'envoie avec son coup (S1, C1, m1) à P2.
  • P2 fait déplacer m2; signe l'état résultant S2, produisant la signature C2; et l'envoie avec son mouvement (S2, C2, m2) à P1.
  • etc.

À la fin, les deux clients soumettent le résultat au serveur central, et s'ils ne sont pas d'accord, ils soumettent les pistes d'audit: (S1, C1, m1), (S2, C2, m2), etc. Puisque chaque joueur a signé ses mouvements, ils leur sont attachés.

Il est toujours vulnérable à un joueur DDOSing l'autre pour l'empêcher de soumettre son résultat, mais il n'y a vraiment pas grand-chose que vous pouvez faire à ce sujet.

NB: Ce n'est qu'un bref aperçu - je suis sûr que si vous le postez sur crypto.stackexchange.com, quelqu'un y fera des trous massifs - mais je pense que le principe est solide. Faites réviser le schéma que vous concevez par quelqu'un qui connaît son affaire avant de commencer à vous y fier.

Peter Taylor
la source
Vous pouvez éviter le problème DoS en exigeant que les journaux d'audit soient soumis à moins que tous les joueurs ne soumettent un résultat et ne l'acceptent. Cependant, un autre problème est qu'un joueur qui s'est rendu compte qu'il perdait pourrait simplement abandonner le jeu. Vous pouvez décider que l'abandon signifie la perte, mais un joueur pourrait alors donner l'impression que son adversaire a abandonné en ajoutant un coup supplémentaire à sa piste d'audit. Un moyen de contourner ce problème serait de permettre aux joueurs de télécharger les pistes d'audit soumises et de modifier ultérieurement les leurs, mais cela pourrait entraîner des jeux plutôt longs.
Ilmari Karonen