Поиск на сайте: Расширенный поиск


Новые программы oszone.net Читать ленту новостей RSS
CheckBootSpeed - это диагностический пакет на основе скриптов PowerShell, создающий отчет о скорости загрузки Windows 7 ...
Вы когда-нибудь хотели создать установочный диск Windows, который бы автоматически установил систему, не задавая вопросо...
Если после установки Windows XP у вас перестала загружаться Windows Vista или Windows 7, вам необходимо восстановить заг...
Программа подготовки документов и ведения учетных и отчетных данных по командировкам. Используются формы, утвержденные п...
Red Button – это мощная утилита для оптимизации и очистки всех актуальных клиентских версий операционной системы Windows...
OSzone.net Видео Unix Интернет Firewall Фильтрация баннеров на Cisco RSS

Фильтрация баннеров на Cisco

Текущий рейтинг: 5 (проголосовало 3)
 Посетителей: 865 | Просмотров: 1197 (сегодня 0)  Шрифт: - +
Введение.
---------

   Как известно устройства Cisco позволяют фильтровать исходящие HTTP
   запросы (команды filter url и url-server), посылая запрашиваемые URL
   на внешний сервер для проверки. Но поддерживаются только коммерческие
   продукты фирм Websensc (http://www.websense.com/) и N2H2 (http://www.n2h2.com/).
   Но если задача только обрезать баннеры и не пустить людей на порно
   сайты, можно попытаться сделать это своими руками.


Анализ протокола.

   Был выбран продукт Sentian от N2H2, и UDP протокол. Сервер Sentian
   использует порт 4005.
   Протокол довольно простой, в нем есть 2 фазы: проверка того, что
   сервер жив и собственно проверка запрошенного URL.


Формат пакетов.

   Все передаваемые пакеты начинаются с 2-х байтного идентификатора типа.
   Следующие 4-е байта - номер пакета, в каждом запросе номер уникален, а
   в ответном пакете он совпадает с номером из запроса. Далее идут
   данные, про которые поговорим позже.


Проверка доступности сервера.

   Cisco периодически (определяется параметром timeout команды
   url-server) посылает alive запрос.

       |Длина Байт	|Описание				|Значение

       2 		идентификатор типа (запрос URL-а) 	02 03
       4 		Номер запроса 				Уникально
       14 		В alive-запросе эта часть всегда 
                        одинаковая и не используется. 		00 00 00 00 00 00 
                                                                00 00 00 01 00 01 
                                                                00 00



   Пример.

        02 03                       Идентификатор типа
        00 01 78 24                 Номер запроса
        00 00 00 00 00 00 00 00 00  Данные
        01 00 01 00 00


   Сервер на alive-request отвечает alive-response пакетом

       |Длина Байт	|Описание				|Значение

       2 		Идентификатор типа (запрос URL-а) 	03 02
       4 		Номер запроса на который отвечаем 
                        Совпадает с номером запроса
       4 		В alive-ответе эта часть всегда 	00 00 00 00
                        одинаковая. 


Пример.

        03 02                       Идентификатор типа
        00 01 78 24                 Номер запроса
        00 00 00 00                 Данные



Проверка запрошенного URL.

   Когда пользователь открывает URL, Cisco пересылает на сервер IP адрес
   и имя клиента, IP и URL запрошенного сервера.

         |Длина Байт   	|Описание				|Значение

         2          	идентификатор типа (запрос URL-а) 	02 00
         4          	Номер запроса                     	Уникально
         4          	IP клиента                       
         4          	IP запрошенного сервера          
         2          	Длинна URL с завершающим 0       
         2          	Длинна имени с завершающим 0     
         ~Переменная 	Запрошенный URL                   	Строка заканчивающаяся 0
         ~Переменная 	Имя пользователя                  	Строка заканчивающаяся 0


Пример.

        02 00                       Идентификатор типа
        00 01 78 25                 Номер запроса
        AC 12 0A 01                 IP клиента
        C2 55 22 E2                 IP сервера
        00 17                       Длина URL
        00 09                       Длина имени
        68 74 74 70 3A 2F 2F 77     Запрошенный URL: http://www.opennet.ru/
        77 77 2E 6F 70 65 6E 6E
        65 74 2E 72 75 2F 00
        73 6F 6B 6F 6C 6F 66 66     Имя пользователя: sokoloff
        00


   В ответ сервер может послать либо разрешающий, либо запрещающий пакет.
   Разрешающий пакет очень прост:

         |Длина Байт 	|Описание             		|Значение

         2        	идентификатор типа (запрос URL-а) 	00 02
         4        	Номер запроса на который отвечаем 	Совпадает с номером запроса
         4        	Ответ                             	00 00 00 00


Пример.

        02 00                       Идентификатор типа
        00 01 78 25                 Номер запроса
        00 00 00 00                 Данные


   Теперь самое интересное, запрещающий пакет.

        |Длина Байт. 	|Описание 				|Значение

        2 		идентификатор типа (запрос URL-а) 	01 02
        4 		Номер запроса на который отвечаем 	Совпадает с номером запроса
        4 		Длинна URL
        ~Переменная 	URL на который перенаправляем клиента 	Строка заканчивающаяся 0


Пример.

        01 02                       Идентификатор типа
        00 01 78 25                 Номер запроса
        00 00 00 1D                 Длина URL
        68 74 74 70 3A 2F 2F 6C     URL на который перенаправляем: http://localserver/stop.html
        6F 63 61 6C 73 65 72 76
        65 72 2F 73 74 6F 70 2E
        68 74 6D 6C 00


   Теперь клиент вместо запрошенной страницы увидит
   http://localserver/stop.html. Очень похоже на работу баерорезалки в SQUID.

Пример реализации.

   Пишем на perl простенький скрипт.

        #!/usr/bin/perl
        use IO::Socket::INET;
        use strict;


        my $REQ_ALIVE=0x0203;
        my $RES_ALIVE=0x0302;
        my $REQ_REQUEST=0x0200;
        my $RES_ACCEPT=0x0002;
        my $RES_DENIED=0x0102;

        my @banners;
        open (FILE, `/root/banners.txt`) || die "Can`t open file";
        while(){
           chomp;
           push(@banners, $_);
        }
        close FILE;
        &main;

        sub checkurl{
           my $url=$_[0];
           foreach (@banners){
              if ($url=~/$_/i,) { return `http://localserver/stop.html`};
           };
           return ``;
        };

        sub main{
           my $socket= IO::Socket::INET->new(Proto=>`udp`, LocalPort=>4005);
           my $request;
           while ($socket->recv($request, 4096)){
              my($code,$id,$data)=unpack("nNa*", $request);
              if ($code==$REQ_ALIVE) {
                 $socket->send(pack("nNN",$RES_ALIVE,$id,0));   # Посылаем ответ, что мы живые
              }
              elsif($code==$REQ_REQUEST){
                 my($cl_ip1,$cl_ip2,$cl_ip3,$cl_ip4, $serv_ip1,$serv_ip2,$serv_ip3,
            $serv_ip4, $url_len, $name_len, $url, $name)=unpack("CCCCCCCCnnZ*Z*",$data);
                 if (my $replace=&checkurl($url)) {
                        print STDERR "$replace\n";
                $socket->send(pack("nNN",$RES_DENIED,$id,length("$replace\x00")) . 
              "$replace\x00");  # В ответе посылаем URL куда перенаправить.
                 }
                else{
                  $socket->send(pack("nNN",$RES_ACCEPT,$id,0));     # Посылаем ответ, что можно
                };
             };
           };
        };


   В данном примере проверяется только URL ($url), но можно проверять IP
   сервера($serv_ip1 - $serv_ip4), IP клиента ($cl_ip1 - $cl_ip4), имя
   клиента ($name).

   На Cisco выполняем команды:

        url-server (inside) vendor n2h2 host 192.168.0.2 port 4005 timeout 5 protocol UDP
        filter url http 0.0.0.0 0.0.0.0 0.0.0.0 0.0.0.0 allow


   Здесь 192.168.0.2 - адрес машины где работает скрипт.

   Вот и все.

   2004. Соколов Александр. sokoloff@sendmail.ru


Иcточник: http://www.opennet.ru  •  Опубликована: 05.03.2005
Нашли ошибку в тексте? Сообщите о ней автору: выделите мышкой и нажмите CTRL + ENTER
Теги:  


Оценить статью:
Вверх
Комментарии посетителей
Комментарии отключены. С вопросами по статьям обращайтесь в форум.