Как разделить логин и игровую логику при написании серверов?

9

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

user342580
источник
4
ЯГНИ: тебе это не понадобится. Не реализуйте преждевременную оптимизацию. Вход в систему звучит как очень тривиальная часть игры, разделение которой вряд ли принесет какую-либо пользу; как только в вашей игре будет достаточно пользователей, которые вам небезразличны (вы сможете поддерживать 1000 пользователей на одном сервере, а других - только для резервирования), вы сможете нанять инженеров-программистов, которые понимают подобные вещи.
MarkR
Вы приняли вводящий в заблуждение ответ, вам следует тщательно его пересмотреть, иначе у вас в голове будут неправильные представления и ложное чувство безопасности в вашем коде.
о0 '.
Мне понравился ответ Kylotan, потому что мне не нужно иметь дополнительное соединение между игровыми серверами и сервером входа в систему, я также вижу точку зрения Филиппа о том, что компрометация секретного ключа является компромиссом для всех учетных записей, которые являются фрахтованными. Я реализую обе версии логина и спрошу эксперта по безопасности, когда я проверю свой код. Мой вопрос кажется довольно простым, и я ожидал, что это будет стандартное решение, с которым все согласны. Пойди разберись. Если только эксперт по безопасности может прийти в эту дискуссию и принять решение.
user342580
Строго говоря, передача токена входа между вашими серверами более безопасна, если у вас есть безопасный канал для этого. Это также сложнее в реализации, что увеличивает риск того, что вы ошибетесь. Система аутентификации сообщений на основе хеш-функции должна быть абсолютно безопасной, если кто-то не может получить ваш секретный ключ - и если он может получить ваш ключ через доступ к вашим внутренним системам, у вас есть проблемы, которые не будут устранены путем отправки логина жетоны вручную.
Килотан

Ответы:

3

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

  1. Когда пользователь успешно проходит аутентификацию на сервере входа, ему отправляется адрес игрового сервера и токен входа, как указано выше. Однако этот токен состоит из 2 частей: время на сервере входа в систему и хеш этого числа плюс их имя пользователя, их IP-адрес, IP-адрес или идентификатор игрового сервера и секретный ключ, который известен только вам.
  2. Клиент пытается войти на предоставленный игровой сервер, отправив этот токен. Сервер формирует тот же хэш, что и раньше, основываясь на информации в токене входа в систему, а также на своем IP-адресе / идентификаторе и секретном ключе. Если этот хэш совпадает с хэшем в токене, вы знаете, что игрок аутентифицирован должным образом. Затем проверьте, не слишком ли старая дата (например, более 1 минуты).

Это работает, потому что:

  • Его нельзя скопировать и использовать повторно, так как дата истекает.
  • Он не может быть создан без нового логина, не зная секретного ключа.
  • Он не может быть легко перехвачен кем-то другим (например, с помощью анализатора пакетов) и использован, потому что для его создания используется исходный IP-адрес.
  • Его нельзя использовать для другой учетной записи, поскольку имя пользователя является частью хэша.
  • Его нельзя использовать для одновременного входа в систему на разных игровых серверах, поскольку ID / IP-адрес сервера является частью хэша.

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

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

Kylotan
источник
Очень умно, я предпочитаю это решение. Тогда мой вопрос - секретный ключ. Должно ли это быть как парольная фраза или что-то? И должно ли оно быть разным для каждого пользователя?
user342580 11.02.13
Это не работает, или, на самом деле, это скрытая повторная реализация ответа @ Philipp. Сбой, потому что он предполагает, что и сервер входа, и игровой сервер знают один и тот же секретный ключ. Если они оба знают ключ, один из них должен связаться с другим, чтобы предоставить его. Или вам нужна третья сторона, чтобы отправить ее обоим. В любом случае, это так же, как и раньше.
о0 '.
@Lohoris, идея в том, что вы владеете как логином, так и игровым сервером и можете предоставить им секретный ключ. Если вы не владеете обоими серверами, как игровой сервер может доверять аутентификации сервера входа?
Килотан
@ user342580: Я бы использовал какую-то длинную фразу. Это не должно отличаться для каждого пользователя, но если это так, это не повредит. Пока крипто-хеш-функция достаточно сильна, и вы периодически меняете ее, это не должно иметь значения.
Килотан
@ Килотан точно, и как вы даете им ключ? Почему вы считаете более безопасным соединение между вами и серверами, чем между сервером и сервером?
о0 '.
8
  1. После того, как пользователь аутентифицировался на сервере входа в систему, присвойте ему токен (уникальную, случайно сгенерированную строку, слишком длинную, чтобы угадать).

  2. Loginserver выбирает игровой сервер. Отправьте токен, имя пользователя и все другие соответствующие данные о пользователе с сервера входа на выбранный сервер.

  3. Отправьте токен и имя хоста игрового сервера клиенту. Затем отключите его от логина-сервера.

  4. Затем клиент подключается к игровому серверу со своим именем пользователя и токеном.

  5. Когда токен от клиента совпадает с токеном, только что сообщенным сервером входа в систему, вы принимаете его.

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

Philipp
источник
Так будет ли достаточно использовать bcrypt? Я думаю о создании токена из хэша времени + имя пользователя + пароль, используя bcrypt.
user342580 10.02.13
Я предполагаю, что это будет. Можно узнать токен, зная пароль, но когда вы знаете пароль, вы можете просто войти в систему обычным способом.
Филипп
1
bcrypt работает до тех пор, пока ввод будет случайным и не поддающимся проверке. Если вы просто используете время, злоумышленник может попытаться предсказать время, затем запустить bcrypt и получить токен. Обязательно используйте секретную соль со временем или безопасный рандомизатор (например, / dev / random в системах UNIX / Linux).
Шон Миддлдич
Пароль мог быть взломан на другом сайте, поэтому я бы не стал считать его подходящим секретом.
Шон Мидлдич
1
@SeanMiddleditch Когда пароль скомпрометирован, вся безопасность все равно теряется. У злоумышленника, получившего пароль, нет причин угадывать токен, потому что он мог просто получить его, войдя в систему обычным способом.
Филипп