クライアント、中央サーバー、プレーヤー実行サーバー間の認証


8

私はMinecraftに似たクライアントサーバースキームを使用するオープンソースゲームを開発しています。プレイヤーが独自のサーバーを実行する一方で、アカウントが有効であることを確認する中央認証サーバーを制御します。

クライアントの認証は簡単ですが、サーバーは、資格情報やセッショントークンにアクセスすることなく、ユーザーが有効であることをどのようにして知ることができますか?

例えば:

  • クライアント>認証サーバー:ユーザー資格情報を送信します。
  • 認証サーバー>クライアント:有効なログインの場合、セッションIDで応答します。

その後、クライアントはサーバーに接続できますが、サーバーはクライアントが本人であることを確認する方法がありません。これらのサーバーはプレーヤーによって実行されるため、サーバーの変更とユーザーデータの収集が簡単になります。(信頼できるのは中央認証サーバーのみです)

認証サーバーはTCP接続を受け入れることができますが、この場合HTTPSの方が簡単でしょうか。応答を取得する方が、特に少数の要求に対してのみ、両側でリスナーを確立するより簡単です。

回答:


3

編集:これを投稿した後、私はそれがAli.Sによって与えられたものとほぼ同じ答えであることに気付きました(わずかに異なりますが、全体的なアプローチは同じです)。

この方法は、すべての通信が一連の安全なトンネルを介して行われていることを前提としています。これをどのように達成するかは重要ではありません。TLSをお勧めしますが、それは私だけです。

  1. クライアント=>ゲームサーバークライアントはゲームサーバーに接続し、ログインセッションを開始します。
  2. ゲームサーバー=>認証サーバーゲームサーバーは認証サーバーに接続し、認証サーバーにセッションIDトークンを要求します。この接続は、ログインの成功/失敗をリッスンするために開いたままになります。
  3. ゲームサーバー=>クライアントセッションIDトークンがクライアントに送り返されます。
  4. クライアント=>認証サーバークライアントは、ユーザーのユーザー名とパスワード、およびサーバーに関するいくつかの情報(IP、TLS公開鍵など。脚注を参照)とともに、セッションIDを認証サーバーに送信します。
  5. 認証サーバー=>ゲームサーバー認証サーバーは、クライアントから提供されたセッションIDを使用して、ログインに関する情報(成功の状態、ユーザー名、統計など)をゲームサーバーに送信します。
  6. ゲームサーバー=>クライアントゲームサーバーは、認証が成功したことをクライアントに通知し、認証を許可します。
  7. 最初のクライアントからゲームサーバーへの接続を除くすべての接続が切断されます。

または、ゲームサーバーにログインをリッスンするための専用ポートを与えることもできます。このルートを選択すると、フローは次のようになります。

  1. クライアント=>認証サーバークライアントはユーザー名、パスワード、サーバーIPを認証サーバーに送信します。
  2. 認証サーバー=>ゲームサーバー+クライアントログインが成功すると、認証サーバーはゲームサーバーとクライアントに一意のトークンを送信します。トークンが盗まれないように、クライアントのIPもゲームサーバーに送信します。
  3. クライアント=>ゲームサーバー次に、クライアントはトークンをゲームサーバーに送信し、そこでトークンが検証されてゲームサーバーで削除されます。その後、ゲームサーバーはクライアントを許可します。

この2番目のアプローチでは、全体的な実装が少し簡単になります。

脚注:

ゲームサーバーに関する情報を認証サーバーに送信する必要があると私が指定した理由は、なりすましに対するプロセスを強化するためです。サーバーは情報を検証して、プレーヤーが期待する接続を承認していることを確認できます。

セッションIDは暗号的に安全である必要はありませんが、スプーフィング接続を行うと、なりすましが困難になります。

TLSルートを選択する場合は、インフラストラクチャで使用されるすべての証明書に署名する署名サーバーをセットアップし、クライアント/サーバーソフトウェアで信頼できるCAとして追加できます。署名証明書が緩まない限り、適切な認証を提供できます。

DoS攻撃を緩和するために、20秒以下で接続をタイムアウトにします。それよりも長く続く場合は、問題が発生しており、接続がタイムアウトするのを3分間待つ必要はありません。


代替フローは、「並列」NATデバイス(MicrosoftのXbox Liveプログラムによって「厳格」として分類されている)の背後にあるクライアントでは機能しない可能性があることに注意してください。2つのクライアントが同じNATデバイスの背後に同時に存在する場合も同様に問題が発生する可能性があります(NATデバイスがその状況を処理する方法の詳細によって異なります)。これは、NATが原因で、ゲームサーバーが認証サーバーとは異なるIPアドレスとポートを認識する可能性があるためです。最初にリストされているアプローチは、すべてのケースで問題なく機能するはずです。
Trevor Powell

用語を明確にするために、クライアント(プレーヤー)は2番目のフローについて特別な要件を課されていません。この方法では、ゲームサーバーだけが専用のポートマッピングを必要とします。それはすでに専用ポートでゲームを提供しているので、これは多すぎて質問すべきではありません。プロセス全体は、クライアントが認証サーバーとの接続を初期化することによって開始されます。これは、NATの厳密性に関係なく、インターネット上の任意のデバイスが実行できます。
Kaslai

