Jump to content
Калькуляторы

А есть ли возможность задавать общий шейпер на подсеть? (т.е. у абонента "серые" адреса /29, единая "труба" на все адреса)

Share this post


Link to post
Share on other sites

Оказалось, что мини-вебсервер не выдерживает потока подключений. Переделал с POE.

Патч по сравнению с предыдущей версией: http://dl.dropbox.com/u/12495607/web_auth_v5_to_v6.patch .

Патч для ванильной версии (предпочтительней): http://dl.dropbox.com/u/12495607/web_auth_v6.patch .

Share this post


Link to post
Share on other sites

Оказалось, что мини-вебсервер не выдерживает потока подключений. Переделал с POE.

Патч по сравнению с предыдущей версией: http://dl.dropbox.com/u/12495607/web_auth_v5_to_v6.patch .

Патч для ванильной версии (предпочтительней): http://dl.dropbox.com/u/12495607/web_auth_v6.patch .

 

Почему бы этот проэкт не разместить где нибудь типа github.com?

Share this post


Link to post
Share on other sites

Оказалось, что мини-вебсервер не выдерживает потока подключений. Переделал с POE.

Патч по сравнению с предыдущей версией: http://dl.dropbox.com/u/12495607/web_auth_v5_to_v6.patch .

Патч для ванильной версии (предпочтительней): http://dl.dropbox.com/u/12495607/web_auth_v6.patch .

 

Почему бы этот проэкт не разместить где нибудь типа github.com?

Я уже думал. Скорее на bitbucket.

Ну, это если буду развивать дальше.

Share this post


Link to post
Share on other sites

http://dl.dropbox.com/u/12495607/web_auth_v7.patch

Следующая версия. Исправлена ошибка, из-за которой из таблицы web_auth не удалялись записи (спасибо Олегу за подсказку). Обязательно пересобрать модуль ядра!

 

Новости: у нас с Олегом разное видение того, как должна быть реализована поддержка веб-авторизации (он считает - редирект в модуле ядра; я, в принципе, не против, но не умею), поэтому в основной ветке веб-авторизации в таком виде не будет. Но изменения не слишком большие, поэтому смысла выносить это всё в отдельный проект я не вижу. Пусть будут патчи.

Edited by Abram

Share this post


Link to post
Share on other sites

ИМХО стоит сделать ветку-форк, и синкать ее с основной... Намного проще чем накладывать патчи, конфликты разрешаются автоматом, а где не разрешились - в коде ручками правятся спорные места. Хотя для такого небольшого по объему проекта разница еще не так заметна.

Share this post


Link to post
Share on other sites

http://dl.dropbox.com/u/12495607/web_auth_v7.patch

Следующая версия. Исправлена ошибка, из-за которой из таблицы web_auth не удалялись записи (спасибо Олегу за подсказку). Обязательно пересобрать модуль ядра!

 

Новости: у нас с Олегом разное видение того, как должна быть реализована поддержка веб-авторизации (он считает - редирект в модуле ядра; я, в принципе, не против, но не умею), поэтому в основной ветке веб-авторизации в таком виде не будет. Но изменения не слишком большие, поэтому смысла выносить это всё в отдельный проект я не вижу. Пусть будут патчи.

 

Могу подсказать как редиректить из ядра. Сам долго придумывал для биллинга своего.

Это кусок от ядерного таргет модуля для iptables

Вот код:

