Иногда возникает необходимость «подружить» несколько кэширующих прокси-серверов таким образом, чтобы изменить стандартную последовательность обработки запросов с «локальный кэш, интернет» на «локальный кэш, кэш соседнего прокси-сервера, интернет».
Это может быть полезно, если каждый отдел организации имеет свой отдельный прокси-сервер, однако «наружу» все отделы выходят через один общий канал, в этом случае такое объединение кэшей соседних прокси-серверов позволит ускорить загрузку страниц и приведёт к дополнительнй экономии трафика. Также возможна ситуация, когда несколько офисов одной организации подключены к одному провайдеру, и используемый тариф предусматривает более низкую стоимость и/или более высокую скорость внутрисетевого трафика по отношению к внешнему.
Далее будет показано, как можно организовать взаимодействие двух прокси-серверов для взаимного обмена данными из их кэшей.
Начальные условия:
- Два офиса, соединённые с помощью OpenVPN;
- Прокси-сервера обоих офисов работают под управлением Ubuntu Jaunty;
- На обоих прокси-серверах установлен пакет squid (или squid3), который слушает на порту 3128.
Задача:
Настроить оба кэширующих прокси-сервера таким образом, чтобы поиск объекта производился сначала в локальном кэше, потом в кэше соседнего прокси-сервера, и только потом (если раньше объект не был найден) происходил запрос объекта из интернета.
Решение:
Будем считать, что прокси-сервера уже настроены и связаны с помощью OpenVPN, прокси-сервер A имеет адрес 192.168.10.1, а прокси-сервер B – 192.168.10.107. На обоих адресах разрешён весь трафик с «соседнего» адреса. На прокси-сервере A установлен пакет squid3, а на прокси-сервере B – squid.
Сначала рассмотрим, как же именно будут взаимодействовать прокси-сервера. Допустим, что прокси-сервер A получил запрос от клиента, первым делом он будет искать ответ на запрос у себя в кэше. Если ответ найден в кэше – он будет передан клиенту, если же нет – прокси-сервер шлёт ICP (Internet Cache Protocol)-запрос прокси-серверу B. Если ответ есть в кэше прокси-сервера B, то оригинальный HTTP-запрос пересылается на сервер B, там из кэша «достаётся» ответ, возвращается серверу A и оттуда клиенту. Если же кэш прокси-сервера B также не содержит ответа – прокси-сервер A делает запрос в интернет и возвращает клиенту отклик уже оттуда.
Принципиальной разницы между настройками squid3 и squid нет, фактически в пакете squid содержится версия squid 2.7, а в пакете squid3 – версия 3.0, являющаяся продолжением версии 2.7.
Приступаем к настройке. Для начала надо на обоих серверах разрешить ICP-запросы друг от друга. На сервере A для этого нужно в файле /etc/squid3/squid.conf найти строку:
icp_access deny all и добавить перед ней следующие строки:
acl peer_allow src 192.168.10.107 icp_access allow peer_allow Затем на сервере B в файле /etc/squid/squid,conf также нужно найти строку:
icp_access deny all и добавить перед ней строки:
acl peer_allow src 192.168.10.1 icp_access allow peer_allow Здесь в обоих случаях создаются списки доступа (ACL) с именем peer_allow, в которые входят адреса «соседних» прокси, и разрешается доступ с них на текущий сервер по ICP. По умолчанию для обработки ICP-запросов используется UDP-порт 3130, и мы не будем это менять.
Разрешив прокси-серверам доступ к друг другу по ICP (то есть фактически разрешив прокси-серверам получать информацию о наличии объектов в кэше друг у друга), перейдём, собственно, к настройке использования этой возможности.
Для этого первым делом разрешим использование прокси-серверов друг другому с помощью директивы http_access (например, добавив адреса соседних прокси в ACL localnet).
Затем используем директиву файла конфигурации cache_peer, с помощью которой настраивается взаимодействие с другими прокси-серверами.
На прокси-сервере B нужно добавить в конец файла /etc/squid/squid.conf строку:
cache_peer 192.168.10.1 sibling 3128 3130 no-digest После чего применить новую конфигурацию squid командой:
squid -k reconfigure На прокси-сервере A в файл /etc/squid3/squid.conf нужно добавить строку:
cache_peer 192.168.10.107 sibling 3128 3130 background-ping no-digest и применить новую конфигурацию командой:
squid3 -k reconfigure Отличие добавляемых строк заключено в опции background-ping, которая появилась в версии squid 3.0, и позволяет периодически в фоновом режиме проверять доступность соседнего прокси-сервера и в случае его недоступности — отключать поиск объектов в его кэше.
На этом в общем-то всё. Система уже работает, однако как быть, если один из прокси-серверов отправляет запросы не напрямую в интернет, а через «родительский» прокси-сервер? Понятно, что у нас будет две директивы cache_peer, однако как указать правильный порядок их перебора? Тут на помощь приходит опция weight директивы cache_peer, с помощью которой задаются приоритеты соседних кэшей (чем больше значение weight, тем приоритетнее кэш).
Допустим, что squid на сервере A пересылает запросы на HAVP, раотающий на localhost:8080, тогда конфигурация этого сервера примет вид:
cache_peer 192.168.10.107 sibling 3128 3130 background-ping no-digest weight=2 cache_peer 127.0.0.1 parent 8080 0 no-query no-digest weight=1 В этом случае при отсутствии файла в локальном кэше, поиск будет произведён в соседнем, и в случае отсутствия файла там – запрос будет переслан на «родительский» прокси.
На этом всё. Приятной работы!