Вперед Назад Содержание

10. Контроль доступа

10.1 Введение

Схема контроля доступа в Squid достаточно развита и тяжела для понимания некоторым людям. Она состоит из двух различных компонентов: элементов ACL и списков доступа. Список доступа состоит из директивы allow или deny и указанных вслед за ней элементов ACL.

элементы ACL

Замечание: Информация, представленная здесь верна для версии 2.4.

Squid-у известны следующие типы элементов ACL:

Заметьте:

Не все элементы ACL могут быть использованы со всеми видами списков доступа (описаны ниже). К примеру, snmp_community предназначено для использования только совместно с snmp_access. Типы src_as и dst_as используются только в списках доступа cache_peer_access.

Тип arp элемента ACL требует специально опции --enable-arp-acl. Кроме того, код ARP ACL портируется не на все операционные системы. Это работает на Linux, Solaris, и некоторых *BSD системах.

Элемент ACL SNMP и список доступа требуют конфигурационной опции --enable-snmp .

Некоторые элементы ACL могут вносить задержки в работу кеша. Например, использование src_domain и srcdom_regex требует обратного преобразования клиентского IP. Это преобразование вносит некоторую задержку в обработку запроса.

Каждый элемент ACL обозначается уникальным именем. Имя элемента ACL содержит список значений. Когда проверяется совпадения для нескольких значений, используется логическое "ИЛИ". Другими словами, элемент ACL совпал, когда совпало одно из значений.

Вы не можете указывать одинаковое имя для двух различных типов элементов ACL. Это вызовет синтаксическую ошибку.

Вы можете присваивать различные значения одному и тому же ACL в различных строках. Squid объединит их в один список.

Списки доступа

Существуют следующие типы списков доступа:

Замечание:

Правило списка доступа состоит из слова allow или deny, с последующим указанием списка имен элементов ACL.

Список доступа состоит из одного или более правил списков доступа.

Правила списков доступа проверяются в порядке их объявления. Поиск по списку прекращается, как только одно из правил совпадает.

Если правило содержит несколько элементов ACL, используется логическое И. Другими словами, все элементы ACL, указанные в этом правиле должны совпасть, чтобы правило сработало. Это значит, что есть возможность написать правило, которое никогда не сработает. К примеру, номер порта никогда не может быть равен 80 И 8000 одновременно.

Если ни одно из правил не сработало, по умолчанию будет произведено действие обратное указанному в последнем правиле списка. Поэтому хорошей идеей будет явно указать действие по умолчанию. Наилучший выбор для этого - ACL all. Например:

        acl all src 0/0
        http_access deny all

10.2 Как мне разрешить моим клиентам использовать кеш?

Объявите ACL, описывающий IP-адреса клиентов. К примеру:

        acl myclients src 172.16.5.0/24
Далее разрешите доступ этим клиента при помощи списка http_access:
        http_access allow myclients

10.3 Как мне настроить Squid, чтобы он не кешировал определенный сервер?

        acl someserver dstdomain .someserver.com
        no_cache deny someserver

10.4 Как мне организовать ACL списка запрета?

Предположим, к примеру, что вы желаете избавить пользователей от доступа к рецептам.

Первый способ - запретить любой URL, содержащий слова ``cooking'' или ``recipe.'' Вы могли бы использовать следующую конфигурацию:

        acl Cooking1 url_regex cooking
        acl Recipe1 url_regex recipe
        http_access deny Cooking1
        http_access deny Recipe1
        http_access allow all
url_regex обозначает - искать указанное вами регулярное выражение в поступившем URL. Заметьте, что это регулярное выражение чувствительно к регистру символов, т.е. URL, содержащие ``Cooking'' не будут запрещены.

Другой путь - запретить доступ к определенным серверам, если известно что они хранят рецепты. К примеру:

        acl Cooking2 dstdomain gourmet-chef.com
        http_access deny Cooking2
        http_access allow all
dstdomain значит искать строку ``gourmet-chef.com.'' и имени хоста в URL. Заметьте, что когда в URL используется IP-адрес (вместо имени домена), Squid-1.1 выполняет смягченный контроль доступа(?). Если имя домена для IP-адреса было сохранено Сквидом в ``FQDN cache,'' то Squid может сравнивать домен назначения с контролем доступа. Однако, если домен недоступен немедленно, Squid разрешит запрос и сделает преобразование IP-адреса, которое будет доступно для будущих запросов.

