Bagaimana cara membagi log masuk dan permainan saat menulis server?

9

Saya membangun poker seperti server permainan, saya akan memiliki semua login dan logika permainan untuk ditangani di satu server, tetapi dari penelitian saya di web, saya belajar bahwa ini tidak akan skala, dan masuk akal untuk membagi pekerjaan menjadi server login dan game. Tapi yang tidak saya dapatkan adalah setelah saya menangani otentikasi di server login, dan meminta klien membuat koneksi baru ke server game, bagaimana saya tahu klien mana yang mana? Apakah saya tidak perlu masuk lagi dan dengan demikian mengalahkan tujuan memiliki server untuk masuk? Apakah ada cara untuk melewati koneksi di seluruh proses dan mesin yang saya tidak tahu? Maafkan sedikit pengetahuan saya tentang jaringan.

pengguna342580
sumber
4
YAGNI: Anda tidak akan membutuhkannya. Jangan menerapkan optimasi prematur. Masuk terdengar seperti bagian yang sangat sepele dari gim ini, memisahkannya sepertinya tidak akan memberikan manfaat apa pun; setelah gim Anda memiliki cukup banyak pengguna yang Anda pedulikan (Anda harus dapat mendukung ribuan pengguna di satu server, dengan yang lainnya hanya untuk redundansi), Anda akan dapat mempekerjakan beberapa insinyur perangkat lunak yang memahami hal semacam ini.
MarkR
Anda menerima jawaban yang menyesatkan, Anda harus mempertimbangkan kembali dengan cermat, atau Anda akan berakhir dengan gagasan yang salah di kepala Anda dan dengan rasa aman yang salah dalam kode Anda.
o0 '.
Saya menyukai jawaban Kylotan karena saya tidak harus memiliki koneksi ekstra antara server game dan server login, saya juga dapat melihat poin Philip bahwa kompromi kunci rahasia adalah kompromi pada semua akun yang melakukan pengiriman. Saya akan mengimplementasikan kedua versi login dan bertanya kepada pakar keamanan ketika kode saya diaudit. Pertanyaan saya tampaknya cukup mendasar dan saya berharap mereka akan menjadi solusi standar yang disetujui semua orang. Sosok pergi. Andai saja pakar keamanan dapat datang dalam diskusi ini dan membuat keputusan.
user342580
Sebenarnya, melewati token masuk di antara server Anda lebih aman, asalkan Anda memiliki saluran aman untuk melakukannya. Ini juga lebih sulit untuk diterapkan yang meningkatkan risiko kesalahan Anda. Sistem otentikasi pesan berbasis hash harus benar-benar aman kecuali seseorang dapat memperoleh kunci rahasia Anda - dan jika mereka dapat memperoleh kunci Anda melalui akses ke sistem internal Anda, Anda memiliki masalah yang tidak dapat diperbaiki dengan mengirimkan login. token secara manual.
Kylotan

Jawaban:

3

Meskipun jawaban Philipp sangat bagus, ada cara yang sedikit berbeda yang tidak memerlukan koneksi antara server login dan server game, yang berguna jika koneksi seperti itu sulit.

  1. Ketika pengguna berhasil mengautentikasi pada server masuk, mereka akan dikirim alamat server permainan dan token masuk seperti di atas. Namun token ini terdiri dari 2 bagian: waktu pada server login, dan hash nomor itu ditambah nama pengguna mereka, alamat IP mereka, alamat IP atau ID dari server permainan, dan kunci rahasia yang hanya Anda yang tahu.
  2. Klien mencoba masuk ke server game yang disediakan dengan mengirimkan token ini. Server membentuk hash yang sama seperti sebelumnya, berdasarkan informasi di token masuk ditambah alamat IP / ID dan kunci rahasia. Jika hash ini cocok dengan yang ada di token, Anda tahu pemain diautentikasi dengan benar. Kemudian periksa tanggal tidak terlalu lama (mis. Lebih dari 1 menit).

Ini berfungsi karena:

  • Tidak dapat disalin dan digunakan kembali karena tanggal akan kedaluwarsa.
  • Itu tidak dapat dibangun tanpa login baru tanpa mengetahui kunci rahasia.
  • Ini tidak dapat dengan mudah dicegat oleh orang lain (mis. Dengan sniffer paket) dan digunakan karena alamat IP asli digunakan untuk membangunnya.
  • Itu tidak dapat digunakan untuk akun yang berbeda karena nama pengguna merupakan bagian dari hash.
  • Itu tidak dapat digunakan untuk login bersamaan pada server game yang berbeda karena ID / alamat IP server merupakan bagian dari hash.

