воскресенье, 19 октября 2008 г.

Система фильтрации интернет траффика на основе squidGuard + Apache + Squid + Berkeley DB

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

Вы можете спросить зачем нам нужны все эти сложности? Как любой другой ресурс интернет траффик имет обыкновение заканчиваться. Да и канал от нас к провайдеру не резиновый, Отсюда вывод - необходимо тем или иным образом ограничить аппетиты пользователей. С другой стороны если начальство поймает кого-то из сотрудников за просмотром порносайтов или скачиванием mp3, нагоняй получит не только провинившийся. Администратор будет виноват в том, что позволяет пользователям тратить оплачиваемый организацией трафик на всякую ерунду. В тоже время стоит помнить что разные организации могут иметь различные правила пользования интернет. Довольно часто в списке запретов можно встретить не только эротику, но и сайты анекдотов, форумы и чаты. Например бесплатные почтовые сайты могут быть запрещены из сображения секретности. Одновремнно можно запретить пользователям скачивать из наружной сети исполняемые файлы, видеофайлы и музыку. Запрещение скачивания исполняемых файлов существено снижает опасность вирусного заражения сети и возможно позволит сэкономить на антивирусах.

В тоже время перед нами все еще стоит задача экономии траффика. Существенно снизить его потребление поможет запрещение бесполезной для нас баннерной рекламы. Вы могли бы спросить что в баннерах плохого? Squid - кеширующий прокси соответственно скачиваемые файлы ложатся в локальный кэш. При следующих запросах эти файлы уже не будут скачиваться из интернета. Проблема в том что баннерная реклама построена на применении механизма CGI. CGI (Common Gateway Interface) - расшифровыается как Общий интерфейс шлюза. Характерным признаком CGI является использование знака “?” в адресной строке запроса. Например адрес одного из баннеров Украинской баннерной сети выглядит так :

http://banner.kiev.ua/cgi-bin/bi.cgi?h" + user + "&"+ pid + "&" + page + "&2

К сожалению CGI используется не только для баннерной рекламы, но и для чатов, форумов, сетевых магазинов и прочей полезной сетевой функциональности. То есть везде где необходимо получить от пользователя данные. Затем полученне данные должны быть обработаны, а результаты работы CGI необходимо вернуть пользователю. Значит для каждого пользователя не только запросы, но и ответы будут разные. Поэтому класть полученые документы в кэш squid бесполезно. По умолчанию squid не использует кэш при работе с динамическими документами. В свою очередь это значит, что одни и те же баннеры будут выкачиваться бесконечно. Резко снизить количество потребляемого траффика можно подменяя банеры пустыми картинками с локального Web сервера. А мультимедий файлы скачиваемые пользователями можно подменять на лету своими собственными заготовками, что позволит донести до пользователя добавочную информацию. Только представьте себе пользователь качает музыку в формате mp3 запускает ее в winamp и слышит строгий голос директора отчитыващий его за такое хулиганство.

Обоснование выбора редиректора SquidGuad

Многие администраторы уже столкнувшиеся с вышеописанным комплексом проблем могут утверждать, что они легко решатся с помощью штатных средств Squid. Я не стану отрицать что Access Control List (Списки контроля доступа) сокращенно ACL, используемые в Squid это довольно мощный инструмент. Но для работы с ним требуется достаточно большой опыт. С другой стороны трудно представить каким образом администратор будет разбираться какие сайты он должен блокировать. Остается только всед за пользователями ходить на все часто посещаемые сайты, и постепенно запрещать неугодных. Учитывая количество сайтов интернет, а так же распространенность баннерной рекламы такой путь выглядит утопией. В начале такого ошибочного пути кажется что нужно всего лишь записывать все запрещенные сайты в отдельные файлы с помошью ACL записей типа:

acl porno src "/usr/local/squid/etc/porno.lst"
acl erotic src “/usr/local/squid/etc/erotic.lst”