10.5 Как мне блокировать доступ к кешу определенным пользователям и группам?

Ident

Вы можете использовать ident lookups чтобы разрешить доступ к вашему кешу определенным пользователям. Это потребует запуска процесса ident server на клиентской машине(ах). В вашем конфигурационном файле squid.conf вам необходимо будет написать нечто подобное:

        ident_lookup on
        acl friends user kim lisa frank joe
        http_access allow friends
        http_access deny all

Proxy Authentication

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

В Squid вер.2 аутентификация производится через внешний процесс. Информацию о том как это настроить это см. в разделе Настройка аутентиикации.

10.6 А у вас есть CGI-программа, позволяющая пользователям менять свой пароль доступа к прокси?

Pedro L Orso переделал htpasswd от Apache в CGI-скрипт, называемый chpasswd.cgi.

10.7 Есть ли способ осуществлять поиск ident только для определенного хоста и сравнивать результат со списком пользователей в squid.conf?

Sort of.

Если вы используете ACL типа user в squid conf, то Squid будет выполнять ident lookup для каждого клиентского запроса. Другими словами, Squid-1.1 выполняет ident поиск для всех запросов или не выполняет вообще. Объявление ACL типа user включает поиск ident, вне зависимости от значения ident_lookup.

Однако, хотя запросы ident выполняются для каждого запроса, Squid не ожидает их завершения, если ACL того не требует. Взгляните на следующую конфигурацию:

        acl host1 src 10.0.0.1
        acl host2 src 10.0.0.2
        acl pals  user kim lisa frank joe
        http_access allow host1
        http_access allow host2 pals
Запросы, пришедшие с 10.0.0.1, будут разрешены немедленно, т.к. не указано пользователя для этого хоста. Однако запросы с 10.0.0.2 будут разрешены только после завершения поиска ident и если установлено, что имя пользователя kim, lisa, frank или joe.

10.8 Типичные ошибки

Логическое И/ИЛИ

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

К примеру, следующая конфигурация контроля доступа никогда не будет работать:

        acl ME src 10.0.0.1
        acl YOU src 10.0.0.2
        http_access allow ME YOU

Для того, чтобы запрос был разрешен, он должен совпасть и с acl ``ME'' И acl ``YOU''. Это невозможно, т.к. IP-адрес в данном случаю может совпасть либо с одним, либо с другим acl. Это должно быть заменено на:
    
        acl ME src 10.0.0.1
        acl YOU src 10.0.0.2
        http_access allow ME
        http_access allow YOU

Такая конструкция тоже должна работать:

        acl US src 10.0.0.1 10.0.0.2
        http_access allow US

перепутанные allow/deny

Я перечитал несколько раз мой squid.conf, поговорил с коллегами, почитал FAQ и документацию по Squid Docs и никак не могу понять, почему следующее не работает.

Я успешно подключаюсь к cachemgr.cgi с нашего web-сервера, но хотелось бы использовать MRTG для мониторинга различных параметров нашего прокси. Когда я пытаюсь использовать 'client' или GET cache_object с машины, на которой работает прокси, то всегда получаю "доступ запрещен".

        acl manager proto cache_object
        acl localhost src 127.0.0.1/255.255.255.255
        acl server    src 1.2.3.4/255.255.255.255
        acl all src 0.0.0.0/0.0.0.0
        acl ourhosts src 1.2.0.0/255.255.0.0

        http_access deny manager !localhost !server
        http_access allow ourhosts
        http_access deny all

Приведенная здесь задача состоит в том, чтобы разрешить запросы кеш-менеджера с адресов localhost и server и запретить все остальные. Такая политика описывалась правилом:

        http_access deny manager !localhost !server

Проблема состоит в разрешении запроса, правило доступа не срабатывает. К примеру, если IP-адрес источника localhost, тогда ``!localhost'' - ложь и правило доступа не срабатывает, Squid продолжает проверять другие правила. Запросы к кеш-менеджеру с адреса server работают, т.к. server находится в подсети ourhosts, сработает второе правило и запрос будет разрешен. Это значит также, что любой запрос кеш-менеджера из ourhosts будет разрешен.

