【问题标题】:Protocol error resistant socket server协议防错套接字服务器
【发布时间】:2011-09-26 20:55:04
【问题描述】:

我正在 C# 上开发服务器(使用 *Async 方法)。一切正常,直到一方违反协议(例如攻击服务器)。

客户端和服务器交换以下结构的消息:

  1. 前 4 个字节定义消息正文的长度 (N),以字节为单位
  2. 以下 N 个字节定义消息正文

如果有人传输了错误的长度 - 此客户端和服务器之间的所有通信都将变得不可预测。

所以这个想法是创建一个最简单的自同步协议。

我正在使用 TCP 协议,所以我的想法是将消息分成数据包,并且没有两条消息应该共享同一个数据包 - 这样我就可以忽略协议违规并恢复通信,如果出现问题错了。

我想为此使用 TCP,因此数据包将与 TCP 段相同。但是有几个问题:

  • MTU(定义 MSS)可能不同,并且我可以使用的缓冲区大小没有预定义值(如果我错了,请纠正我)
  • 我还没有找到直接操作 TCP 段的方法(没有“流”抽象)

我是套接字服务器编程的新手,所以我需要帮助。也许有人可以分享这个问题的通用解决方案(抗故障协议)或描述常见的陷阱,或者提供有用的链接。

我在 .NET 下开发,如果可以避免的话,我不想使用任何 P/Invokes。

【问题讨论】:

    标签: .net sockets tcp client-server network-protocols


    【解决方案1】:

    您可能想了解the protobuf-c RPC implementation

    客户端发出一个 12 字节的标头,后跟 protobuf 编码的消息负载:

    • 方法索引(编码为 4 字节 little-endian 数字)
    • 消息长度:protobuf 编码的有效载荷的长度(编码为 4 字节 little-endian)
    • request id:客户端选择的一个值,允许它知道哪个服务器响应对应于哪个请求,在多个未完成请求的情况下)。 (4字节编码)

    服务器最终发出类似的 16 字节响应:

    • 状态代码(作为 4 字节 little-endian 数字)。以下值之一:
      0:成功
      1:服务失败(即为关闭的消息传入NULL)
      2:太多未决(客户端连接有太多未决请求)
    • 方法索引(与请求相同)
    • 消息长度(与请求相同)
    • 请求 ID(与请求相同)

    要考虑的另一件事是,如果您尝试通过非 TCP/IP(即无错误通道)执行此操作,请在标头和有效负载上添加 CRC 检查。

    【讨论】:

    • 好的,如果有人在传输中插入了一些损坏的字节,我该怎么办。例如在“方法索引”和“消息长度”之间
    • 除非您要进行比 CRC 检查更高级的内容(例如 error detection and correction coding),否则我不知道您如何检测到插入的字节不是预期的消息索引或消息长度。
    【解决方案2】:

    这里有两个不同的问题。

    1. 你如何处理协议 违规?
    2. 你打算如何 保护您的服务器?

    您无法通过在协议处理程序中构建纠错来保护您的服务器。您需要安全的编码实践来做到这一点。为初学者研究 SSL - 如果您尝试自己使服务器安全 a) 它不会,并且 b) 这需要很长时间。

    您可能会发现,一旦服务器安全,协议错误问题的解决就简单多了。这意味着客户端上的编码错误或网络数据完整性问题。预先排除恶意使这两个问题都更容易解决。

    【讨论】:

      【解决方案3】:

      断开行为不端的客户端

      【讨论】:

      • 问题在于检测异常行为和正常传输开始的地方。
      • 我认为 -1 这个有点苛刻。我会说同样的话,只要检测到任何协议错误就断开连接。不要尝试重新同步,不要尝试纠正错误,只是断开连接。因此,假设您可以判断何时收到无效数据,只需断开有问题的客户端即可。
      • 不是我 :) 但问题仍然存在 - 如何检测不当行为及其发生的位置?我应该这样做吗?
      • dip_the_coder:一般来说 - 协议消息是一些序列化的结构。服务器检查传入的字节是否可以成功反序列化,以及生成的消息是否遵循协议定义的逻辑不变量。如果违反上述任何约束 - 发回错误消息并断开连接。请注意,您应该将传输级别错误与可能具有单独定义的处理方式的业务逻辑错误区分开来。
      【解决方案4】:

      TCP 抽象是流的抽象,没有内置的消息边界,您不应该试图违反该抽象。

      处理行为不端的客户端的主要策略是严格检查客户端提供的所有输入(例如,通常设置协议级消息的允许大小上限)。当健全性检查表明协议已被违反时,您将停止处理错误消息。您可能还想记录错误,和/或将其报告给客户。

      如果协议违规导致您无法重新同步,那么您别无选择,只能断开客户端连接。这可以;行为不端的客户无权期待任何级别的服务。

      您可以设计一个允许重新同步的协议 - 最简单的示例是在后续协议消息之间的边界处使用分隔符(分隔符本身不允许出现在消息中)。许多旧的“基于行”的互联网协议,如 FTP、SMTP 和 IRC 都以这种方式工作(在这种情况下,分隔符是换行符)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-24
        • 1970-01-01
        • 2013-02-04
        • 1970-01-01
        • 2011-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多