static unsigned int
mark_redir_target(struct sk_buff *skb, const struct xt_action_param *par){
 const struct xt_mark_redir_info *info = par->targinfo;
 struct sk_buff *new_skb;
 unsigned int offset;
 unsigned int skb_len_in_mem;
 unsigned int headlen;

 //защита от петли - когда сгенерированый нами пакет попадает опять к нам
 if(skb->mark == info->mark){
   //просто игнорим его. пусть дальше по списку правил идет.
   return XT_CONTINUE;
 }
 //создаем новый skb. Нельзя использовать skb_copy так как оно лишнее
 //копирует и netif_rx не работает из за этого.
 skb_len_in_mem=skb->tail - skb->head;
 new_skb = alloc_skb(skb_len_in_mem, GFP_ATOMIC);
 //проверяем что он создался
 if(!new_skb){ return NF_DROP; }
 //получаем разность в адресах между вновь создаваемым и оригинальным skb
 offset=new_skb->head - skb->head;
 //получем длину head
 headlen=skb->data - skb->head;
 //резервируем в новом skb место для блока head
 skb_reserve(new_skb, headlen);
 //выделяем место для блока data
 skb_put(new_skb, skb->len);
 //копируем из skb блок head+data
 //странные параметры да? я это взял с skb_copy. Если присмотреться то оно работает :)
 if(skb_copy_bits(skb, -headlen, new_skb->head, headlen + skb->len)){ BUG(); }
 //копируем длины
 new_skb->mac_len=skb->mac_len;
 new_skb->hdr_len=skb->hdr_len;
 //указатели на x_headers
 new_skb->transport_header=skb->transport_header+offset;
 new_skb->network_header=skb->network_header+offset;
 new_skb->mac_header=skb->mac_header+offset;
 //индекс устройства dev
 new_skb->skb_iif=skb->skb_iif;
 //устройство с которого прилетел пакет
 new_skb->dev = skb->dev;
 //протокол
 new_skb->protocol = skb->protocol;
 //не нужно считать контрольную сумму
 new_skb->ip_summed = CHECKSUM_UNNECESSARY;
 //маркируем
 new_skb->mark=info->mark;
 //выбрасываем вновь созданный skb в ядро
 //как будно это пакет принятый сетевухой
 netif_rx(new_skb);
 //дропаем оригинальный пакет
 return NF_DROP;
}//----------------------------------------------------------------------------------------

 

Этот изврат нужен потому что у меня модуль биллинга сидит в mangle FORWARD а REDIRECT можно делать только из PREROUTING.

Вот я и перевыкидываю пакеты идущие на порт 80 от неавторизированых пользователей в начало и при этом они у меня уже промаркированые. А дальше

iptables -I PREROUTING -p tcp -m mark --mark 0x9876 -j REDIRECT --to-ports 8091

И все работает. На 8091 порту сидит tcp сервер который делает редирект уже на страничку статистики.

Share this post


Link to post
Share on other sites

adron2,

Спасибо, передал Олегу, может сделает. Для меня это, увы, - тарабарщина.

Share this post


Link to post
Share on other sites

Редирект - да, только в прероутинге. Но ведь DNAT есть везде - и не надо чесать ногой за ухом, копируя пакет и засылая его на себя же. Да и по функционалу DNAT кошернее ИМХО - редиректить можно куда угодно, а не на локальный порт. Ведь не факт, что на насе будет поднят веб-сервер :)

Share this post


Link to post
Share on other sites

Редирект - да, только в прероутинге. Но ведь DNAT есть везде - и не надо чесать ногой за ухом, копируя пакет и засылая его на себя же. Да и по функционалу DNAT кошернее ИМХО - редиректить можно куда угодно, а не на локальный порт. Ведь не факт, что на насе будет поднят веб-сервер :)

А что по вашему DNAT работает не только в PREROUTING?

SNAT да.. В postrouting запросто. А вот DNAT нет. Или я ошибаюсь?

 

А веб сервер на насе очень простенький работает. Там около 100 строчек на Си. Его задача только сделать редирект на страничку статистики и все.

 

P.S. С приведенным выше кодом можно и DNAT сделать вместо REDIRECT. Все одно будет работать.

Edited by adron2

Share this post


Link to post
Share on other sites

А есть ли возможность задавать общий шейпер на подсеть? (т.е. у абонента "серые" адреса /29, единая "труба" на все адреса)

Кто-нибудь подскажет?

Share this post


Link to post
Share on other sites

Да и по функционалу DNAT кошернее ИМХО - редиректить можно куда угодно, а не на локальный порт. Ведь не факт, что на насе будет поднят веб-сервер :)

Я специально редирект делаю именно на локальный порт.

Если делать DNAT на внешний адрес - не факт, что ответ пройдет через тот же маршрутизатор, и как следствие - может прийти не оттуда.

Веб-сервер я сунул прямо в ISGd, но все, что он делает - отдает клиенту 307 (вроде как) с адресом страницы авторизации. 307 отдавать надо все равно (иначе браузер может некорректно воспринять подмену - например, закешировать вместо гугла страницу с авторизацией, да и неправильно это, в конце-концов), так почему бы не убить двух зайцев сразу?

Edited by Abram

Share this post


Link to post
Share on other sites

Хм, таки ошибся, DNAT есть в OUTPUT... Но все равно метод выглядит извращением. Как минимум - копирование всего skb с данными, причем - вручную (а не через skb_clone/skb_copy) выглядит коряво, думается, должна быть более красивая альтернатива...

 

