Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Си, linux, проблема с RAW сокетами, не уходят пакеты ACK, ACK+PSH 
:(
    Опции темы
bodigard
Дата 14.5.2013, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Доброго времени суток всем !

есть модуль ядра написаный на Си который ловит пакеты на 80(http) порт, анализирует GET запрос (т.е. пропускает handshakе т.к. неизвесно к какой страничке в конечном итоге пойдёт запрос) и принимает решение дропнуть или пропустить пакет.

задача: хотелось-бы чтоб это дело не просто дропало пакет(на стороне пользователя это выглядит будто сайт просто лёг) а возвращало пользователю страничку с описанием почему доступ закрыт.

сейчас пробую сделать это дело следующим образом

1 - модуль ядра, при запрещённом GET, шлёт через netlink в userspase следующую структуру
Код

struct helper_data{
    __u32 saddr;
    __u32 daddr;
    __u16 sport;
    __u16 dport;
    __u32 SEQb;
    __u32 ACKb;
};



2 - в userspase демон эту структуру ловит и по идее(судя по анализу с wireshark) должен отправить 2 пакета, ACK (seq=ACKb, ack_seq=345) и ACK(seq=ACKb, ack_seq=345)+PSH+нагрузка, соответственно выставив адреса, порты, посчитав контрольную сумму TCP.

но пакеты с выставленный ACK и ACK+PSH не отправляются (tcpdump на сервере и wireshark на клиенте не видят их), при этом sendto ошибок не возвращает.

далее попробовал проанализировать, отправляются пакеты PSH, FIN+ACK, SIN+ACK, RST, и остальные вменяемые и невменяемые связки
при этом если saddr поставить левый и выставить seq и ack из присланой модулем структуры, то пакеты отправляются и принимаются, но при этом seq и ack_seq установленны в 1 а не в те значения что я выставил


вопщем прошу помощи в понимании как правильно послать поддельный пакет с ответом http, или возможно другой алгоритм решение поставленной задачи.

заранее благодарен за помощь !
 

да, чуть не забыл,
сервер CentOS 6.4
клиент WinXp SP3
оба в VirtualBox
PM MAIL   Вверх
rsm
Дата 15.5.2013, 03:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 999
Регистрация: 16.3.2005

Репутация: нет
Всего: 62



Цитата(bodigard @  14.5.2013,  14:11 Найти цитируемый пост)
анализирует GET запрос (т.е. пропускает handshakе

Как-то не вяжется первое со вторым.

Цитата(bodigard @  14.5.2013,  14:11 Найти цитируемый пост)
алгоритм решение поставленной задачи

И в чём же задача?
PM MAIL   Вверх
bodigard
Дата 15.5.2013, 06:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Цитата(rsm @  15.5.2013,  03:55 Найти цитируемый пост)
Цитата(bodigard @  14.5.2013,  14:11 Найти цитируемый пост)
анализирует GET запрос (т.е. пропускает handshakе

Как-то не вяжется первое со вторым.


может не так выразился ...
пропускается 3 пакета установки связи, т.е.

клиент -> SIN -> HTTP сервер
клиент <- SIN, ACK <- HTTP сервер
клиент -> ACK -> HTTP сервер

эти пакеты не несут нагрузки

а вот 4-ый пакет идёт от клиента, PSH+ACK+нагрузка, а в нагрузке как раз 
Код

GET /test/test/?item_id=16 HTTP/1.1\n
Host: www.test-sait.ru\n
...........

на основе этого и принимается решение о дальнейшей судьбе пакета


Цитата(rsm @  15.5.2013,  03:55 Найти цитируемый пост)
И в чём же задача? 

задача состоит том, чтоб при обращении к запрещённому ресурсу не просто дропнуть пакет (это сейчас успешно делается модулем ядра), но отправить(может перенаправить) пользователю страничку с уведомлением о том что ресурс закрыт.

с уважением !

Это сообщение отредактировал(а) bodigard - 15.5.2013, 06:42
PM MAIL   Вверх
rsm
Дата 15.5.2013, 20:21 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 999
Регистрация: 16.3.2005

Репутация: нет
Всего: 62



Цитата(bodigard @  15.5.2013,  08:21 Найти цитируемый пост)
задача состоит том, чтоб при обращении к запрещённому ресурсу не просто дропнуть пакет (это сейчас успешно делается модулем ядра), но отправить(может перенаправить) пользователю страничку с уведомлением о том что ресурс закрыт

Это называется "прозрачный прокси с контролем доступа", и ядро тут совершенно ни при чём. Более того, перенос такого рода софта в ядро - это не просто плохая идея, это огромнейшая дыра в безопасности. Всю описанную функциональность может покрыть например Squid. Или в совсем уж редких и экзотических случаях - Squid в связке с сервером ICAP, когда к последнему пишется модуль, принимающий решение, что и как делать с трафиком.
PM MAIL   Вверх
feodorv
Дата 15.5.2013, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Я согласен с rsm, это всё функции прокси. Тем более что не всё, что http, то 80ый порт.

Цитата(bodigard @  14.5.2013,  13:11 Найти цитируемый пост)
но пакеты с выставленный ACK и ACK+PSH не отправляются (tcpdump на сервере и wireshark на клиенте не видят их), при этом sendto ошибок не возвращает.

далее попробовал проанализировать, отправляются пакеты PSH, FIN+ACK, SIN+ACK, RST, и остальные вменяемые и невменяемые связки
при этом если saddr поставить левый и выставить seq и ack из присланой модулем структуры, то пакеты отправляются и принимаются, но при этом seq и ack_seq установленны в 1 а не в те значения что я выставил

Скорее всего ядро-то и режет Ваши поддельные пакеты... Они не выглядят для ядра достаточно естественными...


Цитата(bodigard @  14.5.2013,  13:11 Найти цитируемый пост)
модуль ядра, при запрещённом GET, шлёт через netlink в userspase следующую структуру

Смысл этого действия? Логгирование?


Цитата(bodigard @  14.5.2013,  13:11 Найти цитируемый пост)
как правильно послать поддельный пакет с ответом http

А сам модуль ядра не может такой пакет сформировать, раз уж он разбирается в HTTP запросах? И заодно отправить пакет серверу о разрыве соединения...

Это сообщение отредактировал(а) feodorv - 15.5.2013, 22:10


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
bodigard
Дата 16.5.2013, 06:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Цитата(rsm @  15.5.2013,  20:21 Найти цитируемый пост)
Всю описанную функциональность может покрыть например Squid.

верно, но в моём случае он не применим, во первых после прохождения через сквиду пакет дальше полетит с IP сквида, во вторых он просто загнётся на моём объёме трафика.

Цитата(rsm @  15.5.2013,  20:21 Найти цитируемый пост)
это огромнейшая дыра в безопасности.

если не трудно, разьясните поподробнее почему это является угрозой безопасности ?

Цитата(feodorv @  15.5.2013,  21:48 Найти цитируемый пост)
Скорее всего ядро-то и режет Ваши поддельные пакеты... Они не выглядят для ядра достаточно естественными...

тоже так думаю, но не понятно почему тогда например PSH+payload, FIN+ACK, RST, или даже совсем невменяемый SIN+FIN+ACK+PSH+RST+URG для него естественны.

Цитата(feodorv @  15.5.2013,  21:48 Найти цитируемый пост)
Смысл этого действия? Логгирование?

смысл, передать демону юзерспейса данные для формирования поддельного пакета, и да, логирование, но логирование это вторично ...

Цитата(feodorv @  15.5.2013,  21:48 Найти цитируемый пост)
 сам модуль ядра не может такой пакет сформировать, раз уж он разбирается в HTTP запросах? И заодно отправить пакет серверу о разрыве соединения...

не хотелось бы грузить ядро ещё и этим, задумка была передать минимум необходимых данных из ядра демону юзерспейса и продолжить заниматься основной задачей, а демон юзерспейcа пускай делает потехоньку все необходимые действия, т.е. отправляет http серверу пакет о разрыве (это получилось сделать), и пользователю отдаёт поддельную страничку с информацией почему туда нельзя ...

меня вот гложет, почему ядро подменяет seq и ack_seq ...

с уважением !

Это сообщение отредактировал(а) bodigard - 16.5.2013, 07:06
PM MAIL   Вверх
rsm
Дата 16.5.2013, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 999
Регистрация: 16.3.2005

Репутация: нет
Всего: 62



Цитата(bodigard @  16.5.2013,  08:36 Найти цитируемый пост)
после прохождения через сквиду пакет дальше полетит с IP сквида

Совсем не обязательно, это можно решить разными способами. Для начала стоит определиться, нужно ли это вообще.

Цитата(bodigard @  16.5.2013,  08:36 Найти цитируемый пост)
он просто загнётся на моём объёме трафика

Тогда прошу огласить требования. На Squid свет клином не сошёлся, не хватит его - найдётся что-нибудь другое. Если требования совсем уж астрономические, то здесь и ядро не поможет, только правильный выбор софта, кластеризация и балансировка нагрузки.

Цитата(bodigard @  16.5.2013,  08:36 Найти цитируемый пост)
разьясните поподробнее почему это является угрозой безопасности?

Во-первых, код ядра требует архивнимательной разработки, ибо малейшая ошибка может привести к kernel panic. Во-вторых, разбор HTTP внутри ядра даёт любому злоумышленнику возможность повысить привилегии или уронить систему, тупо отправив специально сформированный запрос. Перед тем как начать разработку, стоило бы погуглить, не пытался ли кто-нибудь уже сделать подобное. Я нашёл два проекта: TUX web server и kHTTPd, оба мертвы много лет. Что в целом вполне логично - риск создания дыры в безопасности на уровне ядра перевешивает любые другие доводы, какими бы привлекательными они ни казались. Поиграться на localhost'е из чисто академического интереса это ещё куда ни шло, но ставить такой софт на сервер не станет ни один вменяемый админ.
PM MAIL   Вверх
feodorv
Дата 16.5.2013, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(bodigard @  16.5.2013,  07:36 Найти цитируемый пост)
меня вот гложет, почему ядро подменяет seq и ack_seq ...

Трудно сказать. Может, на машине поднят NAT, он точно ничего такого не пропустит. Может, по HTTP вы ходите с сервера, тогда ядро проверит, тот ли процесс сгенерировал пакет. Может, какие-то дополнительные опции в ядре прописаны, кто знает. Может, Вы неправильно формируете пакеты)))


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
bodigard
Дата 17.5.2013, 07:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Цитата(rsm @  16.5.2013,  13:01 Найти цитируемый пост)
Совсем не обязательно, это можно решить разными способами. Для начала стоит определиться, нужно ли это вообще.