Atau lebih sederhananya, hash memastikan bahwa hampir tidak mungkin bagi pengirim untuk memalsukan token login mereka sehingga informasi dalam token dapat dipercaya.

Seperti halnya hashing yang berorientasi pada keamanan, gunakan fungsi hash terbaik yang bisa Anda dapatkan - saat ini orang-orang tampaknya menyukai bcrypt, PBKDF2, dan scrypt - dan memastikan kunci rahasia Anda sangat panjang sehingga membuat reproduksi brute force kurang praktis.

Kylotan
sumber
Sangat pintar, saya lebih suka solusi ini. Pertanyaan saya kemudian adalah kunci rahasia. Haruskah itu seperti frase sandi atau semacamnya? Dan haruskah ini berbeda untuk setiap pengguna?
user342580
Ini tidak berhasil, atau, sebenarnya implementasi ulang tersembunyi dari jawaban @ Philipp. Gagal karena mengasumsikan server masuk dan server gim mengetahui kunci rahasia yang sama. Jika mereka berdua tahu kuncinya, salah satu dari mereka harus menghubungi yang lain untuk memberikannya. Atau Anda perlu pihak ketiga untuk mengirimnya ke keduanya. Either way, itu sama sniffable seperti sebelumnya.
o0 '.
@ Lohoris, idenya adalah Anda memiliki login dan server game sekaligus dan dapat memberikan mereka kunci rahasia. Jika Anda tidak memiliki kedua server, bagaimana mungkin server game dapat memercayai otentikasi server login?
Kylotan
@ user342580: Saya akan menggunakan frasa panjang semacam. Tidak harus berbeda per pengguna, tetapi jika ya, itu tidak akan merugikan. Selama fungsi hash crypto cukup kuat dan Anda mengubahnya secara berkala itu tidak masalah.
Kylotan
@Kylotan tepatnya, dan bagaimana Anda memberi mereka kuncinya? Mengapa Anda menganggap lebih aman koneksi dari Anda ke server, daripada dari server ke server?
o0 '.
8
  1. Setelah pengguna mengautentikasi sendiri ke server masuk, berikan token (string unik, yang dibuat secara acak, terlalu lama untuk ditebak).

  2. Server login mengambil server game. Kirim token, nama pengguna, dan semua data relevan lainnya tentang pengguna dari server masuk ke server yang dipilih.

  3. Kirim token dan nama host gim untuk klien. Kemudian putuskan sambungan dari server login.

  4. Klien kemudian terhubung ke server permainan dengan nama pengguna dan tokennya.

  5. Ketika token dari klien cocok dengan yang baru saja dilaporkan oleh loginserver, Anda menerimanya.

Perhatikan bahwa agar ini aman, token harus dibuat dari generator nomor acak yang aman secara kriptografis, masing-masing token hanya dapat diterima satu kali oleh server permainan dan token yang tidak digunakan harus dibuang setelah beberapa menit.

Philipp
sumber
Jadi apakah menggunakan bcrypt sudah cukup? Saya sedang berpikir untuk membuat token dari hash waktu + nama pengguna + kata sandi menggunakan bcrypt.
user342580
Saya kira itu akan terjadi. Orang bisa menebak token ketika mengetahui kata sandi, tetapi ketika Anda tahu kata sandi, Anda bisa masuk dengan cara biasa.
Philipp
1
bcrypt bekerja selama inputnya acak dan tidak layak. Jika Anda hanya menggunakan waktu, penyerang dapat mencoba memprediksi waktu, kemudian jalankan bcrypt dan dapatkan tokennya. Pastikan untuk menggunakan garam rahasia dengan waktu atau pengacak yang aman (mis. / Dev / random pada sistem UNIX / Linux).
Sean Middleditch
Kata sandi mungkin telah dikompromikan di situs lain, jadi saya akan menghindari anggapan bahwa itu adalah rahasia yang cocok.
Sean Middleditch
1
@SeanMiddleditch Ketika kata sandi dibobol, semua keamanan tetap hilang. Seorang penyerang yang memperoleh kata sandi tidak memiliki alasan untuk menebak token, karena ia hanya bisa mendapatkannya dengan masuk dengan cara biasa.
Philipp