Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm building a poker like game server, I was going to have all logins and game logic to be handled on one server, but from my research on the web, I learn that this would not scale, and it would make sense to split the work into a login and game servers. But what I don't get is after I handled authentication in the login server, and have the client make a new connection to the game server, how would I know which client is which? Would I not have to re-login again and thus defeat the purpose of having a server for login? Is there some way to pass a connection across processes and machines that I don't know about? Excuse my little knowledge of networking.

share|improve this question
3  
YAGNI: you aren't going to need it. Don't implement a premature optimisation. Login sounds like a very trivial part of the game, splitting it is unlikely to give any benefit; once your game has enough users that you care (you should be able to support 1000s of users on a single server, with others only for redundancy), you will be able to hire some software engineers who understand this kind of thing. –  MarkR Feb 11 '13 at 12:42
    
You accepted a misleading answer, you should reconsider that carefully, or you'll end up with wrong notions in your head and with a false sense of security in your code. –  Lohoris Feb 11 '13 at 14:21
    
I liked Kylotan's answer because I don't have to have an extra connection between the game servers and login server, I can also see Philip's point that a compromise of the secret key is a compromise on all accounts which is freighting. I will implement both login versions and ask a security expert when I get my code audited. My question seems pretty basic and I expected that their would be a standard solution that everyone agree on. Go figure. If only a security expert can come in this discussion and make a decision. –  user342580 Feb 11 '13 at 18:57
    
Strictly speaking passing the login token between your servers is more secure, providing you have a secure channel to do it with. It's also harder to implement which increases the risk of you getting it wrong. A hash-based message authentication system should be perfectly safe unless someone can get hold of your secret key - and if they can get hold of your key via access to your internal systems, you have problems that won't be fixed by sending the login tokens manually. –  Kylotan Feb 11 '13 at 23:19
add comment

2 Answers

up vote 0 down vote accepted

Although Philipp's answer is perfectly good, there is a slightly different way that does not require a connection between the login server and the game server, which is useful if such a connection is difficult.

  1. When the user authenticates successfully on the login server, they are sent a game server address and a login token as above. However this token consists of 2 parts: the time on the login server, and a hash of that number plus their username, their IP address, the IP address or ID of the game server, and a secret key that only you know.
  2. The client attempts to log in to the provided game server by sending this token. The server forms the same hash as before, based on the information in the login token plus its own IP address/ID and the secret key. If this hash matches the one in the token, you know the player authenticated properly. Then check the date is not too old (eg. more than 1 minute).

This works because:

  • It can't be copied and re-used as the date will expire.
  • It can't be constructed without a fresh login without knowing the secret key.
  • It can't easily be intercepted by someone else (eg. with a packet sniffer) and used because the original IP address is used to construct it.
  • It can't be used for a different account as the username forms part of the hash.
  • It can't be used for concurrent logins on different game servers as the server's ID/IP address forms part of the hash.

Or to put it more simply, the hash ensures that it's nearly impossible for the sender to have forged their login token and so the information in the token can be trusted.

As with any security oriented hashing, use the best hash function you can get - at the moment people seem to like bcrypt, PBKDF2, and scrypt - and ensure your secret key is very long so as to make brute force reproduction less practical.

share|improve this answer
    
Very clever, I much prefer this solution. My question is then the secret key. Should it be like a pass phrase or something? And should it be different for each user? –  user342580 Feb 11 '13 at 5:25
    
This doesn't work, or, it is actually a hidden re-implementation of @Philipp's answer. It fails because it assumes that both the login server and the game server know that same secret key. If they both know the key, one of them have to contact the other to provide it. Or you need a third party to send it to both. Either way, it is as sniffable as before. –  Lohoris Feb 11 '13 at 9:51
    
@Lohoris, the idea is that you own both the login and the game server and can provide them with the secret key. If you didn't own both the servers, how could the game server trust the login server's authentication anyway? –  Kylotan Feb 11 '13 at 13:11
    
@user342580: I would use a long phrase of some sort. It doesn't have to differ per user, but if it did, that wouldn't hurt. As long as the crypto hash function is strong enough and you change it periodically it shouldn't matter. –  Kylotan Feb 11 '13 at 13:14
    
@Kylotan exactly, and how do you provide them the key? Why do you consider more secure the connection from you to the servers, than that from server to server? –  Lohoris Feb 11 '13 at 13:28
show 7 more comments
  1. After the user authenticated itself to the loginserver, give it a token (an unique, randomly-generated string too long to be guessed).

  2. The loginserver picks a gameserver. Send the token, the username and all other relevant data about the user from the loginserver to the server it picked.

  3. Send the token and the hostname of the gameserver to the client. Then disconnect it from the loginserver.

  4. The client then connects to the gameserver with its username and token.

  5. When the token from the client matches the one just reported by the loginserver, you accept it.

Note that in order for this to be secure, the tokens need to be created from a cryptographically secure random number generator, each token may only be accepted once by the gameserver and unused tokens should be discarded after a few minutes.

share|improve this answer
    
So would using bcrypt suffice? I'm thinking of creating a token from the hash of the time+username+password using bcrypt. –  user342580 Feb 10 '13 at 19:59
    
I guess it would. One could guess a token when knowing the password, but when you know the password, you could just log in the normal way. –  Philipp Feb 10 '13 at 20:03
    
Many thanks from a beginner programmer. Cheers! –  user342580 Feb 10 '13 at 20:06
1  
bcrypt works so long as the input is suitably random and ungessuable. If you just use the time, the attacker can try to predict the time, then run bcrypt and get the token. Be sure to use a secret salt with the time or a secure randomizer (e.g. /dev/random on UNIX/Linux systems). –  Sean Middleditch Feb 10 '13 at 20:44
1  
@SeanMiddleditch When the password is compromised, all security is lost anyway. An attacker who obtained the password has no reason to guess a token, because he could just get one by logging in the normal way. –  Philipp Feb 10 '13 at 20:50
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.