Squid Web Proxy Cache

Однажды мне дали задание установить прокси-сервер для нашей подсети. Мой выбор пал на Squid, о котором я слышал много хорошего. Сразу бросилось в глаза, что во многих форумах и конференциях люди постоянно обсуждают различные проблемы его (Сквида) конфигурирования и настройки, активно обмениваются опытом, обсуждают прелести и неприятности новых версий. На его родном сайте можно увидеть неплохой FAQ, древний Users Guide, снять последний исходник. Там также хорошо видна история версий, с изменениями и патчами ко многим (даже старым) версиям. Существует русская версия FAQ'а, ее можно найти на некоторых русских серверах, посвященных unix'у. Но, ближе к делу. Представленная информация разбита по разделам, по аналогии с пунктами технического задания: что, зачем и как.

Физика процесса установки и настройки Squid показана на примере версии 2.2.STABLE5, хотя я начинал свое знакомство с версии 1.1.7. 2-ая версия значительно отличается от предыдущей, хотя даже сейчас на некоторых серверах успешно работает Squid 1.X.

Для чего нужен прокси-сервер?

Прокси-сервер, осуществляющий доступ в Интернет, предоставляет следующие возможности:

централизованный выход в Интернет через один сервер в сети

локальное хранение часто просматриваемых документов для увеличения скорости загрузки страниц (один пользователь загрузил документ с удаленного сервера в Интернете, а все остальные после этого берут этот документ с прокси-сервера)

возможность регулировать пропускную способность канала в зависимости от его нагрузки

авторизованный доступ в Интернет (пользователь может загружать документы из Интернета только при наличии логина и пароля)

В моем случае на Squid'е включен авторизованный доступ, с помощью которого существует возможность собрать и обсчитать статистику использования прокси-сервера каждым пользователем и подвести некоторые итоги за период (день, неделю, месяц). Подробнее об этом читайте в разделе о SQMGRLOG'е.

Номера и типы версий - что ставить?

Версии имеют номер, например, Squid 2.2, тип (PRE, DEVEL и STABLE). Сами разработчики советуют ставить стабильные (STABLE) версии, хотя в порядке эксперимента можно поставить любую из предложенных. Думаю, надо исходить из поставленных перед Вами целей: если нужно поставить, настроить, разобраться, то можно взять DEVEL. Ну а если нужна стабильная работа, то лучше взять STABLE, причем обязательно предварительно глянуть в Reported Bugs for version x.x и проверить, действительно ли это провернная и рабочая версия (иногда имеет смысл ставить предпоследнюю версия, а не самую свежую)! Переход на следующую версию/подверсию/тип можно осуществить с помощью патчей для Вашей версии:

cd squid-2.2.STABLE4 - здесь лежит Ваш исходник,

сюда можно скопировать патч,

patch < diff-2.2.STABLE4-2.2.STABLE5

после чего нужно обязательно сделать

make clean

./configure

make

make install

Компиляция и установка

Нужно скачать архив с нужным исходником, положить его, например, в домашний каталог (после установки этот каталог убивать не надо, вдруг нужно будет пропатчевать или переставить заново). Далее:

% tar xzf squid-2.x.RELEASE-src.tar.gz

% cd squid-2.x.RELEASE

% ./configure

% make

% make install

У команды configure есть несколько полезных опций, которые можно посмотреть

% ./configure --help

Configuration:

--cache-file=FILE cache test results in FILE

--help print this message

--no-create do not create output files