а можно пример или хотябы куда копать ?
нужно чтоб пакет от клиента прилетел на сквид, проверился им, и если всё в норме полетел дальше без какиз либо изменений, а если ресурс запрещённый то вернул страничку с описанием, а соединение разорвал.

Цитата(rsm @  16.5.2013,  13:01 Найти цитируемый пост)
Тогда прошу огласить требования. 

сейчас тестовая нагрузка 150 Мбит\с, в реальности думаю нужно чтоб обслуживал >1Гбит\с, всё это http трафик.
пробовал для решения этой задачи использовать snort (понятно что не для того он предназначен, но решить задачу он мог), но вот только он загнулся на ~5-7Мбит\с

Цитата(rsm @  16.5.2013,  13:01 Найти цитируемый пост)
Во-первых, код ядра требует архивнимательной разработки, ибо малейшая ошибка может привести к kernel panic.

совершенно согласен, потому всё сначала тестируется на виртуалке а только потом выставляется на тестовый опять-же сервер.

Цитата(rsm @  16.5.2013,  13:01 Найти цитируемый пост)
Во-вторых, разбор HTTP внутри ядра даёт любому злоумышленнику возможность повысить привилегии или уронить систему, тупо отправив специально сформированный запрос.

разбор заключается в поиске, в пакете с нагрузкой HTTP, заголовка GET и поля Host:, сравнении значений этих полей со списком запрета и на основании этой проверки принятии решение пропустить/дропнуть, если заголовка GET и/или поля Host: в нагрезке нет, то пакет просто пропускается.
из этого получается, что любой, пусть даже специально сформированный запрос, либо пройдёт проверку и полетит дальше либо отбросится.
при этом код ядра строился по принципу "минимум примочек, максимум надёжности", но 1ну примочку всё-же нужно, это какраз вернуть страничку пользователю, ибо пользователя нужно уважать smile