Чтобы необходимая политика работала корректно, правила доступа должны быть переписаны следующм образом

        http_access allow manager localhost
        http_access allow manager server
        http_access deny manager
        http_access allow ourhosts
        http_access deny all

Если вы используете miss_access, не забывайте также добавить правило miss_access для кеш-менеджера:

        miss_access allow manager

Вы можете быть обеспокоены тем, что пять правил взамен трех могут нанести удар по качеству работы кеша. Исходя и нашего опыта, можно сказать, что этого не произойдет. Squid в состоянии поддерживать достаточное количество проверок контроля доступа без снижения качества работы. Можете проверить это самостоятельно.

Различия между src и srcdomain типами ACL.

Для типа ACL srcdomain Squid делает обратное преобразование клиентского IP-адреса и проверяет соответствие результата домену, описанному в строке acl. Для типа ACL src Squid вначале преобразует имя хоста в IP-адрес и только потом сравнивает с клиентским IP. Тип ACL src предпочтительнее, чем srcdomain, т.к. он не требует преобразования адреса в имя при каждом запросе.

10.9 Я установил собственные контроли доступа, но они не работают! Почему?

Если ACL-лы - причина ваших проблем и вы не знаете почему они не работают, вы можете воспользоваться этой инструкцией, чтобы отладить их.

В squid.conf включите отладку для секции 33 на уровне 2. К примеру:

debug_options ALL,1 33,2
Потом перезапустите Squid.

Теперь, ваш cache.log должен содержать строку для каждого запроса, которая поясняет запрещен или разрешен запрос и с каким ACL он совпал.

Если это не дало вам достаточно информации, чтобы избавиться от проблемы, вы можете также включить детальную отладку процесса обработки ACL

debug_options ALL,1 33,2 28,9
Перезапустите Squid.

Теперь ваш cache.log должен содержать детальную трассировку всего процесса контроля доступа. Будте внимательны, на каждый запрос будет по несколько строк.

См. также 11.20 Отладка Squid

10.10 Прокси-аутентификация и братские кеши

Проблема...

                       [ Parents ]
                       /         \
                      /           \
               [ Proxy A ] --- [ Proxy B ]
                   |
                   |
                  USER

Proxy A посылает ICP-запрос на Proxy B о объекте, Proxy B отвечает ICP_HIT. Proxy A перенаправляет HTTP-запрос к Proxy B, но не проходит аутентификация, а посему HTTP GET для Proxy A завершается неудачно.

Только ОДНОМУ кешу в цепочке разрешено ``использовать'' заголовок Proxy-Authentication в запросе request . Если такой заголовок имел место , то он не должен быть пропущен другим прокси.

Поэтому вы должны разрешить братским кешам опрашивать друг друга без прокси-аутентификации. Это просто выполнить указав список ACL братских кешей прежде списков доступов в строках http_access. К примеру:

        acl proxy-A src 10.0.0.1
        acl proxy-B src 10.0.0.2
        acl user_passwords proxy_auth /tmp/user_passwds

        http_access allow proxy-A
        http_access allow proxy-B
        http_access allow user_passwords
        http_access deny all

10.11 Какой самый простой способ запретить все адреса назначения кроме одного?

        acl GOOD dst 10.0.0.1
        acl BAD dst 0.0.0.0/0.0.0.0
        http_access allow GOOD
        http_access deny BAD

10.12 Кто-нибудь имеет списки порно-сайтов и прочего?

10.13 Squid не распознает мой поддомен

Есть хитрая проблема с контролем доступа, основанным на имени домена, когда один элемент ACL является поддоменом другого элемента. К примеру, взгляните на такой список:

        acl FOO dstdomain boulder.co.us vail.co.us co.us

Прежде всего - формат списка просто неверен, потому-что первые два элемента (boulder.co.us и vail.co.us) не нужны. Любое имя домена, которое совпадает с первыми двумя элементами, совпадет и с последним (co.us). Хорошо, но почему это происходит ?

Корень проблемы в структуре данных для индексирования доменных имен в списках контроля доступа. Squid использует Splay trees для списка доменных имен. Как и другие структуры данных в виде дерева, алгоритм поиска требует функции сравнения, которая возвращает -1, 0 или +1 для любой пары ключей (доменных имен). Это подобно тому как работает strcmp().