А затем запрещать их всех скопом. Но обслуживание такой системы способно превратиться в головную боль уже на первой тысячи сайтов. Squid загружает списки контроля доступа в оперативную память. С добавлением новых сайтов размер файла будет постоянно расти. Соответственно и Squid будет занимать все больше оперативной памяти. В связи с тем что список запрещенных сайтов не упорядочен поиск в нем будет занимать довольно продолжительное время.

Для сравнения редиректор Squidguard выполняет за 12 секунд 100.000 запросов к базе содержащей 205.900 записей. Тестирование проводилось на машине с процессором Pentium 500MHz. Такой скорости удается добиться за счет того, что SquidGuard хранит список сайтов в форме B-дерева. Как мы видим средствами Squid все вышеописанное выполнить достаточно тяжело. И тут в поле нашего внимания попадает класс программ под названием редиректоры. С разной степенью легкости эти программы позволяют решать наши проблемы.

В качестве кандидатов на место SquidGuard претендовали squirm и Jesred. После тестирования от squirm пришлось отказаться, потому что список фильтрации поддерживается всего один на всех пользователей. Соответственно запретить что-либо конкретному пользователю не представляется возможным. Запрещать приходится либо всем, либо никому. К тому же список сайтов приходится хранить в виде довольно сложных и неудобных для восприятия регулярных выражений. По моему мнению, такое ограничение не позволяет использовать squirm в сетях средних и больших размеров.
Затем мне под руку попался Jesred. Несмотря на то, что Jesred является модернизированным потомком squirm и имеет более гибкий синтаксис файла шаблонов, он все еще страдает от тех же детских проблем. Единственное улучшение в этой области достаточно высокая скорость работы и возможность пропускать запросы некоторых пользователей без фильтрации. Как Вы понимает в этом случае ни о каком гибком разграничении полномочий пользователей и речи быть не может.

Используемый нами SquidGuard тоже является редиректором. Давайте коротко опишем его возможности.

* может разрешить доступ некоторой группе пользователей только к некоторым сайтам
* блокирует доступ пользователей к определенному списку адресов
* позволяет запретить доступ к определенному списку адресов
* помогает блокировать доступ к сайтам на основе списка регулярных выражений
* запрещает пользователям использовать IP адреса вместо доменных имен внутри URL
* позволяет запретить доступ к определенному списку адресов
* дает возможность перенаправить пользователей, пытающихся получить доступ к запрещенным страницам, на другую страницу, где им будет объяснена причина запрета
* помогает перенаправить запросы на доставку часто скачиваемый файлов, таких как MSIE, Netscape Navigator или ICQ, к их локальным копиям
* позволяет использовать разные политики доступа в зависимости от времени дня, текущей даты, дня недели
* дает возможность гибкой настройки процесса протоколирования обрабатываемых запросов

Платформа и вспомогательное ПО

Ну что же, теперь когда с формальностями и изучением начальной теории покончено, приступим к установке.
Как я уже говорил строить нашу систему фильтрации мы будем на основе FreeBSD 4.5 + Squid + SquidGuard + Berkeley DB 3.2.9 + Apache.

Стоит отметить что обсуждаемые в этой статье приемы будут работать и на основе Linux. В принципе такой комплекс можно построить на любой Unix совместимой системе. Главной проблемой будет неоходимость найти версии SquidGuard и Squid для этой системы. Вместо Apache можно использовать любой другой Web сервер. Кстати Web сервер можно запустить на одельной машине под управлением любой операционной системы. В то же время можно использовать уже существующий Web сервер. Не стоит отчаиваться, если база данных Berkeley DB еще не портирована для Вашей платформы. SquidGuard легко может работать и без нее. Я думаю, нижеприведенных инструкций по настройке Apache и Squid хватит, что бы установить их в комплектации по умолчанию. Для получения более подробных сведений вам стоит посетить следующие сайты:

http://apache.lexa.ru
http://www.squid-cache.org
http://squid.opennet.ru

В процессе компиляции всего програмного обеспечения вместо стандартного make мною использовался gmake, но это опять же вопрос личных предпочтений. Мне кажется, что gmake работает стабильнее и быстрее.

Установка и настройка Squid