Кстати, классы траффика бы сделать не только по подсетям, а еще и по меткам - вообще хорошо бы было...

Edited by NiTr0

Share this post


Link to post
Share on other sites

Хм, таки ошибся, DNAT есть в OUTPUT... Но все равно метод выглядит извращением. Как минимум - копирование всего skb с данными, причем - вручную (а не через skb_clone/skb_copy) выглядит коряво, думается, должна быть более красивая альтернатива...

 

Кстати, классы траффика бы сделать не только по подсетям, а еще и по меткам - вообще хорошо бы было...

 

OUTPUT только для локальных пакетов. То есть тех которые породил сам роутер. А вы гляньте skb_close/skb_copy...там тоже самое делается только + еще куча всего ненужного. Я ненужное убрал и оставил только самое необходимое чтобы работало.

Причем это же только первый пакет на 80 порт от неавторизированого пользователя. Остальные пакеты уже пойдут в обход модуля редиректинга. Так что там оверхед при клонировании пакета минимальный.

 

P.S.

Есть еще другой путь. Можно переназначить dst тобиш out interface и пакет выйдет наружу через нужный нам интерфейс(например ipip tun к биллингу). А на другом конце этого интерфейса должен сидеть роутер(биллинговый сервер с включенным NAT) который делает что то типа iptables -t nat -I PREROUTING -i tun0 -j REDIRECT...

Тогда вообще исходный пакет клонировать не нужно. Но мне нужно было именно чтобы NAS делал редирект поэтому от такого метода отказался.

Share this post


Link to post
Share on other sites

OUTPUT только для локальных пакетов.

Угу, знаю.

 

А вы гляньте skb_close/skb_copy...там тоже самое делается только + еще куча всего ненужного. Я ненужное убрал и оставил только самое необходимое чтобы работало.

skb_clone не копирует собссно тело пакета, правда насколько он применим здесь - сказать не могу. Да и "ненужное" - вы уверены, что оно действительно ненужное, и что в скажем некой 3.20 ветке ядра в skb не появится новое поле - из-за чего ваш модуль придется опять править? :)

ИМХО - правильнее юзать библиотечные функции все же...

Share this post


Link to post
Share on other sites

OUTPUT только для локальных пакетов.

Угу, знаю.

 

А вы гляньте skb_close/skb_copy...там тоже самое делается только + еще куча всего ненужного. Я ненужное убрал и оставил только самое необходимое чтобы работало.

skb_clone не копирует собссно тело пакета, правда насколько он применим здесь - сказать не могу. Да и "ненужное" - вы уверены, что оно действительно ненужное, и что в скажем некой 3.20 ветке ядра в skb не появится новое поле - из-за чего ваш модуль придется опять править? :)

ИМХО - правильнее юзать библиотечные функции все же...

 

В моем модуле копируются только необходимые поля. Если в skb добавят еще какое то поле не думаю что оно будет таким уж и необходимым. А модуль всяко прийдется править под новые ядра. Они там постоянно что то меняют. Тот же обработчик пакетов для таргет модуля(описание функии) постоянно меняется.

P.S. Если использовать skb_copy вместо того что у меня ядро улетает в панику :)

Edited by adron2

Share this post


Link to post
Share on other sites

Unable to sweep ne queue (Connection refused)

из-за чего может быть вызвана?

Share this post


Link to post
Share on other sites

grep -R "sweep ne queue" <путь к папке где исг> и читать потом из найденного.

Share this post


