Otentikasi antara klien, server pusat, dan server dijalankan pemain

8

Saya mengembangkan game sumber terbuka yang menggunakan skema client-server yang mirip dengan Minecraft. Kami akan mengontrol server otentikasi pusat yang memverifikasi akun valid, sementara pemain akan menjalankan server mereka sendiri.

Mengotentikasi klien itu sederhana, tetapi bagaimana server bisa tahu bahwa pengguna itu valid, tanpa memiliki akses ke kredensial atau token sesi?

Sebagai contoh:

  • Klien> Auth Server: Mengirim kredensial pengguna.
  • Auth Server> Client: Menanggapi dengan ID sesi jika masuk dengan benar.

Kemudian, klien dapat terhubung ke server, tetapi server tidak memiliki cara memverifikasi adalah klien yang dikatakannya. Server ini dijalankan oleh pemain, yang membuatnya mudah untuk memodifikasi server dan mengumpulkan data pengguna. (Hanya server auth pusat yang dapat dipercaya)

Server otentikasi dapat menerima koneksi TCP, tetapi saya ingin tahu apakah HTTPS akan lebih mudah dalam hal ini, karena mendapatkan respons lebih mudah daripada membuat pendengar di setiap sisi, terutama hanya untuk beberapa permintaan.

Cyral
sumber

Jawaban:

3

Sunting: Setelah memposting ini, saya menyadari bahwa jawabannya hampir sama persis dengan yang diberikan oleh Ali.S (sedikit berbeda tetapi keseluruhan pendekatannya sama.) Awalnya dimulai sebagai sesuatu yang sangat berbeda.

Metode ini mengasumsikan bahwa semua komunikasi ditahan melalui serangkaian terowongan yang aman. Bagaimana Anda mencapai ini tidak masalah. Saya akan menyarankan TLS, tapi itu hanya saya.

  1. Client => Server Game Klien terhubung ke server game dan memulai sesi login.
  2. Game Server => Server Auth Server game terhubung ke server auth dan meminta token ID sesi dari server auth. Koneksi ini tetap terbuka untuk mendengarkan keberhasilan / kegagalan login.
  3. Server Game => Klien Token ID sesi dikirim kembali ke klien.
  4. Klien => Server Auth Klien mengirim ID sesi ke server auth bersama dengan nama pengguna dan kata sandi pengguna, dan beberapa informasi tentang server (IP, kunci publik TLS, dll. Lihat catatan kaki)
  5. Auth Server => Server Game Server auth kemudian mengirimkan informasi tentang login ke server game (status keberhasilan, nama pengguna, statistik, dll.) Menggunakan ID sesi yang disediakan oleh klien.
  6. Server Game => Klien Server game memberi tahu klien bahwa auth berhasil, dan membiarkannya masuk.
  7. Semua koneksi kecuali klien awal ke koneksi server game sekarang dirobohkan.

Atau, Anda dapat memberikan port khusus untuk server game untuk mendengarkan info masuk. Jika Anda memilih rute ini, maka alirannya akan terlihat seperti ini:

  1. Klien => Server Auth Klien mengirim nama pengguna, kata sandi, dan IP server ke server auth.
  2. Auth Server => Server Game + Klien Jika login berhasil, server auth mengirimkan token unik ke server game dan klien. Kirim IP klien ke server game juga, sehingga token tidak dapat dicuri.
  3. Client => Server Game Klien kemudian mengirimkan token ke server game, yang kemudian diverifikasi dan dihapus di server game. Server game kemudian mengizinkan klien masuk.

Pendekatan kedua ini akan membuat implementasi keseluruhan sedikit lebih mudah.

Catatan kaki:

Alasan saya menentukan bahwa beberapa informasi harus dikirim tentang server game ke server auth adalah untuk memperkeras proses terhadap spoofs. Server dapat memverifikasi informasi untuk memastikan bahwa itu mengotorisasi koneksi yang diharapkan pemain.

ID sesi tidak harus aman secara kriptografis, meskipun itu akan membuat koneksi spoofing menjadi lebih sulit jika memang demikian.

Jika Anda memilih untuk pergi dengan rute TLS, Anda dapat mengatur server penandatanganan yang menandatangani semua sertifikat yang digunakan oleh infrastruktur Anda, dan menambahkannya sebagai CA tepercaya dalam perangkat lunak klien / server. Selama Anda tidak membiarkan sertifikat penandatanganan Anda longgar, Anda akan dapat memberikan beberapa otentikasi yang layak.

Demi memitigasi serangan DoS, buat koneksi habis setelah 20 detik atau kurang. Jika berlangsung lebih lama dari itu, maka ada sesuatu yang salah dan Anda tidak perlu menunggu 3 menit menunggu koneksi ke timeout sendiri.