В качестве прокси сервера я использовал squid 2.5.STABLE1. На момент написания статьи это была самая свежая версия. Рекомендуется всегда использовать самые новейшие из стабильных версий программ. Такой подход позволит в дальнейшем избежать многих проблем со стабильностью и безопасностью работы той или иной программы.

# tar zxvf squid-2.5.STABLE1-src.tar.gz
# cd squid-2.5.STABLE1
# ./configure
# gmake
# gmake install

После инсталяции редактируем файл конфигурации squid, находящийся в /usr/local/squid/etc/squid.conf.
Должно получиться примерно следующее:

http_port 3128 # Обрабатывать запросы на порт 3128
hierarchy_stoplist cgi-bin ? # Запрещаем кэшировать CGI
acl QUERY urlpath_regex cgi-bin \?
no_cache deny QUERY
cache_mem 64 MB # Размер оперативной памяти отводимой под кэш
error_directory /usr/local/squid/share/errors/Russian-koi8-r #Тут мы будем брать файлы стандартных сообщений об ошибках
maximum_object_size 16384 KB # Максимальный размер объекта записываемого в кэш
cache_dir ufs /usr/local/squid/cache 5000 16 256 # Здесь у нас будет храниться кэш. Отводим под него места 5000 мгб. Приказываем создать 16 директорий первого уровня и 256 второго уровня.
cache_access_log /usr/local/squid/logs/access.log # Протокол доступа к кэшу
cache_log /usr/local/squid/logs/cache.log # Тут находится протокол работы кэша
cache_store_log /usr/local/squid/logs/store.log # Протокол работы менеджера кэша
ftp_user vasa@pupkin.ru # Под этим пользователем будем ходить по Ftp
quick_abort_pct 60 # Если Squid уже скачал 60% файла, а пользователь отказался его забирать, то все равно продолжать скачивать файл.
negative_ttl 1 minutes # Время жизни запросов завершившихся ошибкой. Например “connection refused” или “404 Not Found”
positive_dns_ttl 6 hours # Время жизни успешного DNS запроса.
negative_dns_ttl 5 minutes # Время жизни DNS запросов завершившихся ошибкой.
half_closed_clients on Поддержка нестандартных Http клиенттов
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 # Ssl
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 563 # https, snews
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
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 users src “/usr/local/squid/etc/users.txt” # описываем наших пользователей
http_access allow manager localhost # Разрешаем соединения только по правильным портам. И раздаем всем права доступа
http_access deny manager
http_access deny !Safe_ports
http_access allow users
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny all
cache_mgr root@test.ru # Адрес пользователя которого будут уведомлять о переполнении кэша
cache_effective_user nobody # Пользователь от имени которого будет работать Squid
cache_effective_group nogroup # Группа от имени которой будет работать Squid
forwarded_for on # Включать ли IP адресс клиента в заголовок Http запроса
cachemgr_passwd passwd all # Разрешаем управлять кэшем с помощью cachemgr.cgi. В качестве пароля будем использовать слово “passwd”
client_db on # Включаем сбор статистики по каждому клиенту

Обращаю Ваше внимание на строку acl users src “/usr/local/squid/etc/users.txt”. Она означает, что список пользователей, которым разрешен доступ к squid, находится в файле /usr/local/squid/etc/users.txt

Файл списка имеет следующий формат:

#Петрова Наталья (Снабжение)
192.168.10.91/32
#Иванов Владимир (Доставка)
192.168.10.92/32
#Сергеев Игорь (Плановый отдел)
192.168.10.93/255.255.255.255
#Кривоухина Ирина (Лаборатория)
192.168.10.94/255.255.255.255
#Синицына Светлана (секретарь генерального директора)
192.168.10.95/255.255.255.255

Реально в списке содержатся не имена пользователей, а IP адреса их машин. Как Вы смогли убедиться все устроено достаточно просто. Отдельный файл со списком пользователей решено использовать, что бы не захламлять главный конфигурационный файл. Users.txt должен иметь те же права доступа, что и squid.conf для того что бы squid мог читать его содержимое.

# chown nobody:nogroup /usr/local/squid/etc/users.txt

