The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

How To Make a Transparent WWW Proxy (c) http://www.lexa.ru (proxy cisco squid redirect acl nat)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: proxy, cisco, squid, redirect, acl, nat,  (найти похожие документы)
From : Alex Tutubalin <lexa@home.lexa.ru> Subj : How To Make a Transparent WWW Proxy (c) http://www.lexa.ru ------------------------------------------------------------------------------- <b>(c) http://www.lexa.ru<;/b> <h4 align=center>How To Make a Transparent WWW Proxy</h4> <b>Введение в проблему</b><p> В некоторый момент я обнаружил, что большую часть входящего траффика в моей сети составляет WWW. При этом клиенты не пользовались Proxy, хотя это заметно ускорило бы их работу (hit ratio составляет у нас почти 50%), а пройтись по всем клиентам и поправить настройки их броузеров я не имел возможности (да и желания тоже). Думаю, подобные проблемы часто возникают и у ISP, когда поправить настройки клиентов просто нельзя. <p> Почитав Squid'овский <a href="http://squid.nlanr.net/Squid/FAQ/FAQ.html">FAQ</a>, я нашел там описание того, как заставить клиентов насильно использовать Proxy, проблема заключалась только в том, что предложенный способ не работал. С другой стороны, я знал, что в <a href="http://www.radio-msu.net">RadioMSU</a> таки заставили работать всех своих клиентов через Proxy.<br> После консультации с Ярославом Тихим все стало на свои места и окончательное решение было сделано за пару часов. <p> <b>Как это у меня работает</b><p> Действующие лица и исполнители: <ul> <li>Роутер Cisco 2511 производства <a href="http://www.cisco.com">Cisco Systems</a>. К нему подключены все клиенты (локальная сеть на Ethernet и клиенты по Dialup), внешний канал на Demos тоже включен туда же. Для простоты представим, что LAN имеет адреса/маску 192.168.1/24, а dialup-клиенты - 192.168.2/24. <li>Машина на которой установлен кэширующий proxy - Pentium-200, 64M RAM, 8Gb дисков. Работает под управлением <a href="http://www.freebsd.org">FreeBSD 2.2.5</a>. На машине установлен <a href="http://coombs.anu.edu.au/ipfilter/">IPFilter 3.2.3</a> и <a href="http://www.nlanr.net/Squid">Squid 1.NOVM.20</a>. Для простоты изложения, представим, что адрес этой машины - 192.168.1.1 </ul> <p> <b>Настройки</b> <dl> <dt>На Cisco</dt> <dd>Нужно завернуть все транзитные пакетики с destination eq 80 на Proxy. Это делается примерно так: <pre> ! Prevent loops access-list 101 deny tcp host 192.168.1.1 any eq 80 ! All other clients: access-list 101 permit tcp 192.168.1.0 0.0.0.255 any eq 80 access-list 101 permit tcp 192.168.2.0 0.0.0.255 any eq 80 ! Route-map route-map forced-proxy permit 10 match ip address 101 set ip next-hop 192.168.1.1 ! ! Интерфейсы: ! LAN interface Ethernet 0 ip policy route-map forced-proxy ! ! Dialup interface Group-Async 1 group-range 1 16 ip policy route-map forced-proxy </pre> </dd> <dt>На машине с proxy</dt> <dd> Первым делом нужно завернуть приходящие на 80-й порт пакеты на proxy. Предполагая, что proxy работает на порту 3128, это делается как-то так: <pre> ipnat -f - &lt;&lt;EOM rdr ed0 192.168.1.1/32 port 80 -&gt; 192.168.1.1 port 80 rdr ed0 0.0.0.0/0 port 80 -&gt; 192.168.1.1 port 3128 EOM </pre> Первое правило позволяет работать локальному WWW-серверу - он будет продолжать получать свои пакетики. Вторая строчка перенаправит все остальные пакеты с destination port 80 на локальный Squid. <p> В <b>squid.conf</b> пишутся строчки вида <pre> httpd_accel www.your.domain 80 httpd_accel_with_proxy on httpd_accel_uses_host_header on </pre> В <a href="http://squid.nlanr.net/Squid/FAQ/FAQ.html">FAQ</a> рекомендовано вместо имени сервера в строчке httpd_accel писать слово <b>virtual</b>. Это - неверно, во всяком случае для Squid-1.NOVM.18..20. Проблема в том, что в этом режиме Squid определяет destination server по вызову getsockname(2), однако этим вызовом он может получить только один из своих адресов, а это явно не подходит к условиям задачи. </dl> Получившаяся конструкция работает по такой вот схеме (я рисовал эту картинку минут 10 и хотя она тут почти не нужна, не пропадать же добру):<br> <!-- img src="proxy.gif" width=640 height=292 align=center alt="Data Flow" --> <p> <b>Улучшения</b><p> При такой настройке, адрес реального сервера к которому обращается пользователь будет браться из заголовка <b>Host:</b> HTTP-запроса. Для подавляющего большинства клиентов этого достаточно - все сколько-нибудь распространенные броузеры этот заголовок ставят. Однако хочется большего.<p> В-принципе, можно было бы написать отдельную маленькую программу (вместо proxy), которая спрашивала бы у <b>IPFilter</b> реальный destination-address пакета, формировала бы заголовок <b>Host:</b> и отдавала бы все это кэширующему proxy. Однако такой подход имеет свои недостатки - в логах Squid будут только локальные адреса и сопоставить, скажем, Hit Ratio с конкретным клиентом будет непросто. Я пошел по другому пути и встроил необходимую функциональность прямо в Squid. Патч для версии 1.NOVM.20 вы можете взять прямо отсюда ( <a href="squid-1.NOVM.20.ipfilter.diff">для версии 1.NOVM.20</a>, <a href="squid-1.NOVM.22.ipfilter.diff">для версии 1.NOVM.22</a>). (<i>Необходимые замечания:</i> Патч предполагает, что *.h-файлы от ipfilter лежат у вас в /sys/netinet, а все прочие добавленные includes необходимы на FreeBSD 2.2.x, а про прочие системы я не в курсе). <p> После установки этого патча, Squid начнет понимать директиву httpd_accel_uses_ipfilter_redirect в конфигурационном файле. Использовать ее нужно так: <pre> httpd_accel_uses_ipfilter_redirect on </pre> И еще одно замечание - для пользователя с правами которого работает squid файл /dev/ipnat должен быть доступен на чтение. <p> В squid 2.x эта функциональность присутствует, если запускать <code>configure --enable-ipf-transparent</code>, при этом никаких дополнительных директив не нужно, это включено по умолчанию. <p> После всех этих изменений все работает и без заголовка Host. Правда требование, чтобы клиент был HTTP-1.x (а не HTTP/0.9) остается, но уж HTTP/0.9 клиентов я вообще очень давно не встречал. <p> <b>Возможные проблемы</b><p> Возможные проблемы связаны с ICMP-сообщениями 'packet too big'. Дело тут вот в чем. Допустим, между HTTP-Proxy и клиентом есть линк с маленьким MTU, при этом и клиент и proxy живут на media с большим MTU. Представим, что proxy начинает отвечать клиенту с каким-то размером пакета, который не пролезет через этот тонкий линк. Ipnat подменит source-address у этого пакета на IP-address сервера к которому обращался клиент. Если на пути встретится слишком маленький MTU, то ICMP-сообщение об этом уедет на какой- нибудь www.microsoft.com, которому он совершенно ни к чему.<p> Идея лечения понятна - завернуть на той же Cisco все ICMP-пакеты на хост с WWW-proxy, там их проверять на предмет соответствия с какой-то строчкой из таблицы трансляции Ipnat, все которые "неправильные" отдавать прямо местному TCP-стеку, все прочие - отсылать дальше (можно при этом подменять у них source address на какой-то левый). Это теория. До практики у меня руки пока не дошли за полной ненадобностью - у меня все клиенты имеют MTU 1500.

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

Обсуждение [ RSS ]
  • 1, Eugene (??), 15:48, 27/01/2006 [ответить]  
  • +/
    Помоему ошибка есть, надо:
    httpd_accel_port 80
    httpd_accel_host www.my.domain
     

     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру