【发布时间】:2012-12-18 05:52:42
【问题描述】:
我有一个使用标准网络套接字上的 TCP/IP 用 C++ 编写的 Web 应用程序,在 Linux 上运行。该服务对狂野而笨拙的互联网开放。
我会定期收到来自运行自动化脚本的垃圾邮件发送者的大量滥用请求。我可以检测到这些并关闭套接字。现在我只是礼貌地关闭套接字,就像对任何已完成的有效请求所做的那样,套接字库关闭如下:
close( mSocket );
但有时关闭套接字通常会通知垃圾邮件脚本套接字连接已终止,它们会立即发起另一个欺诈请求。
终止 TCP/IP 连接的最佳方法是什么,该连接会清理我系统上打开的套接字,但会使远程方挂起。那就是我想以对我来说成本最低但对他们来说成本最高的方式关闭套接字。
@尼古拉斯·威尔逊:
使用 TCP_REPAIR 似乎是个好主意。在 TCP_REPAIR 模式下关闭套接字时,不会发送 FIN 或 RST 数据包。远程插座悬空。我会尝试并报告回来。这是我的(未经测试的)代码:
if ( abuse )
{
int aux = 1;
if ( setsockopt( mSocket, SOL_TCP, TCP_REPAIR, &aux, sizeof( aux )) < 0 )
reportError( "Tried to do a rude socket close... but could not turn on repair mode.\n" );
}
close( mSocket );
如果这可行,我会报告。 (@edit:下面的测试答案)
@“让套接字保持打开”的想法:
这可行,但不是最佳的。攻击者有能力用打开的套接字使您的系统饱和。每个请求都会创建一个保持打开状态的新套接字。使用 DOS 攻击,您最终会耗尽套接字。
那么管理打开的套接字也有问题:
- 只是不要关闭它。开放式套接字永远存在。攻击者的成本:高 - 他们没有鳍。对我来说成本:更高。我所有的文件描述符最终都会被使用。
- 为每个套接字生成一个线程以休眠 10 分钟,然后关闭套接字。攻击者的成本:高 - 他们没有鳍。对我来说成本:更高。虽然我最终确实关闭了套接字,但对于每个请求,我的套接字使用时间都比攻击者长,而且我有一个线程的开销。
- 产生一个线程来处理所有被滥用的套接字过期。攻击者的成本:高 - 他们没有鳍。对我来说成本:更高。像 2 一样,许多套接字保持打开状态。管理它的单个线程的开销。代码复杂,烦人。
【问题讨论】:
-
你想要的是关闭连接而不发送 FIN。然而,这并不容易实现。我在 SO 上找到的一些已经是这样的:stackoverflow.com/questions/9925705/…
-
另一个选择是创建一个蜜罐。只是不要关闭套接字,而是让它挂很长时间。它只会占用一个套接字资源(这会是个问题吗?)。大约 10 分钟后释放它。
-
在最近的 linux 上,您可以使用套接字修复模式 (TCP_REPAIR)。然后关闭套接字;不会发送任何 FIN,所有内容都将被清除。不过有点矫枉过正。
-
如果你想阻止来自该 IP 地址的连接,你可以添加一个 iptables 规则。 IP 集是一种内核功能,旨在用于此类内容。
-
让套接字打开是次优的。
标签: c++ c sockets networking tcp