我有一个使用标准网络套接字上的 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 一样,许多套接字保持打开状态。管理它的单个线程的开销。代码复杂,烦人。