--quiet, --silent do not print `checking...' messages

--version print the version of autoconf that created configure

Directory and file names:

--prefix=PREFIX install architecture-independent files in PREFIX

[/usr/local/squid]

--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX

[same as prefix]

--bindir=DIR user executables in DIR [EPREFIX/bin]

--sbindir=DIR system admin executables in DIR [EPREFIX/sbin]

--libexecdir=DIR program executables in DIR [EPREFIX/libexec]

--datadir=DIR read-only architecture-independent data in DIR

[PREFIX/share]

--sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]

--sharedstatedir=DIR modifiable architecture-independent data in DIR

[PREFIX/com]

--localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]

--libdir=DIR object code libraries in DIR [EPREFIX/lib]

--includedir=DIR C header files in DIR [PREFIX/include]

--oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]

--infodir=DIR info documentation in DIR [PREFIX/info]

--mandir=DIR man documentation in DIR [PREFIX/man]

--srcdir=DIR find the sources in DIR [configure dir or ..]

--program-prefix=PREFIX prepend PREFIX to installed program names

--program-suffix=SUFFIX append SUFFIX to installed program names

--program-transform-name=PROGRAM

run sed PROGRAM on installed program names

Host type:

--build=BUILD configure for building on BUILD [BUILD=HOST]

--host=HOST configure for HOST [guessed]

--target=TARGET configure for TARGET [TARGET=HOST]

Features and packages:

--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)

--enable-FEATURE[=ARG] include FEATURE [ARG=yes]

--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]

--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)

--x-includes=DIR X include files are in DIR

--x-libraries=DIR X library files are in DIR

--enable and --with options recognized:

--enable-dlmalloc[=LIB] Compile & use the malloc package by Doug Lea

--enable-gnuregex Compile GNUregex

--enable-xmalloc-debug Do some simple malloc debugging

--enable-xmalloc-debug-trace

Detailed trace of memory allocations

--enable-xmalloc-statistics

Show malloc statistics in status page

--enable-carp Enable CARP support

--enable-async-io Do ASYNC disk I/O using threads

--enable-icmp Enable ICMP pinging

--enable-delay-pools Enable delay pools to limit bandwith usage

--enable-mem-gen-trace Do trace of memory stuff

--enable-useragent-log Enable logging of User-Agent header

--enable-kill-parent-hack

Kill parent on shutdown

--enable-snmp Enable SNMP monitoring

--enable-time-hack Update internal timestamp only once per second

--enable-cachemgr-hostname[=hostname]

Make cachemgr.cgi default to this host

--enable-arp-acl Enable use of ARP ACL lists (ether address)

--enable-htcp Enable HTCP protocol

--enable-forw-via-db Enable Forw/Via database

--enable-cache-digests Use Cache Digests

see http://squid.nlanr.net/Squid/FAQ/FAQ-16.html

--enable-err-language=lang

Select language for Error pages (see errors dir)

--enable-poll Enable poll() instead of select(). Normally poll

is preferred over select, but configure knows poll

is broken on some platforms. If you think you are

smarter than the configure script, you may enable

poll with this option.

--disable-poll Disable the use of poll().

--disable-http-violations

This allows you to remove code which is known to

violate the HTTP protocol specification.

--enable-ipf-transparent

Enable Transparent Proxy support for systems

using IP-Filter network address redirection.

--enable-leakfinder

Enable Leak Finding code. Enabling this alone

does nothing; you also have to modify the source

code to use the leak finding functions. Probably

Useful for hackers only.

--disable-ident-lookups

This allows you to remove code that performs

Ident (RFC 931) lookups.

Возможно, кому-то нужно включать все опции, но я на практике использую только:

--prefix=PREFIX установить нужный путь для установки корневой сквидовой директории (по умолчанию /usr/local/squid)

--enable-delay-pools включить опцию ограничения полос пропускания

--enable-useragent-log включить возможность записи в логи сведений о браузере/ОС пользователя

--enable-err-language=lang включить функцию вывода ошибок на родном языке

Итак, сквид откомпилился и поставился (если при компиляции появились ошибки, можно лишний раз заглянуть в FAQ и в Reported Bugs, возможно там Вы найдете объяснение ошибки, а может и патч для ее устранения). Осталось его настроить и запустить!

Редактирование squid.conf

В файле QUICKSTART в корне исходников перечислены опции squid.conf, которые необходимо отредактировать:

cache_peer - основной кеш

If you have a parent cache, put it here. The administrators of the

parent cache typically provided you with instructions. You should

always ask permission before adding a parent cache.

cache_mem - стандартное количество памяти для сквида

Add here the amount of memory (RAM memory) to devote to caching.

Warning: Squid uses much more than this value. Rule of thumb: if

you have N megabytes free for Squid, put N/3 here.

!!! Добавлено специально для самых мудрых !!!

# NOTE: THIS PARAMETER DOES NOT SPECIFY THE MAXIMUM PROCESS

# SIZE. IT PLACES A LIMIT ON ONE ASPECT OF SQUID'S MEMORY

# USAGE. SQUID USES MEMORY FOR OTHER THINGS AS WELL.

# YOUR PROCESS WILL PROBABLY BECOME TWICE OR THREE TIMES

# BIGGER THAN THE VALUE YOU PUT HERE

#

# 'cache_mem' specifies the ideal amount of memory to be used

# for:

# * In-Transit objects

# * Hot Objects

# * Negative-Cached objects

#

# Data for these objects are stored in 4 KB blocks. This

# parameter specifies the ideal upper limit on the total size of

# 4 KB blocks allocated. In-Transit objects take the highest

# priority.

#

# In-transit objects have priority over the others. When

# additional space is needed for incoming data, negative-cached

# and hot objects will be released. In other words, the

# negative-cached and hot objects will fill up any unused space

# not needed for in-transit objects.

#

# If circumstances require, this limit will be exceeded.

# Specifically, if your incoming request rate requires more than

# 'cache_mem' of memory to hold in-transit objects, Squid will

# exceed this limit to satisfy the new requests. When the load

# decreases, blocks will be freed until the high-water mark is

# reached. Thereafter, blocks will be used to store hot

# objects.

#

# The default is 8 Megabytes.

#

#cache_mem 8 MB

cache_dir /usr/local/squid/cache 100 16 256 - дисковая память под кеш (в Мб)

Add here (first number, here 100) the amount of hard disk space

(in megabytes) to devote to caching.

acl, http_access, icp_access - списки доступа (подробнее см. ниже)

Access control lists. This is important because it prevents people

from stealing your network resources. To fill in the

"allowed_hosts" ACL, use your network address (for instance

192.168.10.0 and your network mask (for instance 255.255.255.0):

acl manager proto cache_object

acl localhost src 127.0.0.1/255.255.255.255

acl all src 0.0.0.0/0.0.0.0

acl allowed_hosts src 192.168.10.0/255.255.255.0

http_access deny manager all

http_access allow allowed_hosts

http_access deny all

icp_access allow allowed_hosts

icp_access deny all

cache_mgr - почтовый адрес администратора

Put here the e-mail address of the manager:

cache_effective_user - имя пользователя, владельца процесса для запуска

If you must start Squid as root, find a safe user and group to run

as after startup (typically "nobody" and "nogroup"). Do not use

"root", for security reasons.

visible_hostname - публикуемое имя кеш-сервера

The host name you advertise for the cache.

Это, действительно, основные параметры, которые необходимо прописать для нормального функционирования сквида. После этого все готово к первому запуску.

Запуск Squid'а

Первый раз сквид нуно запускать с параметром z:

% /usr/local/squid/bin/squid -z

После создания кешового дерева сквид можно запускать (без параметров). Для предыдущих версий нужно писать:

% /usr/local/squid/bin/RunCache &

Сквид можно запускать как из командной строки (% /usr/local/squid/bin/squid), так и автоматически при каждой новой загрузке сервера (например, из rc.local). После первого запуска сквида (с опцией z) в логах может появиться сообщение типа "WARNING: Cannot write to swap directory" - по словам разработчиков, это нормальное явление.

Дополнительная настройка

В этом разделе будет рассмотрена настройка листов доступа сквида, авторизация пользователей прокси-сервера, работа сквида из-под Firewall (на примере FWTK) и ключи командной строки squid.

Access control lists

Листы доступа (ACL) нужны для управления работой пользователей через прокси-сервер, введения временных и адресных ограничений, фильтрации запросов на web-сервера, на которые заходят пользователи. Решения проблем ограничения входа на порно-сервера можно посмотреть здесь.

В файле squid.conf даны всевозможные описания ACL'ов:

# ACCESS CONTROLS

# -----------------------------------------------------------------------------

# TAG: acl

# Defining an Access List

#

# acl aclname acltype string1 ...

# acl aclname acltype "file" ...

#

# when using "file", the file should contain one item per line

#

# acltype is one of src dst srcdomain dstdomain url_pattern

# urlpath_pattern time port proto method browser user

#

# By default, regular expressions are CASE-SENSITIVE. To make

# them case-insensitive, use the -i option.

#

# acl aclname src ip-address/netmask ... (clients IP address)

# acl aclname src addr1-addr2/netmask ... (range of addresses)

# acl aclname dst ip-address/netmask ... (URL host's IP address)

# acl aclname myip ip-address/netmask ... (local socket IP address)

#

# acl aclname srcdomain foo.com ... # reverse lookup, client IP

# acl aclname dstdomain foo.com ... # Destination server from URL

# acl aclname srcdom_regex [-i] xxx ... # regex matching client name

# acl aclname dstdom_regex [-i] xxx ... # regex matching server

# # For dstdomain and dstdom_regex a reverse lookup is tried if a IP

# # based URL is used. The name "none" is used if the reverse lookup

# # fails.

#

# acl aclname time [day-abbrevs] [h1:m1-h2:m2]

# day-abbrevs:

# S - Sunday

# M - Monday

# T - Tuesday

# W - Wednesday

# H - Thursday

# F - Friday

# A - Saturday

# h1:m1 must be less than h2:m2

# acl aclname url_regex [-i] ^http:// ... # regex matching on whole URL

# acl aclname urlpath_regex [-i] .gif$ ... # regex matching on URL path

# acl aclname port 80 70 21 ...

# acl aclname port 0-1024 ... # ranges allowed

# acl aclname proto HTTP FTP ...

# acl aclname method GET POST ...

# acl aclname browser [-i] regexp

# # pattern match on User-Agent header

# acl aclname ident username ...

# # string match on ident output.

# # use REQUIRED to accept any non-null ident.

# acl aclname src_as number ...

# acl aclname dst_as number ...

# # Except for access control, AS numbers can be used for

# # routing of requests to specific caches. Here's an

# # example for routing all requests for AS#1241 and only

# # those to mycache.mydomain.net:

# # acl asexample dst_as 1241

# # cache_peer_access mycache.mydomain.net allow asexample

# # cache_peer_access mycache_mydomain.net deny all

#

# acl aclname proxy_auth username ...

# # list of valid usernames

# # use REQUIRED to accept any valid username.

# #

# # NOTE: when a Proxy-Authentication header is sent but it is not

# # needed during ACL checking the username is NOT logged

# # in access.log.

# #

# # NOTE: proxy_auth requires a EXTERNAL authentication program

# # to check username/password combinations (see

# # authenticate_program).

# #

# # WARNING: proxy_auth can't be used in a transparent proxy. It

# # collides with any authentication done by origin servers. It may

# # seem like it works at first, but it doesn't.

#

# acl aclname snmp_community string ...

# # A community string to limit access to your SNMP Agent

# # Example:

# #

# # acl snmppublic snmp_community public

#

#

#Examples:

#acl myexample dst_as 1241

#acl password proxy_auth 300

#

#Defaults:

После создания нового ACL'а его нужно активировать (поставить разрешение либо запрещение для него):

# TAG: http_access

# Allowing or Denying access based on defined access lists

Пример запрещения работы пользователей в воскресенье:

acl sunday time S

http_access deny sunday

Пример, как запретить пользователям качать музыку, видео и архивы:

acl bigfiles urlpath_regex .mp3$ .zip$ .avi$ .mpeg$

http_access deny files

Нужно помнить, что по умолчанию работа через прокси может быть разрешена всем пользователям (с любого адреса, в том числе не из Вашей сети), которые могут зайти по любому адресу в любое время. Поэтому работу по созданию ACL'ов желательно производить по следующему простому плану: сначала запретить всем все, а потом по надобности разрешать кому-то что-то! Некоторые советуют поступать наоборот (разрешить все, запрещать что-то), но это уже вопрос логики и понимания текущей ситуации. Поэтому я советую начинать так:

acl all src 0.0.0.0/0.0.0.0

http_access deny all

А потом надо разрешить доступ с Ваших адресов туда, куда, по Вашему мнению, можно.

Авторизация пользователей прокси (ncsa_auth)

Чтобы включить проверку имени и пароля на сквиде, нужно отредактировать squid.conf:

# TAG: authenticate_program

authenticate_program /usr/local/squid/bin/ncsa_auth /usr/local/squid/etc/passwd

# TAG: acl

# Defining an Access List

acl users proxy_auth REQUIRED

# TAG: http_access

http_access allow users

Этим Вы даете понять сквиду, что Ваша authenticate_program находится по пути /usr/local/squid/bin/ncsa_auth и работает с файлом паролей /usr/local/squid/etc/passwd. Листы доступа настроены в приведенном выше примере на разрешение доступа для всех пользователей, находящихся в файле passwd.

Вносить изменения в файлы паролей можно с помощью программы HTPASSWD, описание которой приводится ниже.

proxy# ./htpasswd

Usage: htpasswd [-cm] passwordfile username

The -c flag creates a new file.

The -m flag forces MD5 encryption of the password.

On Windows systems the -m flag is used by default.

Если пользователь уже есть в файле passwd, то команда ./htpasswd passwd user newpassword просто изменяет предыдущий пароль на новый. Удалить пользователя из файла passwd можно прямым удалением строки из этого файла с помощью любого текстового редактора.

Авторизация пользователей прокси (ncsa_auth) с привязкой к IP-адресу

Иногда бывает нужно осуществить привязку пользователя squid к его IP-адресу, т.е. чтобы человек со своим логином/паролем мог выйти в Интернет только со своей машины. Для этого нужно изменить процедуру проверки данных пользователя на прокси. Автор sqmgrlog'а сделал соответствующие изменения со стандартным модулем ncsa_auth, о чем можно подробно прочесть здесь.

А чтобы полностью "закрепить" пользователя, можно использовать привязку IP-адреса к MAC-адресу его сетевой карты (см. здесь) или использовать ARP_ACL (см. здесь).

Если Вы интересуетесь различными схемами проверки имени/пароля, то советую сходить на страницу Squid ACL Proxy Authentication with External Programs.

Настройка для работы из под Firewall

Чтобы настроить squid для работы из-под firewall, необходимо отредактировать несколько тэгов в squid.conf:

# TAG: cache_peer

cache_peer 192.168.0.1 parent 80 0

# где 192.168.0.1 - ip-адрес Вашего firewall'а, 80 - порт, открытый на нем для http

# TAG: append_domain

append_domain .yourdomain.com # Ваш домен

# TAG: always_direct

# Usage: always_direct allow|deny [!]aclname ...

# TAG: never_direct

# Usage: never_direct allow|deny [!]aclname ...

acl all src 0.0.0.0/0.0.0.0

acl internal src 192.168.0.0/0.0.0.0 # Ваша внутренняя сеть

acl external src x.x.x.0/0.0.0.0 # Ваша внешняя сеть

acl SSL method CONNECT # Включаем поддержку SSL из-под firewall

always_direct deny external

always_direct allow internal

never_direct allow SSL

never_direct allow all

Добавление!

Если Вы имеете внутренний поддомен sub.domain.ru под основным domain.ru, то возможна следующая конфигурация:

acl local-external dstdomain domain.ru

acl local-servers dstdomain sub.domain.ru

always_direct deny local-external

always_direct allow local-servers

never_direct allow all

{Прислал info@legacy.ru}

Ключи командной строки squid

proxy% ./squid -h

Usage: squid [-dhsvzCDFNRVYX] [-f config-file] [-[au] port] [-k signal]

-a port Specify HTTP port number (default: 3128).

-d level Write debugging to stderr also.

-f file Use given config-file instead of

/usr/local/squid/etc/squid.conf

-h Print help message.

-k reconfigure|rotate|shutdown|interrupt|kill|debug|check|parse

Parse configuration file, then send signal to

running copy (except -k parse) and exit.

-s Enable logging to syslog.

-u port Specify ICP port number (default: 3130), disable with 0.

-v Print version.

-z Create swap directories

-C Do not catch fatal signals.

-D Disable initial DNS tests.

-F Foreground fast store rebuild.

-N No daemon mode.

-R Do not set REUSEADDR on port.

-V Virtual host httpd-accelerator.

-X Force full debugging.

-Y Only return UDP_HIT or UDP_MISS_NOFETCH during fast reload.

После редактирования squid.conf (squid запущен) нужно сделать squid -k reconfigure.

Чтобы обновить (обнулить) log-файлы, запустите squid - k rotate.

Первый раз squid нужно запускать с ключом -z, после чего можно работать с ним в нормальном режиме (о запуске из rc.local смотрите выше).

Версия squid'а смотрится с ключом -v.

Добавление: настройка squid.conf для работы из под Firewall для версий выше 2.3

Путем экспериментов выяснено, что начиная с версии 2.4 в файле squid.conf в строчку cache_peer необходимо добавлять no-query default:

cache_peer your_firewall_ip parent 80 0 no-query default

Хотя в изменениях по данной версии это не написано :-(

Добавление: Авторизация пользователей прокси (ncsa_auth) с привязкой к IP-адресу

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

user:password:changed_date:ip_address

При желании новые поля заполняем звездочкой и работаем как прежде. То есть привязки к IP и дате нет. Если у Вас очень большой файл паролей, и Вы не хотите долбить все ручками, возмите скриптик, который за Вас добавляет в каждую строчку парольного файла ":*:*".

Обновлено: 13.03.2015