Цитата(rsm @  16.5.2013,  13:01 Найти цитируемый пост)
 Перед тем как начать разработку, стоило бы погуглить, не пытался ли кто-нибудь уже сделать подобное.

гуглил, и не 1н день, но того что нужно нет в природе. TUX web server и kHTTPd это веб сервера уровня ядра, и тут согласен с вами, нечего им в ядре делать. Мне-же как Вы уже поняли нужен не веб сервер и даже не прокси сервер, но нужен максимально производительный фильтр http запросов на уровне заголовка http, остальной http контент меня не интересует.


Цитата(feodorv @  16.5.2013,  13:28 Найти цитируемый пост)
Трудно сказать. Может, на машине поднят NAT, он точно ничего такого не пропустит. Может, по HTTP вы ходите с сервера, тогда ядро проверит, тот ли процесс сгенерировал пакет. Может, какие-то дополнительные опции в ядре прописаны, кто знает. Может, Вы неправильно формируете пакеты))) 

поклон Вам, натолкнули на мысль, нужно проверить, отпишусь получится или нет ...

с уважением !

Это сообщение отредактировал(а) bodigard - 17.5.2013, 07:22
PM MAIL   Вверх
bodigard
Дата 21.5.2013, 08:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Цитата(feodorv @  16.5.2013,  13:28 Найти цитируемый пост)
 на машине поднят NAT