Kaslai
sumber
Perhatikan bahwa aliran alternatif Anda kemungkinan tidak berfungsi untuk klien yang berada di belakang perangkat NAT "paralel" (diklasifikasikan sebagai "ketat", oleh program Microsoft Xbox Live). Dan mungkin juga memiliki masalah jika dua klien keduanya secara bersamaan di belakang perangkat NAT yang sama (tergantung pada spesifik bagaimana perangkat NAT mereka menangani situasi itu); ini karena server game dapat melihat port + alamat IP yang berbeda dari server auth, hanya karena NAT. Pendekatan yang terdaftar pertama harus bekerja tanpa masalah dalam semua kasus.
Trevor Powell
Hanya untuk memperjelas terminologi, Klien (pemain) tidak akan memiliki persyaratan khusus yang ditempatkan pada mereka untuk aliran kedua. Hanya server game yang membutuhkan pemetaan port khusus untuk metode ini. Karena sudah melayani permainan di pelabuhan khusus, ini seharusnya tidak terlalu banyak untuk ditanyakan. Seluruh proses dimulai oleh klien yang menginisialisasi koneksi dengan server auth, yang dapat dilakukan oleh semua perangkat di internet, terlepas dari seberapa ketat NAT mereka.
Kaslai
Setelah membaca kembali komentar Anda, saya pikir saya melihat apa masalah Anda. Dalam hal pengguna menggunakan semacam penyeimbang beban yang secara teoritis dapat mengirim permintaan auth melalui satu IP dan permintaan gim terhubung melalui IP lain, maka itu dapat diselesaikan dengan menggunakan solusi Ali S.
Kaslai
Ya, itulah yang ingin saya tunjukkan (tapi mungkin tidak menjelaskan). Di bawah NAT "ketat" (menurut definisi Microsoft), server auth dan server gim tidak akan melihat IP yang sama: Nilai port untuk satu pemain, sehingga server auth tidak dapat memberi tahu server game tentang IP / port yang diharapkan untuk melihat. Masalah ini juga dapat terjadi dengan NAT "moderat" (tergantung pada implementasi NAT tertentu) jika ada dua pemain di belakang satu perangkat NAT, keduanya mencoba mengirim dari nomor port yang sama.
Trevor Powell
Ah, well saya hanya berpikir bahwa IP itu sendiri harus diperhitungkan. Port tidak terlalu penting; Hanya untuk mencegah pihak ketiga jahat mencuri token dan menggunakannya di tempat lain. Tidak masalah jika ada banyak pengguna di belakang NAT yang sama, karena token akan mengidentifikasi pengguna yang sebenarnya, jadi tidak ada masalah tabrakan yang perlu dikhawatirkan.
Kaslai
2

Klien harus memiliki kunci pribadi dan publik .

Kunci pribadi harus berupa pengidentifikasi unik yang diterima klien dari server otentikasi. Kunci publik juga harus dikirim ke klien.

Sebelum klien terhubung ke server game, ia harus mengirim pesan dengan kunci privat dan ip server game yang ingin dihubungkan, ke server otentikasi. Server otentikasi kemudian harus memverifikasi dan menemukan kecocokan untuk kunci pribadi dan menyimpan kunci publik dalam catatannya.

Server permainan yang disambungkan klien harus mengirim permintaan ke server otentikasi setelah mendapatkan kunci publik dari klien. Jika server otentikasi dapat memverifikasi bahwa klien ingin terhubung ke IP server permainan itu, kirim kembali klien itu. Server game harus memungkinkan klien untuk terhubung.

Kunci pribadi hanya digunakan untuk otentikasi klien sehingga server game tidak mendapatkan id otentikasi asli.

Statis
sumber
1
Saya rasa saya mengerti proses yang digunakan. Saya menulis semacam diagram alur: i.pyratron.com/MXkZXU.png Apakah informasi ini tampaknya benar?
Cyral
@Cyral Itu terlihat benar.
Statis
1

Ada beberapa solusi yang dapat saya pikirkan, tetapi di sini adalah yang paling aman:

  1. klien terhubung ke server.
  2. klien meminta jembatan otentikasi.
  3. server terhubung ke server auth, bertindak sebagai proksi antara pemain dan auth. server.
  4. client dan server auth, bentuk sesi SSL di atas jembatan yang baru dibentuk ini.
  5. menggunakan koneksi aman ini melalui jembatan, klien login ke server auth.
  6. server auth memberitahu server game apakah login berhasil atau tidak, melalui beberapa koneksi TCP lainnya. kemudian putuskan koneksi bridge / login itu.
  7. client dan server game sekarang dapat melanjutkan komunikasi (hanya) melalui koneksi yang sudah ada (yang digunakan untuk otentikasi).

Perhatikan bahwa, dalam skenario ini server game sebenarnya tidak memiliki cara menguping, meskipun seluruh otentikasi melewatinya. karena alasan yang sama ISP Anda tidak dapat memantau paket apa yang Anda kirim ke Facebook, atau berasal dari facebook.

Ali1S232
sumber
Secara teknis ISP memiliki akses ke data mentah.
Statis
@ HaroldSeefeld Secara teknis bukan yang melewati koneksi IPSec / HTTPS.
Ali1S232
1

Cara saya akan melakukan ini adalah dengan meminta token server Auth mengirim ke Klien setelah login bersama dengan daftar server Game yang divalidasi (sehingga Klien dapat memastikan server Game valid).

Kemudian Klien akan mengirim token ke server Game, yang kemudian akan mengirimkannya ke server Auth untuk mengkonfirmasi bahwa ini adalah klien yang valid.

Gabung:

  1. Klien ke server Auth: nama pengguna dan kata sandi terenkripsi
  2. Server auth ke Klien: token

Nanti saat bergabung dengan server Game:

  1. Client to Game server: token yang disebutkan sebelumnya
  2. Server game ke server Auth: lagi token
  3. Server auth ke server Game: jika token valid maka sinyal OK
  4. Server permainan untuk Klien: memungkinkan klien untuk bergabung
zoran404
sumber
0

Bagaimana kalau menandatangani token JWT dengan rahasia yang hanya diketahui pusat dan server pemain? Ini memungkinkan Anda masuk json, yang dapat diverifikasi nanti.

Ben Aubin
sumber
Bukankah itu memungkinkan server yang dijalankan pemain untuk mencuri kredensial pengguna mereka?
idbrii
Tidak, 2 cara untuk melakukan ini: 1 - klien meminta jwt dengan server di dalamnya, allwoying server untuk mencuri identitas, tetapi hanya di server mereka (bukan masalah besar) 2 - JWT hanya berfungsi sekali
Ben Aubin