Возможен и другой вариант управления доступом к web. При этом доступ в наружнюю сеть средствами squid не ограничивается. Разграничением доступа в этом случае будет заниматься SquidGuard. Для тех пользователей, чей адрес не внесен в файл /usr/local/squidGuard/squidGuard.conf, производится перенаправление на страницу запрещения. Соответственно, эти пользователи никогда интернета не увидят. Чтобы добиться такого эффекта, нужно удалить из squid.conf строки:

acl users src "/usr/local/squid/etc/users.txt"
http_access allow users
http_access deny all

И добавить в squid.conf вместо них строку

http_access allow all

Мне больше нравится второй вариант разграничения доступа. Если использовать традиционную схему разграничения прав, то проверка прав доступа происходит дважды. Сначала внутри Squid а затем в SquidGuard. Мне кажется что управлять доступом в одной точке, вместо двух гораздо удобнее. Но это опять же дело вкуса и эстетика чистейшей воды.

Настало время создать директорию, в которой у нас будет храниться кэш squid.

# mkdir /usr/local/squid/cache

А тут у нас будут лежать журналы работы Squid.

# mkdir /usr/local/squid/logs

Нужно позаботиться, чтобы директории /usr/local/squid/cache и /usr/local/squid/logs были доступны пользователю, от имени которого работает squid. Узнать имя этого пользователя можно так:

# cat /usr/local/squid/etc/squid.conf | grep cache_effectiv
cache_effective_user nobody
сache_effective_group nogroup

Получается, что пользователя зовут nobody, и группа у него nogroup.

# chown -R nobody /usr/local/squid/cache /usr/local/squid/logs
# /usr/local/squid/sbin/squid -z

Внутри директории /usr/local/squid/cache создаем иерархию директорий для хранения кэш файлов. Заглянув в /usr/local/squid/cache, вы сразу поймете, что имелось в виду под словом иерархия.

Запускаем squid.

# /usr/local/squid/sbin/squid -D

А на другой консоли смотрим, какие сообщения об ошибках появляются в файле протокола.

# tail -f /var/log/messages

Если все сделали правильно, то ошибок мы так и не дождемся. Зато должны увидеть что-то подобное.

Oct 3 12:15:05 dns squid[139]: Squid Parent: child process 141 started

Это значит что, squid у нас заработал. Идем дальше.

Установка и запуск Apache

Теперь примемся за установку Russian Apache. Если вы желаете то можете использовать стандартный Apache. Я использовал весрсию 1.3.27 PL30.16. Ну а Вы как всегда берите новейший дистрибутив.
Распаковываем его и ставим в комплекте по умолчанию.

# tar zxvf apache_1.3.27rusPL30.16.tar.gz
# ./configure
# gmake
# gmake instal

Запускаем apache:

/usr/local/apache/bin/apachectl start

Создаем директорию, где будут лежать пустой баннер и файл mp3 с каким-либо забавным звуком.

# mkdir /usr/local/apache/htdocs/replace

Кладем туда 1×1gif и my.mp3. Берем модифицированный block.cgiи копируем его в /usr/local/apache/cgi-bin Выставляем ему нужные права:

# chown nobody:wheel /usr/local/apache/cgi-bin/block.cgi
# chmod 500 /usr/local/apache/cgi-bin/block.cgi

block.cgi это perl скрипт который будет вызываться каждый раз, когда пользователь попытается посетить запрещенную страницу. Взять его можно из архива с дистрибутивом squidGuard. В первоначальном варианте этот скрипт назывался squidGuard-1.2.0/samples/squidGuard.cgi.in. Можно использовать его, но все же лучше взять слегка модифицированный мною вариант. Мой, скрипт наверно, лучше, потому что руссифицированный. На его исправление ушло почти два часа., впрочем это еще не показатель качества исправлений, поэтому используйте мой скрипт на свой страх и риск.

Установка SquidGurad, Berkeley DB, libtool

