LINUX.ORG.RU

TCP connection, C++: забыть коннект, а не закрывать его.

 


0

2

Есть IP адрес, про который нам стало известно, что это кулхакеры DOS-овцы. Овцы Доса. А коннект от него мы уже приняли в приложении. И тут возникет идея «а давайте скажем TCP-стеку ядра, чтобы оно забыло запись про этот TCP коннект как будто его и не было и наш сокет тоже выкинем и закроем так, чтобы никакого FIN/RST никуда от нас клиенту не уходило». То есть, если про клиента известно, что он скотина, то пускай себе думает, что он всё ещё держит до нас коннект, а мы просто забудем про это, фигли ресурсы на чертилу тратить.

Ясно, что во взрослом мире такие задачи решаются вообще не так: если вдруг про IP-адрес стало известно, что он псина, то этот IP передаётся в списки какой-то firewall-овой машинерии перед нашим физическим сервером и там на низком уровне в DKPK-XDP-фигнях пакеты от этого IP адреса тупо забудутся как будто их не было.

Но вот допустим, мы поняли, что клиент - псина только после того, как соединение приняли. Допустим он по этому соединению нам что-то такое передал, что спалился как чертофан. И тут хочется как-то резко перестать тратить на него ресурсы, поднасрав ему заодно в отместку, авторитарно забыв это соединение и не сказав ему. Пускай ретраит, нам не жалко ваще, тем более что скоро этот IP таки может быть уйдёт в firewall. Хотя тут зло в том, что после первого же ретрая с его стороны, наше ядро, не узнав это TCP-соединение (по исходящей паре ip:port) тупо отправит ему RST. То есть, RST всё равно пойдёт. Но потом. Но цимес в том, что этот чертила может быть тоже про нас уже забыл и слать ничего не собирался, думая что мы всё ещё держим ресурсы на него.

Короче вопрос про резкое забывание TCP-соединения без отправки RST. Я чё-то там почитал про SO_LINGER, shutdown() и т.п., но это всё не то, потому что оно отправляет RST.

Ещё знаю утилиту tcpdrop, которая вроде бы не отправляет «туда» RST.

Ещё слышал про такой способ потереть из TCP стека молча инфу про коннекшн: sudo conntrack -D -s <локальный IP> -d <удалённый IP> -p tcp --sport <локальный порт> --dport <удалённый порт>

Ещё можно shutdown(), перед которым сделать такое:

sudo iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP

Но всё это какие-то внешние тулзы. Они же наверное какие-то вызовы системные дёргают? Я-то их тоже же могу дёрнуть? Вряд-ли без рута. Так чё делать?

Наверное нормальным решением будет написать на сишечке внешнее злое приложение, запустить его от рута на нашей машине. Пусть слушает UDP 127.0.0.1:44444. В это приложение по UDP наше «рабочее» приложение будет стучать доносы, а то приложение уже системные вызовы в ядро делать типа вот того conntrack -D?



Последнее исправление: lesopilorama (всего исправлений: 6)

У злого клиента содеинение имеет свой локальный IP и адрес порта. Банишь его на файрволе на INPUT -s … –sport … и OUTPUT -d … –dport … и потом закрываешь сокет.

Удаление из коннтрака не закрывает сам сокет.

no-dashi-v2 ★★★
()