あなたのコメントを読み直すと、私はあなたの問題が何であったかを私は見ていると思います。理論的には1つのIPを介して認証リクエストを送信し、別のIPを介してゲーム接続リクエストを送信できるある種のロードバランサーを利用するユーザーの場合、Ali Sのソリューションを使用して解決できます。
Kaslai

はい、それは私が指摘しようとしていたことです(しかし、おそらくはっきりしていませんでした)。「厳密な」NAT(Microsoftの定義による)のもとでは、認証サーバーとゲームサーバーは単一のプレーヤーの同じIP:Port値を認識しないため、認証サーバーは期待するIP /ポートをゲームサーバーに通知することができません。見る。この問題は、1つのNATデバイスの背後に2人のプレーヤーがいて、どちらも同じポート番号から送信しようとしている場合、「特定のNAT実装によっては」「中程度」のNATでも発生する可能性があります。
Trevor Powell

ああ、まあ私はIP自体を説明する必要があると思っていました。移植は重要ではありません。これは、悪意のある第三者がトークンを盗んで他の場所で使用するのを防ぐためです。同じNATの背後に複数のユーザーがいても、トークンで実際のユーザーが識別されるため、衝突の問題を心配する必要はありません。
Kaslai

2

クライアントには秘密鍵と公開鍵が必要です。

秘密鍵は、クライアントが認証サーバーから受信する一意の識別子である必要があります。公開鍵もクライアントに送信する必要があります。

クライアントは、ゲームサーバーに接続する前に、秘密鍵と接続先のゲームサーバーのIPを含むメッセージを認証サーバーに送信する必要があります。次に、認証サーバーは、秘密鍵の一致を検証して見つけ、公開鍵をそのレコードに格納する必要があります。

クライアントが接続しているゲームサーバーは、クライアントの公開鍵を取得した後、認証サーバーにリクエストを送信する必要があります。認証サーバーが、クライアントがゲームサーバーのIPに接続することを望んでいることを確認できる場合は、それが問題のないクライアントであることを送り返します。ゲームサーバーは、クライアントが接続できるようにする必要があります。

秘密鍵はクライアントの認証にのみ使用されるため、ゲームサーバーは実際の認証IDを取得しません。


1
使用したプロセスは理解できたと思います。フローチャートのようなものを書きました:i.pyratron.com/MXkZXU.pngこの情報は正しいように見えますか?
2015年

@Cyralよさそうです。
静的

1

私が考えることができる複数の解決策がありますが、これが最も安全な解決策です:

  1. クライアントがサーバーに接続します。
  2. クライアントは認証ブリッジを要求します。
  3. サーバーは認証サーバーに接続し、プレーヤーと認証の間のプロキシとして機能します。サーバ。
  4. クライアントと認証サーバーは、この新しく形成されたブリッジを介してSSLセッションを形成します。
  5. ブリッジを介したこの安全な接続を使用して、クライアントは認証サーバーにログインします。
  6. 認証サーバーは、他のTCP接続を介して、ログインが成功したかどうかをゲームサーバーに通知します。次に、ブリッジ/ログイン接続を切断します。
  7. クライアントとゲームサーバーは、既存の接続(認証に使用された)を介して(のみ)通信を再開できるようになりました。

このシナリオでは、認証全体が通過していても、実際にはゲームサーバーには盗聴の手段がないことに注意してください。同じ理由で、ISPはFacebookに送信したパケットやFacebookから送信されたパケットを監視できません。


技術的には、ISPは生データにアクセスできます。
静的な2015年

@HaroldSeefeld技術的には、IPSec / HTTPS接続を通過するものではありません。
Ali1S232 2015年

1

私がこれを行う方法は、認証されたゲームサーバーのリストと共にログイン後に認証サーバーにクライアントにトークンを送信させることです(これにより、クライアントはゲームサーバーが有効であることを確認できます)。

次に、クライアントはトークンをゲームサーバーに送信し、トークンは認証サーバーに送信されて、これが有効なクライアントであることを確認します。

ログインする:

  1. クライアントから認証サーバー:ユーザー名と暗号化されたパスワード
  2. クライアントへの認証サーバー:トークン

後でゲームサーバーに参加するとき:

  1. クライアントからゲームサーバー:前述のトークン
  2. ゲームサーバーから認証サーバーへ:再びトークン
  3. 認証サーバーからゲームサーバーへ:トークンが有効であればOK信号
  4. ゲームサーバーからクライアント:クライアントが参加できるようにします

0

中央の認証とプレーヤーサーバーだけが知っている秘密でJWTトークンに署名するのはどうですか?後で検証できるjsonに署名できます。


それでは、プレーヤーが実行するサーバーがユーザーの資格情報を盗むことはできませんか?
idbrii

いいえ、これを行うには2つの方法があります。1-クライアントがサーバーを含むjwtを要求し、サーバーがIDを盗むことを余儀なくされるが、サーバー上でのみ(大したことではない)2-JWTは1度しか機能しない
Ben Aubin
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.