Уменьшение трафика (загрузки канала) за счет кэширования повторных обращений нескольких машин к одной Web-странице (кэшируются HTTP и FTP); это ускоряет доступ в Internet за счет отказа от повторной загрузки ранее загруженных страниц, а также позволяет снизить плату за пользование Internet, если провайдер берет оплату за количество перекачанных данных. Возможны варианты как с явным указанием Proxy-сервера на клиентах, так и прозрачное (transparent) перенаправление на Squid запросов, проходящих через маршрутизатор.
Детальный контроль над доступом пользователей в Internet с возможностью разрешать/запрещать доступ не к сервису на указанной машине, а к отдельным Web-страницам:
запрет пользователям доступа к страницам, не имеющим отношения к тем задачам, ради которых им предоставляется доступ в Internet - это чаты, порнография и т.п.
запрет загрузки баннеров, счетчиков и другой лабуды;
ограничение скорости закачки по группам страниц, клиентов и т.п.
Первые две операции позволяют экономить как трафик, так и рабочее время сотрудников (в первом случае за счет удаления отвлекающего фактора, во втором - за счет ускорения загрузки и отрисовки страниц). Ограничение скорости позволяет предотвратить узурпирование канала низкоприоритетным трафиком.
Предоставление доступа к WWW машинам с Intranet-номерами в тех случаях, когда провайдер выдал недостаточное количество IP-номеров (впрочем, с этой задачай гораздо более универсально справляется NAT/Masquerading, но остаются первые две задачи).
Ускорение доступа к WWW-серверу, установленному на нашей территории, а также распределение нагрузки на несколько WWW-серверов.
Как установить и запустить
Я не сторонник самостоятельной компиляции программ (за исключением случаев, когда требуются какие-либо отключенные в заранее скомпилированном пакете функции), поэтому беру Squid из состава packages; этот путь я рекомендую для всех начинающих администраторов. Добавление Squid в систему стандартно:
pkg_add squid-2.4_6.tgz
При этом в директорию /usr/local/etc/rc.d распакуется файл squid.sh, который при перезагрузке машины будет запускать Squid в режиме демона. Но сразу после установки Squid работать не будет - его надо "довести до ума".
Если попытаться запустить Squid сразу после инсталляции, он сообщит, что его надо запустить с ключем -z для создания структуры директорий, где он будет хранить свой кэш (ранее скачанные Web-страницы, каждая в отдельном файле), но делать это сразу не стОит - дело в том, что по умолчанию Squid хранит свой кэш в /usr/local/squid/cache, отведя под него 100 мегабайт. Если мы правильно разбили диск при инсталляции FreeBSD, у нас имеется отдельный асинхронно смонтированный раздел /cache. В этом случае закомментаренную строку
#cache_dir ufs /usr/local/squid/cache 100 16 256
надо заменить на
cache_dir ufs /cache размер 16 256
где размер должен быть порядка трех четвертей от размера раздела (переполнение этого раздела крайне нежелательно, а его можно использовать под хранение временных файлов). Числа 16 и 256 означают, что в директории /cache будет создано 16 директорий, и в каждой - еще 256 директорий (вообще-то это тоже надо настраивать в зависимости от размера кэша и среднего размера кэшированного файла, но я не готов говорить об этом). После этого можно запускать 'squid -z', но я советую сначала настроить другие параметры.
Параметр store_avg_object_size по умолчанию имеет размер 13 KB. Прежде всего, надо рассказать о том, как Squid использует этот параметр при работе с кэшем.
Я уже имел проблемы, связанные со слишком большим store_avg_object_size, задаваемым по умолчанию; поэтому я рекомендую
store_avg_object_size 8 KB
Позднее можно будет оценить средний размер хранимого объекта по содержимому кэша (посчитать занимаемый объем и количество файлов); лучше принять его с некоторым запасом.
При выборе размера кэша следует учесть, что наиболее часто используемые данные он должен держать в памяти. На каждый объект, хранящийся в кэше, следует отвести примерно 200 байт оперативной памяти и указать этот объем
cache_mem N MB
где N расчитать как имеющаяся память за вычетом отведеной под работу ядра и других постоянно работающих программ (рекомендую воспользоваться программами 'top' и 'ps').
Если запустить Squid с данными настройками, он откажется пропускать кого-бы то ни было. Причины те же самые, что и в SendMail для закрытия свободного ralaying (пересылки почты с другой машины на третью) - администратор обязан сам указать множество машин, которые его сервер будет обслуживать. Дело в том, что у многих провайдеров различается цена внутреннего трафика, трафика по стране и заграничного трафика, а со временем такая политика будет распространяться все шире; поэтому реально появление злоумышленников, желающих свалить разницу в цене на кого-нибудь другого (все равно кого - лишь бы меньше платить самомУ).
Изначально в Squid мы имеем:
acl all src 0.0.0.0/0.0.0.0 acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255 acl SSL_ports port 443 563
acl Safe_ports port 80 21 443 563 70 210 1025-65535
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny all
(подробности об устройстве acl и http_access можно посмотреть прямо в squid.conf). Чтобы Squid пускал пользователей, надо прописать их IP-адресА в какой-нибудь ACL и предоставить доступ по этому списку.
Допустим, в нашей сетИ клиенты имеют только Intranet-адреса; в этом случае нам нужно
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl SSL_ports port 443 563
acl Safe_ports port 80 21 443 563 70 210 1025-65535
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
acl intranet src 10.0.0.0/255.0.0.0
acl intranet src 172.16.0.0/255.240.0.0
acl intranet src 192.168.0.0/255.255.0.0
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow intranet
http_access deny all
(добавленные строки выделены). В случае использования других адресов (полученных от провайдера) для списка доступа лучше придумать другое имя.
Как работают правила доступа
Управление доступа производится двумя тэгами: acl (см.подробности в файле squid.conf и у Богомолова) и http_access.
Список доступа задается в виде
acl имя тип список_значений
Действует это таким образом:
Если в списке доступа указывается несколько значений или имеется несколько определений списков доступа с одним именем, то указанные в них значения объединяются.
Если в кавычках пишется имя файла, то список значений берется из этого файла (по одному значению в каждой строке).
Если перед регулярным выражением (regexp) указывается "-i", то оно нечувствительно к регистру букв (не уверен).
Регулярные выражения - те самые, которые используются в Sed/Grep/AWK.
Доменное имя клиента определяется по его IP-адресу через ReverceDNS; доменное имя сервера - берется из URL, если оно там есть, или определяется по IP-адресу, если в URL указывается IP-адрес.
Правило доступа может указать одно из двух действий:
allow - разрешить;
deny - запретить.
Для сравнения: у ipfw их гораздо больше; например, есть переход к правилу с указанным номером (что-то типа оператора GOTO в языках программирования).
Правила доступа применяются последовательно, поэтому их порядок, в отличие от большинства других, очень существенен: для каждого запроса правила просматриваются последовательно до тех пор, пока запрос не попадет под действие какого-нибудь из них (первого встретившегося); после этого правило применяется (выполняется действие), на чем просмотр заканчивается. Это значит, что в списке правил сначала надо записывать частный случай, а потом более общий: например, если надо запретить доступ всем, кроме избранных, то надо сначала написать "разрешить избранным", а потом "запретить всем".
Если в каком-то правиле указано несколько ACL, то правило применяется если запрос попадает сразу во все ACL. Например,
acl net1 src 192.168.1.0/255.255.255.0
acl net2 src 192.168.2.0/255.255.255.0
http_access действие net1 net2
не будет иметь никакого действия, т.к. никакой IP-номер, от которого идет запрос, не может оказаться в двух непересекающихся IP-сетях (я сам совершал такую ошибку, потому и привожу ее как пример).
Если перед списком доступа указан "!", то это означает отрицание, т.е. правило действует если запрос не попадает в список доступа.
Регулярные выражения
Думаю, все сталкивались с wildchars в именах файлов:
"*" обозначает любой набор символов от пустой строки и длиннее (иногда из этого набора исключают точку - разделитель имени и расширения);
"?" обозначает любой символ в количестве одной штуки.
В Unix набор "масочных" символов гораздо шире, а кроме того, есть другие спец.символы, отвечающие за работу с переменными окружения, за запуск нескольких программ из одной командной строки и т.д.. Но в языке регулярных выражений есть свой набор спец.символов:
"." - точка обозначает любой символ в количестве одной штуки (то, что в шаблонах файлов делает "?").
"[...]" - набор символов, заключенный в квадратные скобки, обозначает любой из этих символов (только один); если два символа указаны через дефис(минус), то это обозначает любой символ из диапазона, заданного этими двумя символами. Если в число символов должен входить сам минус, его надо упомянуть первым или последним. Если первым символом внутри квадратных скобок идет "^", то это обозначает любой символ, не входящий в диапазон.
"\" - бэкслеш превращает любой специальный символ в обычный, а обычный - в специальный. Чтобы указать сам бэкслеш, его пишут дважды - первый из них "экранинует" второго.
"^" - крышка в начале шаблона обозначает начало строкИ; в противном случае удовлетворяющая шаблону часть строки ищется в любом ее месте.
"$" - доллар в конце шаблона обозначает конец строкИ.
"(...)" - скобки объединяют заключенные в них символы в группу.
"(...|...)" - пайп обозначает, что требуется присутствие одного из разделяемых им слов (пайпом м.б. сколько угодно). Если все слова содержат только одну букву, лучше воспользоваться квадратными скобками.
Повторители:
"{M,N}" - обозначает, что предыдущий символ или группа символов может повторяться от M до N раз. Если M отсутствует, M=0; если N отсутствует, N=бесконечности.
"*" - звездочка обозначает, что предыдущий символ или группа символов может повторяться ноль или более раз ("{0,}").
"+" - плюс обозначает, что предыдущий символ или группа символов может повторяться один или более раз ("{1,}").
"?" - вопр.знак обозначает, что предыдущий символ или группа символов может повторяться ноль или один раз (т.е. может быть или не быть - "{0,1}").
О построении URL
Мало кто задумывался о том, какие части могут присутствовать в URL. Привожу их список (вероятно, неполный):
протокол:// - обычно http:// или ftp://.
юзер@ или юзер:пароль@ - имя юзера и пароль.
доменое_имя - как строится доменное имя, см.статью про DNS; вкратце: доменное имя может содержать буквы (нечувствительно к регистру), цифры и минус.
:порт - порт (при отсутствии определяется протоколом).
/путь_к_файлу - директории в пути разделяются слэшем; при использовании OS, отличной от Unix, Web-сервер обязан преобразовывать путь_к_файлу в стандарт серверной OS, а при доступе по FTP браузер (или другой клиент) должен сам делать команды 'cd директория'.
?аргументы - параметры запуска CGI-скрипта методом GET. параметры записываются в виде имя=значение, параметры заделяются знаком "&" (амперсенд).
#смещение - вызывает прокрутку до якоря(метки) "<A NAME="смещение">".
Запрещаем чаты и порнографию
Для простоты ограничимся IP-сетью класса C 192.168.1.*, из которой можно выходить в WWW. В этом случае в squid.conf в те же места, которые были выделены в предыдущем примере, пишем
Многие популярные системы имеют WebChat-сайты: chat.chat.ru, chat.rambler.ruи т.д.; отличительным признаком URL является "chat" в третьем сегменте доменного имени (предполагается, что перед "chat" м.б. еще домены типа "www", а также имя юзера с паролем). Для того, чтобы накрыть имя юзера, пароль и префиксные сегменты доменного имени, я указываю "([^/]+[.@])?" - "любые символы, кроме слеша - один или более (т.к. слеш является признаком перехода к пути_к_файлу)"; затем "разделитель - собака или точка"; и все это может быть, а может и не быть (вопрос - "ноль или один раз").
Порнография:
Подавляющее большинство порносайтов содержат в доменном имени и/или в пути к файлу определенные слова - "porno", "udult", "xxx" и т.п.. Однако, такое слово может содержать и обычный сайт, в т.ч. и посвященный проблеме ограниченя порнографии. Я выбрал такой компромисс:
Сайт признается порнографическим, если он содержит порнослово как сегмент доменного имени (т.е. "www.porno.com" считается порнографическим, а "www.antiporno.com" - нет); кроме того порнографическими считаются доменные имена, в которых перед порнословом стоит "best", "cool", "free", "hot", "lady" или "top".
Порнографическими признаются картинки GIF и JPEG, содержащие в доменном имени и/или в пути к файлу порнослово. Обычные сайты будут приемлимо смотреться даже без такой картинки, а порносайт потеряет всю свою привлекательность.
Для борьбы с порнографией я побродил немного по порносайтам и нашел там достаточно много линков, чтобы составить большой список.
Баннеры:
Баннеры неприятны уже тем, что каждый раз загружается новый баннер. Для борьбы с ними я использую свой список.