Проблема в том, что нельзя сказать, что co.us больше чем, равно или меньше чем boulder.co.us.

К примеру, если вы утверждаете, что co.us МЕНЬШЕ чем fff.co.us, то алгоритм поиска по Splay-дереву может никогда не обнаружить совпадения co.us для kkk.co.us.

Аналогично, если вы говорите, что co.us БОЛЬШЕ чем fff.co.us, то алгоритм поиска по Splay-дереву может никогда не обнаружить совпадения co.us для bbb.co.us.

Суть в том, что вы не можете указать значение, которое является поддоменом другого значения. Squid-2.2 сообщит вам, если обнаружит подобное условие.

10.14 Почему Squid запрещает доступ к некоторым портам?

Это опасно - разрешать Squid соединятся по определенным номерам портов. Демонтсрацией этого может послужить использование Squid кем-либо как SMTP (email) релея. Уверен, что вы знаете, что SMTP релей - один из способов, при помощи кторого спамеры имеют возможность засорять почтовые ящики. Что бы предотвратить релей почты, Squid запрещает запросы в URL которых указан порт номер 25. Для предосторожности другие порты также должны быть блокированы.

Есть два способа фильтрации по номерам портов: либо разрешить определенные порты, либо запретить определенные порты. По умолчанию Squid использует первый вариант. Вот ACL-лы, которые присутствуют по умолчанию в squid.conf:

        acl Safe_ports port 80 21 443 563 70 210 1025-65535
        http_access deny !Safe_ports
Указанная выше конфигурация блокирует запросы номер порта в URL которых не совпадает со списком. Разрешен список стандартных портов для HTTP, FTP, Gopher, SSL, WAIS, а также непривелигерованых портов.

Другой подход - запретить опасные порты. Список опасных портов должен выглядеть примерно так:

        acl Dangerous_ports 7 9 19 22 23 25 53 109 110 119
        http_access deny Dangerous_ports
...и возможно некоторые другие.

Загляните в файл /etc/services вашей системы, чтобы получить полный список портов и протоколов.

10.15 А Squid поддерживает использование базы данных типа mySQL для хранения списков ACL?

Замечание: Информация верна для версии 2.2.

Нет, не поддерживает.

10.16 Как мне разрешить доступ к определенному URL только с одного адреса?

Этот пример разрешает доступ к special_url только для special_client. Любому другому клиенту доступ к special_url запрещен.

        acl special_client src 10.1.2.3
        acl special_url url_regex ^http://www.squid-cache.org/Doc/FAQ/$
        http_access allow special_client special_url
        http_access deny special_url

10.17 Как мне разрешить некоторым клиентам использовать кеш в определенное время ?

Скажем у вас есть две рабочие станции, для которых доступ в Интернет должен быть разрешен только в рабочее время (8:30 - 17:30). Вы можете использовать нечто подобное:

acl FOO src 10.1.2.3 10.1.2.4
acl WORKING time MTWHF 08:30-17:30
http_access allow FOO WORKING
http_access deny FOO

10.18 Как мне разрешить некоторым пользователям использовать кеш только в определенное время?

acl USER1 proxy_auth Dick
acl USER2 proxy_auth Jane
acl DAY time 06:00-18:00
http_access allow USER1 DAY
http_access deny USER1
http_access allow USER2 !DAY
http_access deny USER2

10.19 Проблемы с IP ACL-ми, содержащими сложные маски

Замечание: представленная здесь информация верна для версии 2.3.

Следующий ACL дает противоречивый или неожиданный результат:

        acl restricted  src 10.0.0.128/255.0.0.128 10.85.0.0/16
Причина в том, что IP-список доступа помещается в структуру данных в виде ``splay''-дерева. Это дерево требует сортировки ключей. Когда вы указываете сложную или нестандартную маску (255.0.0.128), это приводит к неверной работе функции сравнивающей пару адрес/маска.

Лучшее решение избавится от проблемы - использовать отдельные имена ACL для каждого значения ACL. Например, измените вышеуказанное на :

        acl restricted1 src 10.0.0.128/255.0.0.128
        acl restricted2 src 10.85.0.0/16

При этом, конечно, вам придется переписать ваши правила http_access.

10.20 Могу ли я устанавливать ACL-лы, основанные на MAC-адресах, а не на IP?

