System administration
31 August 2010

Хитрим со Squid в корпоративной сети

Недавно наткнулся на одну достаточно занятную статью (http://habrahabr.ru/blogs/sysadm/28063/), в которой описывалась возможность создания кластера proxy-серверов для увеличения суммарной пропускной способности. Изначально показалось, что место данного интересного решения – в музее устаревших технологий, однако, поразмыслив, пришел к более интересным выводам.
Дело в том, что наша контора, как и я, географически находимся в зоне с достаточно дорогим интернетом и не особо толковым в плане IT генеральным руководством. Как результат – на 500 с гаком человек приходится канал мегабита в два максимум; так что счастливым считается тот час, в который личная скорость поднимается выше отметки в 128 кбит/сек. А это более чем печально.

К счастью, работаю я в адекватном отделе, открытом ко всему новому и, что немаловажно, так же недовольному имеющимися скоростями. Каждому сотруднику полагается компьютер и запись в Active Directory, согласно учетным данным которой центральная прокся выдает ему свой кусочек тощего инета. Как видим, это достаточно благоприятная среда для того, чтобы воспользоваться преимуществами каскадирования прокси-серверов. Не стану описывать предпринятые шаги по конфигурации squid-ов – это и так хорошо описано в вышеприведенном материале. Покажу лишь картинку, иллюстрирующую общий замысел, и немного её откомментирую:

image

На компы заинтересованных сотрудников отдела ставится squid, который конфигурируется на получение интернета от центрального proxy-сервера конторы с использованием соответствующих учетных данных. Делается это следующей строчкой конфигурации squid:

cache_peer адрес прокси parent порт 0 no-query default login=юзер: пароль

Так как в файле конфигурации хранится пароль, настоятельно рекомендуется ограничить к нему доступ.
Далее, поднимается proxy-сервер отдела, который раскидывает поступающие запросы по проксям сотрудников, используя достаточно честный алгоритм round-robin (Round-robin — алгоритм распределения нагрузки распределённой вычислительной системы методом перебора её элементов по круговому циклу). Чтобы север знал, какие прокси ему доступны, в его конфигурацию добавляются вот такие строчки:

cache_peer прокси сотрудника parent порт 0 no-query round-robin

Ну и наконец, клиентский софт, такой как браузеры, менеджеры закачек и прочее, настраивается на использование свежеустановленного proxy-сервера отдела.

Если есть желание повысить безопасность полученного решения, можно воспользоваться различными способами, мной же был применен самый простой. Proxy сотрудников конфигурируются так, чтобы доступ к ним могли иметь только сами сотрудники и proxy отдела:

acl localhost src 127.0.0.1/32
acl proxynet src proxy отдела
http_access allow proxynet
http_access allow localhost
http_access deny all

Для того чтобы отсечь лишних пользователей от полученного кластера, в конфигурации proxy-сервера отдела прописываются вот такие строки, реализующие базовую аутентификацию (пути верны в случае использования squid-а в системе Windows, установленного в папку по умолчанию):

auth_param basic program c:/squid/libexec/ncsa_auth.exe c:/squid/etc/passwd
auth_param basic children 5
auth_param basic casesensitive off
acl Authenticated proxy_auth REQUIRED
http_access deny !Authenticated

А в файле c:/squid/etc/passwd прописываются пары логин/хэш_пароля, по которым производится аутентификация.

На этом можно было бы и закончить данную статью, если бы не один немаловажный аспект, подтолкнувший меня к её написанию. Согласно политикам домена, нам приходится периодически менять свои пароли, и, естественно, часть коллег периодически забывает синхронизировать эти изменения в файле конфигурации своего proxy, что выражается в не очень приятном симптоме, а именно: периодическом запросе аутентификационных данных у всех пользователей кластера при открытии страниц. Это очень сильно раздражает, поэтому было принято решение о написании диагностической утилиты, которая, располагаясь на машине с proxy отдела, по запросу проверяла бы доступность и корректную работу всех подшефных прокси-серверов.

Алгоритм достаточно тривиален, однако я приведу его здесь. Метод GetPeers, получая на вход имя файла конфигурации прокси-сервера отдела, достает по нему список всех прокси-серверов:

private static IEnumerable<String> GetPeers(string configFileName)
{
char[] separators = new char[]{' ', '\t'};
List<String> strings = new List<String>();
StreamReader reader = new StreamReader(configFileName, Encoding.Default);
while (!reader.EndOfStream)
{
string st = reader.ReadLine().Trim();
if (st.ToLower().StartsWith("cache_peer"))
{
string[] substrings = st.Split(separators);
strings.Add("http://" + substrings[1] + ":" + substrings[3]);
}
}
return strings;
}

Метод IsPeerAvaliable проверяет, в каком состоянии находится прокси-сервер с указанным URL-ом. Перечисление PeerStatus однозначно не является академически полным, как и метод определения статуса, однако его вполне достаточно для «любых практических целей»:

private static PeerStatus IsPeerAvaliable(string peer)
{
WebRequest request = WebRequest.Create("http://ya.ru");
request.Method = "GET";
request.Proxy = new WebProxy(peer);
request.Timeout = 5000;
try
{
request.GetResponse();
return PeerStatus.OK;
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ConnectFailure)
return PeerStatus.Offline;
if (ex.Status == WebExceptionStatus.ProtocolError)
return PeerStatus.AuthError;
return PeerStatus.Error;
}
catch (Exception ex)
{
return PeerStatus.Error;
}
}

Данная утилита может быть реализована как консольное или графическое приложение, либо как служба, предоставляющая веб-интерфейс. Мной был выбран последний вариант, как наиболее простой с точки зрения эксплуатации, результаты выглядят примерно так:

image

Какие выводы по этому всему можно сделать?
  • Скорость и отзывчивость интернета действительно возросла: особенно при многопоточной загрузке и открытии тяжелых страниц с кучей картинок. Так, например, скорость загрузки с 10-12 Кбайт/сек возрасла до 40-50.
  • Оптимальное количество участников кластера прокси в таком случае, видимо, следует подбирать эмпирически: вполне вероятно, что добавление N-го участника не принесет никакой пользы (эффективность подобного кластера в случае, когда в нем будет сидеть вся контора, очевидно, равна 0).
  • Особый респект в данном случае хочется выразить генеральному руководству, которое своими мудрыми решениями вынуждает сотрудников тратить их рабочее время на решение сторонних, в общем-то, вопросов.

+27
15.9k 69
Comments 47