我有一个游戏服务器,客户端可以通过TCP连接和通信。如果服务器知道IP和端口,任何设备都可以连接服务器。
我想知道是否需要为服务器添加一些安全性。例如,
(1)为发送/接收的消息添加一些加密。 (防止协议内容泄露)
(2)在消息中添加一些密钥,这样如果服务器在解密后无法识别密钥,则该消息将被丢弃。 (防止未知连接/消息泛滥)
你认为这些东西是必要的吗?我还应该为这样的游戏服务器添加任何其他东西。
答案 0 :(得分:2)
我宁愿把它发布到gamedev问题上,但那里的mod显然比这里更快。在你引用我之前,我想指出以下内容并非基于100%的书本知识,也没有任何这些主题的学位。如果你知道的更好,请改进这个答案,而不是评论和/或竞争。
这是我从研究和/或经验中收集的客户/服务器/安全问题的完整列表:
数据强>
"后端"服务器包含每个人的用户名,密码,信用卡详细信息等,应该是一个堡垒。此服务器仅用于身份验证,应位于私有子网上;只有当收到格式正确的登录请求时,它才会与登录服务器通信,并且只会回复"允许"或者"拒绝"。如果你接受了人们的个人信息,你有义务保护它,并且明智的做法是减轻与专业或托管公司相关的所有安全责任。此服务器没有非严重攻击;如果它被破坏,你就完蛋了。现在,许多/大多数/所有公司都在其他公司之上绘制了漂亮的登录屏幕。后端信用卡/结算系统。
<强>登录强>
与登录服务器的连接应该是安全的。登录服务器只是公共登录机制,专用数据存储和客户端/服务器连接状态之间的消息泵。出于安全考虑,对登录系统的任何HTTP访问都应托管在单独的HTTP服务器上; WWW服务器崩溃不应该关闭你的在线游戏(我的意见)。
<强>世界/ UDP 强>
成功登录和验证后,服务器会通知客户端开始收听&#34;批量数据&#34;或者在特定UDP端口上启动入站连接(可以是随机和每次连接尝试)。无论哪种方式,服务器应保持静默并等待客户端通过某种类型的握手进行IDENT以验证&#34;所谓的客户端&#34;实际上是你的代码。当服务器按顺序请求输入时,更容易猜测;相反,在连接到世界时,依靠客户知道正确的握手,并放弃那些不接受的握手。使用正确的握手可以是CPU时钟滴答或其他任何功能。从那时起,TCP将被最低限度地使用和/或断开连接。初始批量数据是宣传当前服务器端软件版本的好地方,因此过时的客户端可以更新。可以在多个服务器之间分发公共UDP端口池,并且可以将客户端负载平衡到正确的端口/服务器中。在游戏中,&#34;区域转移&#34;可能意味着从一个服务器/端口的文字断开连接并重新连接到不同的服务器/端口。在MMO游戏中,这通常显示为<2秒加载屏幕;有足够的时间断开连接,重新连接,开始获取数据,并同步到新的服务器时钟,更不用说实际的内容加载了。
&#34;世界服务器&#34;描述了在单个刀片的单个处理器的单个核上运行的单个多客户端状态泵送线程。一个物理的,世界级的服务器可以同时在其上运行许多世界。世界可以动态分割/合并(以四叉树方式),在它们之间划分客户端,再次进行负载平衡;服务器之间的同步以LAN速度或更好的速度发生。世界服务器可能只提供UDP连接,除了UDP连接的进程状态更改外,应该无需执行任何操作。 UDP是盲目的,聋哑的,愚蠢的#34;,可以这么说。发送消息时没有流量控制,没有错误检查等;它们基本上被认为是在它们被发送后立即被接收,并且可能实际上迟到,以错误的顺序到达,或者只是从未到达。使用UDP,服务器和客户端都不会停顿,握手,纠错或等待数据。消息需要时间戳,因为它们可能迟到和/或无序。如果UDP通道被阻塞,请将有效客户端动态切换到另一个(可能是随机的)端口。世界服务器仅启动与成功通过身份验证的客户端的UDP连接,并忽略所有其他流量(与HTTP和其他所有内容分开托管的世界服务器)。
过度简化,并且仅使用位置数据作为示例,每个客户端告诉服务器&#34;时间:客户端### :( X,Y)&#34;一遍又一遍。如果服务器没有听到,哦,好吧。服务器说&#34;时间:listOfClients(X,Y)&#34;一遍又一遍地给每个人。如果一个或多个客户没有听到,哦,好吧。
这意味着在客户端上使用预测/外推;客户需要猜测&#34; 应该发生什么,然后在他们再次开始获取数据时纠正自己与服务器达成一致。任何时候你得到一个包含&#34; future&#34;时间,即使数据包没有意义或没有用,你至少可以将客户端时钟推进到那一点并丢弃任何现在已经很晚的数据包,帮助一个滞后的客户赶上。
未经验证的假设:
除了现有的安全问题之外,我还没有看到为什么两个或更多客户端无法在彼此之间维护独立但服务器管理的UDP通道的原因。除了服务器之外,通过通知附近的其他客户端,客户端本身可以帮助实现负载平衡。服务器应该始终验证客户端发生了什么/应该/将要发生的事情,并且能够撤消所有这些并将两个客户端重置为它自己的已知良好状态。客户能够在内部共享的信息应该受到极大限制;基本上只是最关键的位置和/或状态数据。可能不允许客户请求特定信息,并且再次仅依赖于&#34; dumb&#34;广播。这开始接近分布式/云计算,其中客户端实际上正在进行大量的服务器工作,而服务器只是观察和&#34;裁判,&#34;在适当的时候叫犯规。
Client1 - &#34;我与Client2战斗并赢得了#34;
Client2 - &#34;我与Client1战斗并赢得了#34;
服务器 - &#34;我看了,Client2被骗了。 Client1获胜。 (Client2被迫同意)&#34;
服务器甚至不需要观看;如果Client2以异常/不可能的方式损害Client1,Client1可以请求服务器仲裁。
<强>副作用强>
如果玩家四处移动,但数据没有到达服务器,则玩家会经历&#34;橡皮筋&#34;,其中玩家出现以移动客户端但是,服务器端,他们不是。当客户端获得下一个服务器状态时,客户端会将播放器捕捉回服务器停止获取更新时的位置,从而创建橡皮筋效果。
这通常也表现出另一种方式。如果服务器看到玩家移动,则无法接收&#34;停止移动&#34;消息,服务器将预测所有其他客户端的继续路径。例如,在MMO-RPG中,您可以看到&#34;滞后&#34;球员直接进入墙壁。
<强>孔强>
我能想到的最后一件事就是基本的代码安全性。如果您的游戏是可修改的,这一点尤为重要。根据定义,Mod是用户将自己的代码插入您的代码的一种方式。如果你不注意&#34; API&#34;访问你放弃,不可避免地,有人会觉得需要恶意。如果您使用的语言需要,请特别注意字符串终止/处理。不要使用纯文本ASCII内容文件构建游戏。如果你的游戏有一个&#34;文本框,&#34;有人会尝试提供HTML / LUA /等。代码进入它。
最后,路径应尽可能使用适当的系统变量,以避免平台恶作剧和/或访问冲突(x86 / x64,ProgramFiles中没有存档游戏等)。