Да, для некоторых операционных систем. В Squid это называется ``ARP ACLs'' и поддерживается на Linux, Solaris и возможно для BSD вариантов.

ЗАМЕЧАНИЕ: Squid может определить MAC-адрес клиента только для своей подсети. Если клиент находится в другой подсети, Squid не сможет найти его MAC-адрес.

Чтобы использовать контроль доступа по ARP (MAC), вам прежде всего необходимо скомпилировать Squid c поддержкой этой возможности. Это делается при помощи конфигурационной опции --enable-arp-acl:

% ./configure --enable-arp-acl ...
% make clean
% make
Если src/acl.c не компилируется, значит возможно ARP ACL не поддерживается вашей системой .

Если все откомпилировалось, вы можете добавить несколько строк ARP ACL в ваш squid.conf:

acl M1 arp 01:02:03:04:05:06
acl M2 arp 11:12:13:14:15:16
http_access allow M1
http_access allow M2
http_access deny all

10.21 Отладка ACL

См. 10.9 Я установил собственные контроли доступа, но они не работают! Почему? и 11.20 Отладка Squid.

10.22 Могу ли я ограничить количество соединений для клиента?

Да, используйте ACL типа maxconn совместно с http_access deny. К примеру:

acl losers src 1.2.3.0/24
acl 5CONN maxconn 5
http_access deny 5CONN losers

Учитивая вышеописанную конфигурацию, когда клиент, чей IP-адрес находится в сети 1.2.3.0/24, попытается установить 6 или более соединений за одни раз, Squid вернет сообщение о ошибке. Пока вы не используете возможности deny_info, сообщение о ошибке будет звучать как ``access denied.''

ACL типа maxconn требует использования client_db . Если вы отключили client_db (к примеру, использовав client_db off) то ACL maxconn не будет работать.

Заметьте, что ACL типа maxconn достаточно специфичен из-за использования сравнения "меньше чем". ACL считается совпавшим, когда количество установленных соединений больше величины, которую вы указали. Исходя из этого вы вряд ли захотите использовать ACL типа maxconn в http_access allow.

Заметьте также, что вы вы должны объявлять maxconn совместно с типом пользователя (ident, proxy_auth) раньше, чем объявляется тип по IP-адресу.

10.23 Я пытаюсь запретить доступ к foo.com, но это не срабатывает.

В Squid-2.3 мы изменили схему, по которой Squid определяет совпадение поддоменов. Есть разница между .foo.com и foo.com. В первом случае описано соответствие любого домена в foo.com, во втором - это только точное соответствие ``foo.com'' . Т.е., если вы хотите запретить bar.foo.com, вы должны указать

acl yuck dstdomain .foo.com
http_access deny yuck

10.24 Я хочу изменить или создать собственное сообщение о ошибке.

Вы можете изменять существующие сообщения об ошибках как описано в Пользовательские сообщения об ошибках. Вы также можете создавать новые сообщения о ошибках и использовать их совместно с опцией deny_info.

К примеру, предположим, что вы хотите, чтобы ваши пользователи видели специальное сообщение, когда их запрос совпадает с вашим списком порно. Прежде всего создайте файл с именем ERR_NO_PORNO в директории /usr/local/squid/etc/errors. Этот файл должен содержать нечто подобное:

<p>
Our company policy is to deny requests to known porno sites.  If you
feel you've received this message in error, please contact 
the support staff (support@this.company.com, 555-1234).

Далее, установите следующий контроль доступа:

acl porn url_regex "/usr/local/squid/etc/porno.txt"
deny_info ERR_NO_PORNO porn
http_access deny porn
(остальные опции http_access ...)

10.25 Я хочу видеть локальную временную зону в сообщениях о ошибке

По умолчанию Squid использует временную метку в GMT для всех генерируемых сообщений о ошибках. Это опозволяет кешу состоять в иерархии кешей из различных временных зон без риска запутаться в определении времени.

Чтобы изменить временную метку в генерируемых Squid сообщениях о ошибке, вам необходимо изменить подпись Squid. См. Пользовательские осообщения о ошибках. В подписи по умолчанию временная метка указана как %T, но если вам хочется использовать локальную временную зону во временной метке, вы можете указать взамен этого параметр %t.


Вперед Назад Содержаие