четверг, 29 мая 2008 г.

Разделяем поток на два канала для squid

Мы все хотим экономить. В том числе и на Интернет-трафике. Типичная ситуация: организация из 30+ человек и 1 скоростной (и, соответственно, помегабайтный) канал в Интернет, отсутствие безлимитного подключения (потому что скорость его не позволит нормально работать никому). Итог: большие расходы на интернет-трафик.
Конечно, самый простой выход - считать трафик и выделять каждому пользователю по потребности. Иногда от этого страдает больше всего системный администратор. А он тут не при чем.
Итак, для решения проблемы решено подключить второй безлимитный канал на небольшой скорости. И отправить туда весь несущественный, но составляющий большую часть, трафик: картинки, видео, флешки и т.д.

Нам необходимо: сервер я двумя интерфейсами (у меня для лабы eth0 и tun1), работающий squid, фаервол iptables и пакет route2.
Пусть на eth0 (скоростной канал) IP 192.168.0.2/255.255.255.0 шлюз 192.168.0.1
tun1 (медленный) 172.16.1.2/255.255.255.252 шлюз 172.16.1.1 тип P-t-P

eth0 был настроен и работает, добавляем настройки для tun1
Прежде всего необходимо создать второй равнозначный маршрут по уполчанию. Для этого нужно создать вторую таблицу маршрутизации (потом нужный трафик мы перекинем в неё).
ip route flush table 2
ip route show table main \
>| grep -Ev ^default \
>| while read ROUTE ; \
> do ip route add table 2 $ROUTE; \
> done
ip route add default via 172.16.1.2 table 2

(или dev tun1, так как канал P-t-P)

Теперь перехватываем исходящие с IP 172.16.1.2 пакеты и:
- средствами iptables маркируем его:
iptables -t mangle -A OUTPUT -s 172.16.1.0/30 -j MARK --set-mark 2
- средствами route2 отправляем в таблицу 2
ip rule add fwmark 2 table 2
С помощью tcpdump можно посмотреть результат.

Средствами squid можно только назначить исходящий адрес, поэтому такие ухищрения. Вот кусок /etc/squid/squid.conf:

acl SLOW_DOWN urlpath_regex -i \.exe$
acl SLOW_DOWN urlpath_regex -i \.avi$
acl SLOW_DOWN urlpath_regex -i \.mp3$
acl SLOW_DOWN urlpath_regex -i \.jpg$
acl SLOW_DOWN urlpath_regex -i \.gif$
acl SLOW_DOWN urlpath_regex -i \.swf$
acl SLOW_DOWN urlpath_regex -i \.png$

tcp_outgoing_address 172.16.1.1 SLOW_DOWN
tcp_outgoing_address 192.168.0.2


Способ кривой, так как дифференцирует только на основании строки запроса. То есть txt или doc файл размером 700 мегабайт проскочит в быстрый канал. address.com/file - туда же вне зависимости от типа. Но address.com/fille.without.swf - в медленный.

2 комментария:

tierpunk комментирует...

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

Евгений комментирует...

Я когда делал два маршрута по умолчанию с одинаковой метрикой использовался только тот маршрут, который был добавлен последним (проверка - по tcpdump и ping -I {interface}). Он заворачивал пакеты, посланные с первого интерфейса на второй, игнорируя при этом второй маршрут. Поэтому и пришлось сделать вот такую штуку с маршрутами в двух таблицах и раскидыванием пакетов по этим таблицам путём маркировки.