Аутентификация между клиентом, центральным сервером и запущенным сервером игрока


8

Я занимаюсь разработкой игры с открытым исходным кодом, которая использует схему клиент-сервер, аналогичную Minecraft. Мы будем контролировать центральный сервер аутентификации, который проверяет действительность учетной записи, в то время как игроки будут запускать свои собственные серверы.

Аутентификация клиента проста, но как сервер может узнать, что пользователь действителен, не имея доступа к учетным данным или токену сеанса?

Например:

  • Клиент> Сервер аутентификации : отправляет учетные данные пользователя.
  • Auth Server> Client: отвечает с идентификатором сеанса, если действительный вход в систему.

Затем клиент может подключиться к серверу, но сервер не может проверить, является ли клиент тем, кто говорит. Эти серверы управляются игроками, что позволяет им легко модифицировать сервер и собирать пользовательские данные. (Только центральному серверу аутентификации можно доверять)

Сервер аутентификации может принимать TCP-соединения, но мне интересно, будет ли HTTPS легче в этом случае, так как получить ответ легче, чем установить прослушиватель на каждой стороне, особенно для нескольких запросов.

Ответы:


3

Редактировать: После публикации я понял, что это почти тот же самый ответ, который дал Али.С (немного другой, но общий подход тот же.) Он начался как нечто совершенно иное.

Этот метод предполагает, что все коммуникации проходят через серию безопасных туннелей. Как вы этого достигнете, не имеет значения. Я бы предложил TLS, но это только я.

  1. Клиент => Игровой сервер Клиент подключается к игровому серверу и инициирует сеанс входа в систему.
  2. Игровой сервер => Сервер аутентификации. Игровой сервер подключается к серверу аутентификации и запрашивает токен идентификатора сеанса с сервера аутентификации. Это соединение остается открытым для прослушивания успешного / неудачного входа в систему.
  3. Игровой сервер => Клиент Маркер идентификатора сеанса отправляется обратно клиенту.
  4. Клиент => Сервер аутентификации Клиент отправляет идентификатор сеанса на сервер аутентификации вместе с именем пользователя и паролем пользователя, а также некоторую информацию о сервере (IP, открытый ключ TLS и т. Д. См. Сноски)
  5. Сервер аутентификации => Игровой сервер Затем сервер аутентификации отправляет информацию о входе в систему на игровом сервере (состояние успеха, имя пользователя, статистика и т. Д.), Используя идентификатор сеанса, предоставленный клиентом.
  6. Игровой сервер => Клиент Игровой сервер сообщает клиенту, что аутентификация прошла успешно, и пропускает их.
  7. Все соединения, кроме первоначального подключения клиента к игровому серверу, теперь разорваны.

Кроме того, вы можете назначить игровым серверам выделенный порт для прослушивания входа в систему. Если вы выберете этот маршрут, то поток будет выглядеть так:

  1. Клиент => Сервер аутентификации Клиент отправляет имя пользователя, пароль и IP-адрес сервера на сервер аутентификации.
  2. Сервер аутентификации => Игровой сервер + Клиент Если вход в систему успешен, сервер аутентификации отправляет уникальный токен игровому серверу и клиенту. Также отправьте IP-адрес клиента на игровой сервер, чтобы токен не был украден.
  3. Клиент => Игровой сервер. Затем клиент отправляет токен на игровой сервер, где он затем проверяется и удаляется на игровом сервере. Затем игровой сервер впускает клиента.

Этот второй подход сделает общую реализацию немного проще.

Примечания:

Причина, по которой я указываю, что некоторая информация об игровом сервере должна быть отправлена ​​на сервер аутентификации, состоит в том, чтобы обезопасить процесс от подделок. Сервер может проверить информацию, чтобы убедиться, что он авторизует соединение, которое ожидает игрок.

Идентификаторы сеансов не обязательно должны быть криптографически безопасными, хотя в этом случае подделка соединений будет несколько сложнее.

Если вы решите пойти по маршруту TLS, вы можете настроить подписывающий сервер, который подписывает все сертификаты, используемые вашей инфраструктурой, и добавить его в качестве доверенного ЦС в клиент-серверном программном обеспечении. Пока вы не позволите своему сертификату подписи ослабнуть, вы сможете обеспечить некоторую достойную аутентификацию.

Ради смягчения DoS-атак установите время ожидания соединения через 20 или менее секунд. Если он длится дольше, значит, что-то не так, и вам не нужно ждать 3 минуты, ожидая, пока соединение не отключится само по себе.


Обратите внимание, что ваш альтернативный поток, скорее всего, не будет работать для клиентов, которые находятся за «параллельными» NAT-устройствами (классифицированными как «строгие» программой Microsoft Xbox Live). И аналогичным образом могут возникнуть проблемы, если два клиента одновременно находятся за одним и тем же устройством NAT (в зависимости от особенностей того, как их устройство NAT обрабатывает эту ситуацию); Это связано с тем, что игровой сервер может видеть другой IP-адрес + порт, чем сервер аутентификации, только из-за NAT. Первый из перечисленных подходов должен работать без проблем во всех случаях.
Тревор Пауэлл,