Link to post
Share on other sites

   if (!defined($prev_md5) || $curr_md5 ne $prev_md5) {
       my %pfx_list;

       my $err_str = "";
       my %rep;

       do_log("info", "Refreshing traffic classification table");

       seek(FP, 0, 0);
       while (<FP>) {
    chomp; s/^\s+//;
    if (/^([^#]\S+)\s+(.+)\/([0-9]{1,2})/) {
	my $mask = ($3 ? ~((1<<(32 - $3))-1) : 0);
	my $prefix = $2 . "/" . ISG::long2ip($mask);

	if ($3 > 32 || ISG::ip2long($2) & ~$mask) {
	    $err_str = "bad prefix: '$2/$3'";
	} elsif ($pfx_list{$prefix}) {
	    $err_str = "duplicate prefix: $prefix";
	} else {
	    $pfx_list{$prefix} = $1;
	    $tc_names->{$1}++;
	}
    } elsif (length($_) && !(/^#/)) {
	$err_str = "bad line format: '$_'";
    }
    if (length($err_str)) {
        do_log("err", "Error in $cfg{tc_file}, " . $err_str);
        return;
    }
}

if (isg_send_event($sk, { 'type' => ISG::EVENT_NE_SWEEP_QUEUE }, \%rep) < 0) {
    do_log("fatal", "Unable to sweep ne queue ($!)");
    exit(254);
}

из найденного куска я понимаю у меня не понимает классы трафика ?

Share this post


Link to post
Share on other sites

Какая то ошибка при перезагрузке tc. Не может подключится к модулю с помощью сокета. Он у вас точно загружен через lsmod ?

Share this post


Link to post
Share on other sites

Поможите люди добрые :)

Пытаюсь собрать ядрёный модуль.

поставил slackware 13.37 i486 с нуля

скачал и установил iptables 1.4.9 с исходников.

configure прошёл нормально без ошибок

 

root@isg:/usr/src/lISG-0.11.3-alpha/kernel# make

echo "" > build.h

printf "/* Compilation date.\n * Written by Makefile (userspace) */\n#define _BUILD_DATE \"%s %s\"\n" `date +'%F %T'` > build.h

make -C /lib/modules/2.6.37.6-smp/build M=/usr/src/lISG-0.11.3-alpha/kernel modules

make[1]: Entering directory `/usr/src/linux-2.6.37.6'

CC [M] /usr/src/lISG-0.11.3-alpha/kernel/isg_main.o

/usr/src/lISG-0.11.3-alpha/kernel/isg_main.c:806:15: warning: 'struct xt_target_param' declared inside parameter list

/usr/src/lISG-0.11.3-alpha/kernel/isg_main.c:806:15: warning: its scope is only this definition or declaration, which is probably not what you want

/usr/src/lISG-0.11.3-alpha/kernel/isg_main.c: In function 'isg_tg':

/usr/src/lISG-0.11.3-alpha/kernel/isg_main.c:812:43: error: dereferencing pointer to incomplete type

/usr/src/lISG-0.11.3-alpha/kernel/isg_main.c: At top level:

/usr/src/lISG-0.11.3-alpha/kernel/isg_main.c:960:5: warning: initialization from incompatible pointer type

make[2]: *** [/usr/src/lISG-0.11.3-alpha/kernel/isg_main.o] Error 1

make[1]: *** [_module_/usr/src/lISG-0.11.3-alpha/kernel] Error 2

make[1]: Leaving directory `/usr/src/linux-2.6.37.6'

make: *** [all] Error 2

Edited by chixpyx

Share this post


Link to post
Share on other sites

Други, а кто как полисит? Какой бёрст, на каких ядрах?

У меня при разбросе скоростей 5-50 мбит никак не удаётся подобрать вменяемые значения, чтобы и скорость не скакала с разбросом в 50% выделяемой полосы, и спидтесты и яндексы показывали необходимую скорость, и при длительных закачках эта скорость была стабильна и верна =\

Share this post


Link to post
Share on other sites

Нужно было развернуть LISG для одного проекта.

Все завелось, все взлетело. Схема Static NAT 1-1.

#ip route show

blackhole 1*.2*.255.242

NAT-IP ушел в blackhole, но как бы понятно.

 

в quagga настроил редистрибьюцию kernel blackhole

но почему когда я пытаюсь пинговать с компа где стоит lisg

# ping 1*.2*.255.242

connect: Network is unreachable

 

и создается впечатление что нат все таки не работает, т.к. с внешнего интерфейса пинг так же не проходит на 1*.2*.255.242

хотя сессия approved и в iptables -t nat куча всего :)

Share this post


Link to post
Share on other sites

и не работает, т.к. с внешнего интерфейса пинг так же не проходит на 1*.2*.255.242

хотя сессия approved и в iptables -t nat куча всего :)

Пройдите глазами полностью по таблице -t nat задним ходом от конечного /32 на наличие нужных правил dnat.

У меня была проблема на новом ядре не создавались правила dnat skeleton для ip ***.***.***.***, а вот для ***.***.***.** всё создавалось. Пришлось кое-что в коде поправить.

С локального хоста естественно ничего не будет пинговаться, так как роут в blackhole.

Edited by alexmern

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now