unix 2015-08-24 03-50-51
Squid: настраиваем контроль доступа и оптимизируем кэш
Статья из журнала ХакерЕсли нужно предоставить совместный доступ сервисам нескольким пользователям с возможностью кэширования трафика, то в первую очередь вспоминают о кэширующем прокси-сервере Squid. Это очень гибкое решение, которое применяют как в малых офисах с несколькими пользователями, так и в корпоративных сетях со сложной топологией. Предлагаю разобрать, как настроить в Squid самые популярные функции – контроль доступа и работу с кэшем.
Установка Squid
В начале пару слов о самом Squid для новичков. Squid (www.squid-cache.org) — приложение позволяющее организовать прокси/кэширующий сервер для HTTP, FTP и некоторых других популярных протоколов. Поддерживается работа с защищенными TLS/SSL соединениями, кэширование DNS, возможно использование Squid в качестве прозрачного или реверсного прокси. Распространяется по лицензии GNU GPL. Работает во всех популярных вариантах Unix систем — GNU/Linux, *BSD, Mac OS X, SunOS/Solaris, и некоторых других. Есть версия для Windows.
Для примера буду использовать Ubuntu, но все сказанное касается и всех остальных дистрибутивов или ОС, за исключением особенностей установки в конкретном решении. Хотелось бы также отметить, что сейчас параллельно развивается две ветки: 2-x и 3-x. Третья ветка перешла в разряд STABLE в конце прошлого года и рекомендуема к использованию. По параметрам описываемых далее отличий у них практически нет, поэтому все описанное касается обоих версий, отличия будут оговорены отдельно. В репозитарии Ubuntu 6.06 LTS Dapper Drake находится пакет с версией Squid 2.5, в последнем 7.10 – 2.6.14. Также репозитариях всех Ubuntu начиная от Festy Fawn (7.04) есть и пакеты с третьей версией Squid. Об отличиях рассказано здесь. Установка Squid в Ubuntu вообщем то проста:
$ sudo apt-get install squid squid-commonИли для Squid 3:
$ sudo apt-get install squid3 squid3-common
После инсталляции Squid будет запущен с установками по умолчанию.
в репозитарии Ubuntu множество пакетов к Squid
Иногда в процессе запуска появляется ошибка:
FATAL: Could not determine fully qualified hostname. Please set ‘visible_hostname’
По умолчанию разрешение имени узла, на котором работает Squid, происходит при помощи gethostname(), в зависимости от установок DNS, он иногда не может однозначно определить имя, которое будет фигурировать в журналах и выводах об ошибках “ Generated … by server.com (squid/3.0.STABLE2) ”. И просит тебя ему помочь.
Все настройки Squid производятся в единственном файле /etc/squid/squid.conf, параметров внутри очень много, но бросаться менять их все и сразу не стоит. Просмотреть список параметров, убрав пустые и закомментированные строки, можно при помощи команды:
$ sudo grep -v «^#» /etc/squid/squid.conf | sed -e ‘/^$/d’
параметры по умолчанию в squid.conf
Формат squid.conf стандартен для Unix, каждая запись состоит из строк вида:
параметр значение
Возможно использование переменных. Cтроки начинающиеся со знака решетки (#) являются комментариями. Для удобства настройки, все параметры разбиты по секциям. Такое разбиение чисто условно и можно прописывать свои параметры в любое место файла, лишь бы было понятно. Возможно подключение внешнего файла с настройками при помощи include. Единственное о чем следует помнить – установки применяются в порядке очередности. После установки в /usr/share/doc/squid найдешь документацию и примеры конфигурационных файлов.
Для начала запустим Squid, устранив ошибку указанную выше. Заносим в этот файл строку с именем сервера Squid, оно не обязательно должно совпадать с DNS:
visible_hostname mysquid
И запускаем:
$ sudo /etc/init.d/squid start
В настройках по умолчанию сквид принимает входящие сообщения на 3128 порту. При необходимости другой порт можно указать в параметре http_port. Проверяем введя команду “netstat –ant | grep 3128”слушается ли этот порт. Если все нормально, настраиваем веб-браузер для работы через прокси-сервер и выходим в Интернет. Но сейчас это возможно только с localhost. При попытке подключиться другого компьютера в сети, получаем:
$ sudo cat /var/log/squid/access.log | grep 192.168.0.10
1206182759.796 1 192.168.0.10 TCP_DENIED/403 1393 GET http://www.tux.in.ua/
Чтобы в Интернет могли попасть остальные пользователи сети, нужно установить соответствующие разрешения, используя контроль доступа.
Настраиваем доступ
Если на компьютере имеется несколько интерфейсов, изменив параметр http_port ограничим доступ к Squid только внутренней сетью:
http_port 192.168.0.1:3128
Хотя IP-адрес в http_port не является обязательным, можно просто указать порт.
Чтобы разрешить всем пользователям сетей 192.168.0.0, 172.16.0.0 и компьютера 192.168.1.1 подключаться к Squid, добавляем описание нового списка доступа в секцию “ACCESS CONTROL”:
acl localnet src 192.168.0.0/24 172.16.0.0/12
acl localnet src 192.168.1.1
Вторая строка – это название нового списка доступа. Переменные чувствительны к регистру, но использовав параметр “acl –i” можно изменить это поведение. Сейчас в этом необходимости нет, чуть дальше покажу как. Если нужно настроить доступ не для всей сети, а отдельных ее узлов, проще записать их адреса в файл (по одному в строке), который и указать в качестве последнего параметра. Третья строка – тип списка доступа. В нашем случае использован src (от source). При помощи других параметров можно указать внешний адрес (dst), МАС-адрес (arp), доменное имя (srcdomain, dstdomain), порт (port), протокол (proto), время (time) и многие другие. Фактически работа по организации доступа сводится с описания объекта в acl, а затем разрешении или запрете работы объекта при помощи “http_access” с такими параметрами. Например, чтобы указать рабочее время, используем такую конструкцию:
acl work_hours time M T W T F 9:00-18:00
В описании используются первые буквы английского языка, соответствующие дням недели. В секции “ACCESS CONTROL” уже описаны некоторые ACL, в частности описываются номера некоторых портов (привожу не все) и ACL соответствующий всем адресам:
acl SSL_ports port 443 563 873
acl Safe_ports port 80 21 443 563 1025-65535
acl all src 0.0.0.0/0.0.0.0
Следует внимательно просмотреть весь список, и закомментировать строки с портами не нужных или неиспользуемых сервисов.
Когда списки составлены, при помощи параметра http_access разрешаем или запрещаем доступ указанному ACL. Общий формат вызова такой:
http_access allow|deny [!]название_ACL
Восклицательный знак инвертирует значение списка, то есть звучит как “все кроме”. По умолчанию используется правило:
http_access deny all
Его мы обязательно помещаем в конец списка правил. В этом случае все соединения которые явно тобой не разрешены, будут блокированы. Майнтайнеры собирающие пакеты в дистрибутивах, как правило, добавляют и несколько своих правил.
Чтобы разрешить подключение к Squid с указанных адресов и работу только с нужными портами пишем:
http_access allow localnet
http_access deny !Safe_ports
http_access deny !SSL_ports
Сохраняем результат и перезапускаем Squid:
$ sudo /etc/init.d/squid restart
И проверяем. Если все нормально, идем дальше. Чтобы не перестраивать клиентские системы проще использовать iptables:
iptables -t nat -A PREROUTING -i eth1 -p tcp -m tcp —dport 80 -j DNAT —to-destination 192.168.0.1:3128
iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp —dport 80 -j REDIRECT —to-ports 3128
Еще один пример, нам нужно, чтобы компьютеры определенными IP могли соединяться только в рабочее время. Без проблем:
acl workip src 192.168.1.100 192.168.1.200-192.168.1.210
http_access deny !work_hours workip
Можно расписать это правило на два, сделав его более читабельным:
http_access allow work_hours workip
http_access deny workip
Первая строка разрешит доступ при совпадении двух ACL: рабочее время и IP-адрес. Вторая запретит доступ всех записанных в ACL workip при несовпадении с первым правилом, то есть в другой временной промежуток.
Режем баннеры и сайты
Одна из функций присущих сквиду, которая делает его востребованным – возможность запрета доступа к определенным ресурсам Интернет. Это реализовано на той же сладкой парочке: acl и http_access. Зная адрес ресурса, можно просто закрыть доступ к конкретному адресу или целой подсети:
acl denynet dst 194.55.0.0/16
http_access deny denynet
Но вместо того чтобы использовать адрес, удобнее при помощи dstdomain указывать домен назначения. Например, запретим доступ к сервисам вроде RapidShare:
acl rapida dstdomain .rapidshare.com .rapidshare.de
http_access deny rapida
Если в сети есть юзеры, которым разрешено все, например начальство не очень любит когда их куда то не пускают, то запрещающее правило можно дополнить списком адресов:
http_access deny workip dstdomain
В том случае если нужно будет указать домен источника, то используй srcdomain. Это самый простой способ, но далеко не самый удобный, так как юзвери не попав на любимый ресурс, быстро бросятся на поиск альтернативы и естественно его найдут. Поэтому адреса в ACL удобнее задавать при помощи регулярных выражений:
acl adult dstdom_regex sex
acl regexdomain dstdom_regex \.com$ \.net$ \.tv$
http_access deny adult regexdomain
Сейчас мы запретили доступ ко всем все доменам содержащим слово “sex”, и всем доменам в зонах .com, .net и .tv.
Аналогичным образом блокируется и определенный контент, но вместо dstdom_regex используется url_regex или urlpath_regex. С их помощью указывается шаблон регулярного выражения для URL. Второй отличается тем, что не нужно заботиться о пути URL, то есть при описании исключается домен. Например, создадим описания расширений видео, флэш и музыкальных файлов и запретим обращение к таким ссылкам. Для нашего задания urlpath_regex подходит больше, но приведу оба для примера. Чтобы игнорировался регистр символов, используем дополнительно ключ “-i”:
acl videofiles url_regex –i *\.avi$ *\.mpg$ *\.mp4$ *\.swf$
acl soundfiles urlpath_regex -i \.mp3$ \.asf$ \.wma$
http_access deny videofiles soundfiles
Удобнее для хранения URL использовать отдельный файл:
acl blockfiles urlpath_regex -i “/etc/squid/blocks.files.acl”
http_access deny blockfiles
Заносим данные о расширениях в указанный файл:
$ sudo nano /etc/squid/blocks.files.acl
\.exe$
\.avi$
\.mpg$
\.mpeg$
\.mp3$
Изменив содержимое этого файла, следует перезапустить Squid, чтобы он перечитал все изменения.
Иногда бывает полезным выводить информацию, чтобы пользователь знал, что его блокируют и пытался бесцельно получить доступ к такому URL. Для этой цели используется параметр deny_info, который находится в секции “ERROR PAGE OPTIONS”. В качестве параметров ему следует указать файл или URL который будет выведен пользователю, и ACL к которому относится данный deny_info. Файл желательно использовать html формате и находиться он должен в подкаталоге /etc/squid/errors. Кроме этого на каталог для сообщений об ошибках показывает переменная error_directory (в Ubuntu по умолчанию /usr/share/squid/errors/English). Добавляем в squid.conf:
deny_info ERR_BLOCKED_FILES blockfiles
И создаем файл /etc/squid/errors/ERR_BLOCKED_FILES в котором популярно расписываем причину блокировки.
Составив подобным образом URL можно блокировать рекламу, например Google AdSense и некоторые другие попадут под правило:
acl adsense url_regex –i *pagead2*
http_access deny adsense
Используя тип proto, можно указать один из протоколов (http или ftp) для которых будет действовать правило или вообще запретить доступ по выбранному протоколу:
acl ftp proto ftp
http_access deny ftp workip
Теперь с компьютеров с адресами входящими в workip, нельзя будет обратиться к ресурсам на FTP серверов.
Использование ACL для блокировки баннеров не очень удобно, выходом из этой ситуации будет фильтрация не по конкретному адресу, а по содержимому при помощи squidGuard (www.squidguard.org), который представляет собой дополнение к Squid.
Настройки кэша
Борьба с баннерами не единственная возможность сэкономить трафик. Поэтому нельзя обойти стороной некоторые настройки кэширования. А Ubuntu кэш по умолчанию размещается в каталоге /var/spool/squid. В других дистрибутивах может быть иначе, чтобы не искать просмотри значение переменной cache_dir. Формат ее такой:
cache_dir type путь размер L1 L2 [options]
Например:
cache_dir ufs /var/spool/squid 10249 16 256
Поле type определяет формат кэша: ufs (unix file system), aufs и diskd. В особенности углубляться не буду, по умолчанию используется ufs. Максимальный размер после которого кэш будет очищаться установлен по умолчанию в 100 Мб. При больших нагрузках он быстро заполнится, поэтому есть смысл увеличить его до нескольких гигабайт. Удобно, что можно использовать несколько cache_dir, установив кэш на разных дисках. Это положительно сказывается на производительности. В Squid каждый кешируемый объект располагается в отдельном файле, сами файлы не сваливаются в одно место, а используется в двухуровневая иерархия каталогов. Количество каталогов 1 и 2 уровней и определяют параметры L1 и L2. По умолчанию их значения 16 и 256 соответственно. Дополнительно для каждого cache_dir можно определить параметр read-only (только чтение) и max-size (максимальный размер объекта).
Глобально максимальный размер объекта в кэше определяется переменной maximum_object_size, значение по умолчанию которой 4 Мб, имеет смысл его увеличить:
maximum_object_size 10240 KB
Аналогично есть и параметр minimum_object_size отвечающий за минимальный размер объекта, по умолчанию его значение “0” то есть отключен. Объем ОЗУ используемый Squid для хранения обрабатываемых объектов определяется параметром cache_mem, значение по умолчанию 8 Мб. Оставшееся пространство может быть использовано для хранения часто используемых и некэшируемых объектов. Для хранения информации об объектах используется блок 4 кб, при большом размере кэша лучше увеличить значение cache_mem, тем более, что объемы современных ОЗУ это позволяют, иначе Squid будет сбрасывать эту информацию на диск,.
Но это далеко не все. Например отключенный по умолчанию параметр reload_into_ims, разрешает игнорировать nocache или reload и выдавать объект из кэша. Это нарушение стандарта HTTP, и есть определенный риск при его использовании, но большинство серверов умеют корректно обработать такой запрос, потому включаем:
reload_into_ims on
Хотя можно вместо глобальной установки, установить такой параметр для некоторых типов файлов. Теперь документация на странице reload_into_ims отсылает нас к не менее интересному refresh_pattern, который задает параметры кэширования. В общем, шаблон записи выглядит так:
refresh_pattern [-i] regex min percent max [options]
В regex пишем регулярное выражение, которому будет отвечать правило, проверка производится до первого совпадения. Поэтому последним всегда устанавливается «.» то есть правило для всех объектов. Параметр min и max указывают соответственно на минимальное и максимальное время в минутах в течение которого объект считается новым. В percent указывается процент от времени последней модификации объекта, в течение которого объект считается новым. В min рекомендуется устанавливать “0”, чтобы корректно работать с динамически обновляемыми страницами. В версии Squid 2.x по умолчанию используются инструкции:
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern . 0 20% 4320
В версии 3.0 перед «.» добавлено еще:
refresh_pattern (cgi-bin|\?) 0 0% 0
В поле options, через пробел указываются дополнительные параметры. В версии 2.x параметров 7, в 3.х добавилось еще два. Большинство из них идут в разрез со стандартами HTTP и их использование может вызвать проблемы при работе с некоторыми серверами. Но для оптимизации кэша они весьма полезны и понадобятся в дальнейших настройках:
— override-expire – в нарушение стандарта заставляет игнорировать параметр expire, то есть время актуальности объекта;
— override-lastmod – игнорирование времени последней модификации объекта переданное сервером;
— reload-into-ims, ignore-reload– изменяет или игнорирует клиентские запросы nocache или reload и принудительно выдает объект, хранящийся в кэше;
— ignore-no-cache, ignore-private, ignore-auth – игнорирует заголовки “Pragma: no-cache”, “Cache-control: no-cache”, “Cache-control: private” и “Cache-control: public” принудительно кэшируя такой объект;
И параметры появившиеся в третьей версии:
— ignore-no-store – игнорирование заголовка “Cache-control: no-store”;
— refresh-ims – заставляет проверять наличие новой версии файла при получении от клиента If-Modified-Since.
В самом простом случае вместо правил по умолчанию можно написать одно правило, заставляющее принудительно кэшировать объекты на целый год:
refresh_pattern . 518400 80% 518400 override-expire override-lastmod reload-into-ims ignore-no-cache ignore-private ignore-auth ignore-no-store
Устанавливаем размер кэша побольше и забываем о Squid. Это даст весьма ощутимую экономию трафика. Не всегда такой подход приемлем, да и кэш старыми файлами заполнится быстро. Лучше установить свои варианты кэширования, для разных типов файлов. Например, часто на сайтах проектов экзешники, архивы и некоторые другие типы файлов имеют постоянный адрес, вроде server.com/current.exe. Укажем для таких файлов время хранения в месяц:
refresh_pattern \.exe$ 43200 100% 43200 override-expire override-lastmod reload-into-ims ignore-no-cache ignore-private ignore-auth ignore-no-store
refresh_pattern \.zip$ 43200 100% 43200 override-expire override-lastmod reload-into-ims ignore-no-cache ignore-private ignore-auth ignore-no-store
И так далее. Таким же образом “вырезают” рекламу. Так как создавать универсальное правило для acl/http_access тяжело и всегда можно допустить ошибку, рекламу админу проще кэшировать, чем запрещать:
refresh_pattern http://ad\. 43200 100% 43200 override-expire override-lastmod reload-into-ims ignore-no-cache ignore-private ignore-auth ignore-no-store
refresh_pattern http://click\. 43200 100% 43200 override-expire override-lastmod reload-into-ims ignore-no-cache ignore-private ignore-auth ignore-no-store refresh_pattern http://count\. 43200 100% 43200 override-expire override-lastmod reload-into-ims ignore-no-cache ignore-private ignore-auth ignore-no-store
Это самый простой способ, при тщательном изучении логов можно быстро составить коллекцию URL, которые нужно поместить в вечный кэш. Для резки рекламы можно дополнительно использовать прокси-сервер bfilter (bfilter.sf.net) или редиректор для squid – adzapper (adzapper.sf.net).
модуль настройки Squid в Webmin
Как видишь в Squid ничего страшного нет. Если ручную настройку не считаешь удобной, то обратись к Webmin, в котором большинство установок можно произвести в удобной наглядной форме. Базовая настройка занимает минут 10, после некоторой доводки пользователи будут радоваться скорости Интернета, а руководство использованием трафика.