Просто чтобы прояснить терминологию, у Клиента (игрока) не будет особых требований, предъявляемых к ним для второго потока. Только игровому серверу понадобится выделенное отображение портов для этого метода. Поскольку он уже обслуживает игру через выделенный порт, спросить его не стоит. Весь процесс запускается клиентом, устанавливающим соединение с сервером авторизации, что может сделать любое устройство в Интернете, независимо от того, насколько строгим является их NAT.
Каслай

Перечитав ваш комментарий, я думаю, что вижу вашу проблему. В случае, если пользователь использует какой-то балансировщик нагрузки, который теоретически может отправить запрос авторизации через один IP, а запрос игрового подключения - через другой IP, это можно решить с помощью решения Ali S.
Каслай

Да, это то, что я намеревался указать (но, возможно, не ясно). При «строгом» NAT (по определению Microsoft) сервер аутентификации и игровой сервер не будут видеть одинаковые значения IP: порта для одного игрока, поэтому сервер аутентификации не может с пользой сообщить игровому серверу ожидаемый IP / порт увидеть. Эта проблема также может возникнуть с «умеренным» NAT (в зависимости от конкретной реализации NAT), если за одним устройством NAT находятся два игрока, и оба пытаются отправить с одного номера порта.
Тревор Пауэлл

Ах, я просто думал, что сам IP следует учитывать. Порт на самом деле не имеет значения; Это просто для предотвращения кражи токена злоумышленником и его использования в другом месте. На самом деле не имеет значения, есть ли несколько пользователей за одним и тем же NAT, так как токен идентифицирует реального пользователя, поэтому проблем коллизий не возникает.
Каслай

2

Клиент должен иметь закрытый и открытый ключ.

Закрытый ключ должен быть тем, что уникальный идентификатор, который клиент получает от сервера аутентификации. Открытый ключ также должен быть отправлен клиенту.

Прежде чем клиент подключится к игровому серверу, он должен отправить сообщение со своим закрытым ключом и IP-адресом игрового сервера, к которому он хочет подключиться, на сервер аутентификации. Затем сервер аутентификации должен проверить и найти соответствие для закрытого ключа и сохранить открытый ключ в своих записях.

Игровой сервер, к которому подключается клиент, должен отправить запрос серверу аутентификации после получения открытого ключа клиента. Если сервер аутентификации может подтвердить, что клиент хочет подключиться к этому IP-адресу игрового сервера, отправьте его обратно в порядке. Игровой сервер должен позволить клиенту подключиться.

Закрытый ключ используется только для аутентификации клиента, поэтому игровой сервер не получает реальный идентификатор аутентификации.


1
Я думаю, что я понимаю используемый процесс. Я написал блок-схему такого рода вещей: i.pyratron.com/MXkZXU.png Кажется ли эта информация правильной?
Кирал

@Cyral Это выглядит правильно.
Статическое

1

Есть несколько решений, о которых я могу подумать, но вот самое безопасное:

  1. клиент подключается к серверу.
  2. клиент запрашивает мост аутентификации.
  3. Сервер подключается к серверу авторизации, выступая в качестве прокси между плеером и аутентификацией. сервер.
  4. клиент и сервер аутентификации, формируют сеанс SSL по этому недавно сформированному мосту.
  5. используя это безопасное соединение через мост, клиент входит на сервер аутентификации.
  6. auth server сообщает игровому серверу, был ли вход успешным или нет, через какое-то другое TCP-соединение. затем отключает соединение через мост / логин.
  7. клиент и игровой сервер теперь могут возобновить связь (только) через уже существующее соединение (которое использовалось для аутентификации).

Обратите внимание, что в этом сценарии игровой сервер фактически не имеет возможности прослушивания, даже если вся аутентификация проходит через него. по той же причине, по которой ваш интернет-провайдер не может отслеживать, какие пакеты вы отправляете на Facebook или отправляете с Facebook.


Технически провайдер имеет доступ к необработанным данным.
Статическое

@HaroldSeefeld Технически не те, которые проходят через соединение IPSec / HTTPS.
Ali1S232

1

Я бы сделал так, чтобы сервер авторизации отправлял токен клиенту после входа в систему вместе со списком проверенных игровых серверов (чтобы клиент мог быть уверен, что игровой сервер действителен).

Затем Клиент отправляет токен на игровой сервер, который затем отправляет его на сервер аутентификации, чтобы подтвердить, что это действительный клиент.

Авторизоваться:

  1. Клиент к серверу аутентификации: имя пользователя и зашифрованный пароль
  2. Авторизация сервера клиенту: токен

Позже при присоединении к игровому серверу:

  1. Клиент-игровой сервер: ранее упомянутый токен
  2. Игровой сервер к серверу аутентификации: снова токен
  3. Проверка подлинности сервера на игровом сервере: если токен действителен, то сигнал ОК
  4. Игровой сервер к клиенту: позволяет клиенту присоединиться

0

Как насчет подписи токена JWT секретом, который знает только центральный сервер аутентификации и проигрывателя? Это позволяет вам подписать JSON, что может быть проверено позже.


Разве это не позволило бы управляемым игроками серверам украсть учетные данные своих пользователей?
idbrii

Нет, 2 способа сделать это: 1 - клиент запрашивает JWT с сервером в нем, используя сервер для кражи идентификационных данных, но только на своем сервере (не имеет значения) 2 - JWT работает только один раз
Бен Обин
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.