协议抗错套接字服务器
我正在 C# 上开发服务器(使用 *Async 方法)。一切工作正常,直到一侧违反协议(例如对服务器的攻击)。
客户端和服务器交换具有以下结构的消息:
- 前 4 个字节定义消息正文的长度 (N)(以字节为单位)
- 接下来的 N 个字节定义消息正文
如果有人传输错误的长度 - 该客户端和服务器之间的所有通信都将变得不可预测。
所以我们的想法是以最简单的方式创建一个自同步协议。
我使用的是 TCP 协议,因此想法是将消息分成数据包,并且任何两条消息都不应共享同一个数据包 - 这样,如果出现问题,我将能够忽略协议违规并恢复通信。
我想为此使用 TCP,因此数据包将与 TCP 段相同。但有几个问题:
- MTU(定义 MSS)可能不同,并且没有我可以使用的缓冲区大小的预定义值(如果我错了,请纠正我)
- 我找不到直接操作 TCP 段的方法(没有“流”抽象)但
我是套接字服务器编程的新手,所以我需要帮助。也许有人可以分享这个问题的通用解决方案(容错协议)或描述常见的陷阱,或者提供有用的链接。
我正在 .NET 下进行开发,如果可以避免的话,我不想使用任何 P/Invoke。
I'm developing a server on C# (using *Async methods). Everything works fine, until one side violates the protocol (e.g. attack on server).
The client and server interchange messages of the following structure:
- First 4 bytes define the length (N) of the message body in bytes
- The following N bytes define the message body
If someone transmits wrong length - all comunication between this client and the server becomes unpredictable.
So the idea is to create a self-synchronizing protocol the most easy way.
I'm using the TCP protocol, so the idea is to break the message into packets and no two messages should share the same packet - this way I'll be able to ignore protocol violations and restore the communication, if something goes wrong.
I want to use the TCP for that, so the packet would be the same as TCP segment. But there are few catches:
- the MTU (which defines the MSS) could differ and there is no predefined value for the buffer size I could use (correct me if I'm wrong)
- I couldn't find the way to manupulate TCP Segments directly (without "stream" abstraction) yet
I'm new to socket server programming, so I need help. Maybe someone can share the common solution to this problem (the fault-resistant protocol) or describe the common pitfalls, or maybe provide useful links.
I'm developing under .NET and I don't want to use any P/Invokes if it can be avoided.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
TCP 抽象是流的抽象,没有内置的消息边界,您不应该试图违反该抽象。
处理行为不当的客户端的主要策略是严格检查客户端提供的所有输入(例如,通常为协议级消息的允许大小设置上限)。当健全性检查表明协议已被违反时,您将停止处理错误消息。您可能还想记录错误,和/或将其报告给客户端。
如果协议违规导致您无法重新同步,那么您别无选择,只能断开客户端连接。这很好;行为不端的客户无权期望任何级别的服务。
您可以设计一个允许重新同步的协议 - 最简单的示例是在后续协议消息之间的边界处使用分隔符(分隔符本身不允许出现在消息中)。许多旧的“基于行”的互联网协议,如 FTP、SMTP 和 IRC 都是以这种方式工作的(本例中的分隔符是换行符)。
The TCP abstraction is that of a stream, with no in-built message boundaries, and you shouldn't be trying to violate that abstraction.
The main strategy for dealing with misbehaving clients is to rigorously sanity-check all the input provided by clients (for example, it is usual to set an upper bound on the allowed size of your protocol-level messages). When the sanity checks indicate that the protocol has been violated, you stop processing of the erroneous message. You may also want to log the error, and/or report it to the client.
If the protocol violation is such that you cannot resynchronise, then you have no choice but to disconnect the client. This is fine; a misbehaving client has no right to expect any level of service.
You can design a protocol that allows resynchronisation - the simplest example is to use delimiters at the boundary between subsequent protocol messages (the delimiter itself is not allowed to occur within a message). Many of the old "line-based" internet protocols, like FTP, SMTP and IRC work this way (the delimiter in this case is the newline character).
这里有两个单独的问题。
违规?
确保您的服务器安全?
您无法通过在协议处理程序中构建纠错来保护您的服务器。您需要安全的编码实践才能做到这一点。对于初学者来说,请考虑 SSL - 如果您尝试自己确保服务器安全,a)它不会,b)它将需要很长时间。
您可能会发现,一旦服务器安全,协议错误问题就更容易解决。这意味着客户端上存在编码错误,或者网络数据完整性问题。预先排除恶意会使这两个问题更容易解决。
There are two separate issues here.
violations?
secure your server?
You cannot secure your server by building error correction into your protocol handler. You need secure coding practices to do that. Look into SSL for starters - if you try to make the server secure all by yourself a) it will not be, and b) it will take a long time.
You may find that once the server is secure, the issue of protocol errors is a lot simpler to resolve. This implies either a coding error on the client, or a network data integrity problem. Ruling out malice aforethought makes either problem easier to address.
您可能想了解protobuf-c RPC 实现:
要考虑的另一件事是添加,您应该添加尝试通过非 TCP/IP(即无差错通道)执行此操作的方法是在标头和有效负载上添加 CRC 检查。
You might want to read about the protobuf-c RPC implementation:
Another thing to think about added, should you try to do this over non-TCP/IP (i.e. an error-free channel) is to add a CRC check on the header and the payload.
断开行为不当的客户端
disconnect the misbehaving client