действительно в нём было дело ...
теперь пакеты уходят и приходят, но возникла другая трудность, какое-бы ack_seq не выставил система подменяет его на случайный :(

при этом я к примеру из userspase отправляю пакет с ack_seq = htonl(457), ловлю его в ядре(просто ради проверки) в NF_INET_LOCAL_OUT или NF_INET_POST_ROUTING, и у него ack_seq тот который я выставил, но tcpdump показывает другое значение, может есть соображения как это обойти ?

Цитата(feodorv @  16.5.2013,  13:28 Найти цитируемый пост)
может, по HTTP вы ходите с сервера, тогда ядро проверит, тот ли процесс сгенерировал пакет. Может, какие-то дополнительные опции в ядре прописаны, кто знает. Может, Вы неправильно формируете пакеты))) 

по HTTP с сервера точно никуда не хожу, httpd там тоже остановлен, опции ядра не менял.
пакет формирую так
Код

    iph = (struct iphdr *) packet;

    iph->version=4;
    iph->ihl=5;
    iph->tos=0;
    iph->tot_len=htons (sizeof (struct iphdr) + sizeof (struct tcphdr));
    iph->id = htons(id);
    iph->frag_off=htons(IP_DF);
    iph->ttl = 255;
    iph->protocol = IPPROTO_TCP;
    iph->check=0;
    iph->saddr = src.s_addr;
    iph->daddr = dst.s_addr;

    tcph = (struct tcphdr *) (packet+sizeof (struct iphdr));

    tcph->source = data->dport;
    tcph->dest = data->sport;
    tcph->seq = data->ack;
    tcph->doff = 5;
    tcph->psh = psh;
    tcph->ack = ack;
//data->data_len = размер нагрузки из присланного GET
    if(ack == 1)tcph->ack_seq =  htonl(data->data_len+1);
    tcph->rst = rst;
    tcph->fin = fin;
    if(fin == 1) tcph->ack_seq = 0;
    tcph->syn = syn;

    tcph->window = htons(65534);
    tcph->check = 0;
    tcph->urg = 0;

    pseudoheader.source_addr = src;
    pseudoheader.destination_addr = dst;
    pseudoheader.zero = 0;
    pseudoheader.protocol = IPPROTO_TCP;
    pseudoheader.length = htons(DATA_SIZE - sizeof (struct iphdr));

    if ((pseudopacket = (char *) malloc (sizeof (pseudoheader)+ (DATA_SIZE - sizeof(struct iphdr)))) == NULL )
    {
        perror ("malloc");
        return 1;
    }

    memcpy (pseudopacket, &pseudoheader, sizeof (pseudoheader));
    memcpy (pseudopacket+sizeof (pseudoheader), packet + sizeof(struct iphdr), (DATA_SIZE-sizeof (struct iphdr)));

    tcph->check = checksum ((u_short *)pseudopacket, sizeof (pseudoheader) + (DATA_SIZE - sizeof(struct iphdr)));


с уважением !
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1681 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.