Итак, все подготовительные работы окончены, и самое время взяться за установку squidGuard 1.2.0. Для его работы необходимо иметь Berkeley DB 3.2.9. Многие наступают на грабли с версией базы данных. Судя по разговорам на форумах многие люди как и я лично убедились на собственной шкуре, в том неприятном факте что удачной сборки удалось достигнуть только с версей базы 3.2.9. В свою очередь, Berkeley DB не соберется без libtool. Довольно запутаная получается цепочка. Но бояться не стоит. Берем http://www.freebsd.org/cgi/pds.cgi?ports/devel/libtool из коллекции портированных приложений и как обычно, выполняем распаковку, копиляцию, а затем и установку.:

# tar zxvf libtool-1.3.4.tar.gz
# cd libtool-1.3.4
# ./configure
# gmake
# gmake install

С выполнение этих действий не должно возникнуть никаких сложностей. Скачиваем Berkeley DB 3.2.9 http://www.sleepycat.com/update/index.html. Забираем два патча http://www.sleepycat.com/files/patch_329.tar.gz. И снова:

# tar zxvf db-3.2.9.tar.gz

Копируем патч файлы в получившуюся после распаковки дистрибутива директорию db-3.2.9. Затем применяем их для модификации исходного кода.

# cp patch.3.2.9.1 patch.3.2.9.2 ./db-3.2.9
# cd /usr/local/src/db-3.2.9
# patch -p0 < prefix="/usr/local/squidGuard" db="/usr/local/BerkeleyDB.3.2" config="/usr/local/squidGuard/squidGuard.conf" logdir="/usr/local/squidGuard/log" dbhome="/usr/local/squidGuard/db" prefix="/usr/local/squidGuard" db="/usr/local/BerkeleyDB.3.2" config="/usr/local/squidGuard/squidGuard.conf" logdir="/usr/local/squidGuard/log" dbhome="/usr/local/squidGuard/db" type="download&file="bigblacklist." clientaddr="%a&clientname="%n&clientident="%i&clientgroup="%s&targetgroup="%t&url="%u" clientaddr="%a&clientname="%n&clientident="%i&clientgroup="%s&targetgroup="%t&url="%u" clientaddr="%a&clientname="%n&clientident="%i&clientgroup="%s&targetgroup="%t&url="%u" clientaddr="%a&clientname="%n&clientident="%i&clientgroup="%s&targetgroup="Not_Authorized&url="%u"> /usr/local/squidGuard/bin/rebuid_base.sh
#!/bin/sh
/usr/local/squidGuard/bin/squidGuard -C all
chown -R nobody /usr/local/squidGuard/db
killall -HUP squid
^D

Устанавливаем нужные права доступа на файл rebuid_base.sh. Так же необходимо убедиться что этот скрипт имеет право запускать только пользовать root.

# chmod 100 /usr/local/squidGuard/bin/rebuid_base.sh
# /usr/local/squidGuard/bin/rebuid_base.sh

Запустив rebuid_base.sh, необходимо дождаться нормального завершения задачи. Теперь во всех директориях, упомянутых в разделах dest конфигурационного файла, появились файлы баз данных domains.db и urls.db.

Локальное тестирование SquidGuard

Перед тем как подключать squidGuard к squid, необходимо протестировать его локально. Для начала немного теории. Squid передает данные на стандартный ввод редиректора. Редиректор, в свою очередь, обрабатывает запрос и выдает на стандарный вывод результаты своей работы. Затем squid забирает эти данные. Редиректор отвечает на запрос от squid либо пустой строкой, если перенаправление не требуется, либо измененным URL. Формат запроса от squid к редиректору выглядит так:

URL адрес клиента разделитель метод запроса
http://test.ru/win2000/setup.exe 127.0.0.1/ - GET

Для того чтобы проверить как squidGuard будет реагировать на запросы пользователей, скачиваем написанную мною тестовую программу test.tar.gz. Распаковываем ее и кладем полученный файл test.pl в /usr/local/squidGuard/bin/. Устанавливаем файлу test.pl разрешение на выполнение. Затем запускаем test.pl и вводим тестируемый адрес. После этого в файле result.txt смотрим результаты работы squidGuard. Набор тестируемых сайтов можно изменять прямо в файле test.pl. Если результаты теста Вас удовлетворили, значит самое время объединить squidGuard и Squid. В файл /usr/local/squid/etc/squid.conf добавляем строки:

redirector_bypass on
# если не один из экземпляров squidGuard не
# отвечает, то работать напрямую
redirect_program /usr/local/squidGuard/bin/squidGuard
# где находится squidGuard
redirect_children 1
# сколько экземрляров squidGuard запускать

Перезапускаем squid. В свою очередь, squid самостоятельно выполнит перезапуск всех дочерних процессов редиректоров.

# killall -HUP squid

В конце файла /usr/local/squidGuard/log/squidGuard.log ищем такие строки:

2002-10-15 16:11:04 [10653] squidGuard 1.2.0 started (1034683864.337)
2002-10-15 16:11:04 [10653] squidGuard ready for requests (1034683864.353)

Автозапуск squid и Apache

Если они есть, значит все работает как положено. Теперь сделаем так, что бы Squid и Apache запускались автоматически при каждой загрузке машины.

# cat > /usr/local/etc/rc.d/apache.sh
#!/bin/sh
/usr/local/apache/bin/apachectl start
^D
# cat > /usr/local/etc/rc.d/squid.sh
#!/bin/sh
/usr/local/squid/bin/squid -D
^D
# chmod 100 /usr/local/etc/rc.d/apache.sh /usr/local/etc/rc.d/squid.sh

Для проверки стоит перезагрузить машину . Это даст нам возможность посмотреть как сервисы поведут себя при возможных перебоях в подаче электричеста. После перезагрузки можно начать наслаждаться тем, как все гладко работает.

Обновление базы доменов

качестве маленького бонуса можно наладить автоматическое обновление базы доменов. Для скачивания файла базы доменов нам понядобится программа wget. Конечно можно было обойтись и стандартным fetch. Но все же wget работает надежнее. Распаковываем и ставим как обычно.

# tar zxvf wget-1.8.2.tar.gz
# cd wget-1.8.2
# ./configure
# gmake
# gmake install

Смотрим, куда он у нас установился.

# where wget
/usr/local/bin/wget

Пишем скрипт, который будет выкачивать обновления с сайта MESD и класть их в директорию /usr/local/squidGuard/update. Затем архив с обновлениями будет распакован и скопирован в директорию /usr/local/squidGuard/bd. После этого будет произведена перестройка баз и перезапуск squid.

#cat > /usr/local/squidGuard/bin/update_blacklist.sh
#!/bin/sh
/usr/local/bin/wget -q –cache=off ‘http://squidguard.mesd.k12.or.us/blacklists.tgz’ -O /usr/local/squidGuard/update/blacklist.tgz
tar zxvf /usr/local/squidGuard/update/blacklist.tgz -C /usr/local/squidGuard/update/
cp -R -f /usr/local/squidGuard/update/blacklists/* /usr/local/squidGuard/bd
rm -R /usr/local/squidGuard/update/blacklists
/usr/local/squidGuard/rebuid_base.sh
^D

Теперь даем нашему скрипту нужные права.

# chmod 100 /usr/local/squidGuard/bin/update_blacklist.sh

Создадим временную директорию в которую будут распаковываться обновления.

# mkdir /usr/local/squidGuard/update

Настраиваем планировщик на выполнение нашего задания.

# crontab -e -u root
MAILTO=”admin@test.ru”
1 0 * * 7 /usr/local/squidGuard/bin/update_blacklist.sh

Назначаем выполнение обновления на 0 часов 1 минуту каждого воскресенья. Уведомление о выполнении этого задания приказываем слать по адресу admin@test.ru. Теперь осталось раздать всем пользователям подабающие права и можно отдыхать.

Автор Бешков Андрей
Взято на сайте onix.opennet.ru

Комментариев нет:

Неактивный атрибут "скрытый" или как снять атрибут скрытый после вируса

Некоторые пользователи компьютеров часто сталкиваются с проблемой, когда папки и файлы вдруг становятся скрытыми. Или, проще говоря, исчез...