У меня есть веб-приложение, написанное на С++ с использованием TCP/IP через стандартные сетевые сокеты, работающие в Linux. Услуга открыта для дикого и woolly интернета.
Периодически я получаю всплески оскорбительных запросов от спамеров, запускающих автоматические скрипты. Я могу обнаружить их и закрыть сокет. Прямо сейчас я просто делаю вежливый сокет близко, как если бы я сделал с любым действительным запросом, который был завершен, при этом сокет lib закрывается следующим образом:
close( mSocket );
Но иногда закрытие сокета обычно уведомляет спам script о завершении соединения сокета и немедленно инициирует другой мошеннический запрос.
Каков наилучший способ прекратить соединение 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, было открыто много гнезд. Накладные расходы одного потока для управления им. Сложность кода, раздражение.