Настраиваем Squid в качестве прозрачного прокси-сервера для офисной сети. Предполагается, что маршрутизация на сервере настроена, и доступ к сайтам из внутренней сети уже работает. Используем прокси-сервер для расшифровки веб-трафика, ограничения доступа к сайтам и фильтрации медиа-контента.
Настройка ядра
Для работы в режиме прозрачного прокси необходимо обеспечить перенаправление веб-трафика прокси-серверу. Если в качестве брандмауэра используется IPFW, необходимо включить форвардинг пакетов пересобрав ядро с опцией IPFIREWALL_FORWARD. В ядре GENERIC опция перенаправления по умолчанию отключена.
В ядре GENERIC опция перенаправления по умолчанию отключена.Проверяем включено ли перенаправление пакетов командой:
grep ipfw /var/run/dmesg.boot
Получаем следующий результат:
ipfw2 (+ipv6) initialized, divert loadable, nat loadable, rule-based forwarding disabled, default to deny, logging disabled
Если видим: «rule-based forwarding disabled«, форвардинг отключен, необходимо пересобрать ядро. Если сообщение отсутствует, значит IPFW не настроен.
Получаем идентификатор ядра:
uname -i
Если ранее ядро не изменялось, в результате получаем:
GENERIC
Создаем конфиг ядра IPFORWARD, на основе GENERIC
echo include GENERIC >/usr/src/sys/i386/conf/IPFORWARD echo ident IPFORWARD >>/usr/src/sys/i386/conf/IPFORWARD
Включаем перенаправление пакетов:
echo options IPFIREWALL >>/usr/src/sys/i386/conf/IPFORWARD echo options IPFIREWALL_FORWARD >>/usr/src/sys/i386/conf/IPFORWARD
Проверяем полученный конфиг:
cat /usr/src/sys/i386/conf/IPFORWARD
В результате получаем:
include GENERIC ident IPFORWARD options IPFIREWALL options IPFIREWALL_FORWARD
Переходим в папку с исходниками системы:
cd /usr/src
Если файлы в /usr/src отсутствуют, необходимо установить исходники, соответствующие вашей версии системы.
Собираем и устанавливаем ядро, используя созданный конфиг:
make kernel KERNCONF=IPFORWARD
Перезагружаем систему:
shutdown -r now
Проверяем идентификатор ядра:
uname -i
В случае успешной установки ядра, в ответ получаем:
IPFORWARD
Проверяем статус IPFW:
grep ipfw /var/run/dmesg.boot
В случае успеха получаем:
ipfw2 (+ipv6) initialized, divert loadable, nat loadable, rule-based forwarding enabled, default to deny, logging disabled
Установка Squid
Обновляем коллекцию портов:
portsnap fetch && portsnap update || portsnap extract
Получаем список доступных версий Squid:
cd /usr/ports/www && echo squid*
Настраиваем порт:
cd /usr/ports/www/squid32 make config
В параметрах сборки включаем прозрачное проксирование для используемого брандмауэра и поддержку больших файлов:
[*] LARGEFILE Support large (>2GB) cache and log files ... [ ] TP_IPF Enable transparent proxying with IPFilter [*] TP_IPFW Enable transparent proxying with IPFW [ ] TP_PF Enable transparent proxying with PF
Устанавливаем порт:
make install clean
Для сборки пакета используются параметры по умолчанию, установленный из пакета прозрачный прокси будет работать некорректно.
Настройка Squid
Сохраняем файл конфигурации, установленный по умолчанию:
mv /usr/local/etc/squid/squid.conf /usr/local/etc/squid/squid.conf.default
Создаем новый файл конфигурации:
ee /usr/local/etc/squid/squid.conf
Задаем параметры:
#Адрес и порт для входящих подключений #Заданный порт используется при прозрачном проксировании для #передачи изображений на страницах ошибок и протоколом управления кэшем http_port 3128 #Локальный интерфейс, для трафика, перенаправленного брандмауэром http_port 127.0.0.1:3129 intercept #Время ожидания установки TCP соединения с сервером #По умолчанию 1 минута, если сервер не отвечает, выполняется 3 попытки установить соединение, итого время до появления ошибки 3 минуты #Сократим таймаут до 20 секунд connect_timeout 20 second #При завершении работы ожидать закрытия клиентских подключений, так заявлено в документации #По факту ждет независимо от наличия клиентских подключений #По умолчанию - 30 секунд, сократим время ожидания до 1 shutdown_lifetime 1 seconds #Кэш: формат, размещение, размер в мегабайтах, число папок первой и второй вложенности #Указанный размер кэша не учитывает издержки файловой системы и должен быть примерно на 20% меньше доступного дискового пространства #Директиву cache_dir, можно указать несколько раз, выделив под кэш дополнительные разделы cache_dir ufs /usr/local/squid/cache 3000 16 256 #Не кэшировать файлы больше заданного размера #По умолчанию 4Мб maximum_object_size 320 MB #Продолжить загрузку при отключении клиента, если осталось загрузить менее указанного объема данных #Позволяет сохранить объект в кэше при отмене загрузки клиентом #Значение 0 для quick_abort_min и quick_abort_max отменяют докачку #Значение -1 включает полную закачку объекта, не зависимо от оставшегося объема, повышает нагрузку на канал #По умолчанию 16 Кб quick_abort_min 5 MB #Размер кэша в оперативной памяти #По умолчанию 256Мб #cache_mem 256 MB #Максимальный размер объекта, сохраняемого в оперативной памяти #Объекты больше заданного размера в памяти не сохраняются #maximum_object_size_in_memory 512 KB #Отключить кеширование #cache deny all #Путь сохранения дампа аварийного завершения coredump_dir /usr/local/squid/cache #Путь и формат лог-файла access_log daemon:/usr/local/squid/log/access.log squid #Протоколировать параметры запросов #По умолчанию в целях обеспечения приватности в логе не сохраняются параметры CGI-скриптов #strip_query_terms off #Протоколировать http-заголовки log_mime_hdrs on #Не отправлять заголовок X-Forwarded-For содержащий внутренний IP-адрес клиента #forwarded_for transparent #Не отправлять заголовок Via с именем и версией прокси-сервера #via off #Email администратора, для отправки уведомлений об отказе кэша #На практике, ни одного уведомления не видел #Адрес также отображается на страницах ошибок cache_mgr root@localhost #Адрес сервера, отображаемый на страницах ошибок #По умолчанию используется функция gethostname(), которая при http_port 127.0.0.1, вернет localhost #visible_hostname proxy.localnet.local # # Определяем списки контроля безопасности # #IP-адрес, с которого разрешен доступ к управлению кэшем #acl CacheManagerIP src 192.168.0.2 #Обслуживаемая прокси-сервером сеть #acl localnet src 10.0.0.0/8 # RFC1918 possible internal network #acl localnet src 172.16.0.0/12 # RFC1918 possible internal network #acl localnet src fc00::/7 # RFC 4193 local private network range #acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines acl localnet src 192.168.0.0/16 # RFC1918 possible internal network #Метод CONNECT, используется для SSL-соединений acl CONNECT method CONNECT #Путь к списку IP-адресов пользователей, для которых не действует фильтр сайтов и контента #acl AdminsIP src "/usr/local/etc/squid/AccessLists/AdminsIP.txt" #Путь к списку запрещенных сайтов #acl RestrictedDomains dstdomain "/usr/local/etc/squid/AccessLists/RestrictedDomains.txt" #Путь к списку доменов с рекламой #acl AdDomains dstdomain "/usr/local/etc/squid/AccessLists/AdDomains.txt" #Путь к списку доменов с рекламой для фильтрации по ответу #Блокируются изображения и анимация, допускается переход по ссылкам #acl AdDomains_ReplyFilter dstdomain "/usr/local/etc/squid/AccessLists/AdDomains_Content.txt" #Mime-типы для блокировки рекламы #acl AdMimeTypes rep_mime_type ^image/gif ^image/jpeg ^application/x-javascript ^application/x-shockwave-flash #Mime-типы для аудио и видео acl MimeAudioVideo rep_mime_type audio video #Сайты с IP-адресами acl UrlIP url_regex -i ^http://[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/.* # # Задаем права доступа # #Разрешить локальное управление кэшем http_access allow manager localhost #Разрешить удаленное управление кэшем #http_access allow manager CacheManagerIP http_access deny manager #Пароли для различных действий протокола управления кэшем #Значение disable all отключает управление кэшем #cachemgr_passwd disable all #Запретить метод CONNECT #Проксирование SSL-соединений в прозрачном режиме невозможно http_access deny CONNECT #Запретить доступ к локальным ресурсам сервера через прокси http_access deny to_localhost #Первичный фильтр рекламы #Блокируется весь контент с заданных доменов #http_access deny AdDomains #Страница ошибки доступа для рекламы #Создать командой: echo "[AD]" > /usr/local/etc/squid/ERR_ADV_DENIED #deny_info ../../ERR_ADV_DENIED AdDomains #Не ограничивать доступ администраторам #http_access allow AdminsIP #Блокировать запрещенные сайты #http_access deny RestrictedDomains #Запретить доступ к сайтам по IP-адресу #http_access deny UrlIP #Разрешить доступ из локальной сети http_access allow localnet #Блокировать все, что не разрешено http_access deny all # #Фильтрация контента, на этапе получения ответа от сервера # #Фильтр рекламного контента: графика, анимация, JavaScript, клики по ссылкам продолжают работать #http_reply_access deny AdDomains_ReplyFilter AdMimeTypes #Не ограничивать доступ администраторам #http_reply_access allow AdminsIP #Блокировать загрузку аудио/видео контента #http_reply_access deny MimeAudioVideo #Разрешить весь остальной контент http_reply_access allow all #Время устаревания кэшируемого контента в минутах, если явно не задано сервером #Поля: шаблон соответствия URL, минимальное время в минутах, процент для расчета времени устаревания объекта, максимальное время в минутах #Если повторный запрос приходит до наступления минимального времени, объект считается актуальным, запрос к серверу не выполняется #Расчет времени жизни производится по формуле: (ВремяПолучения-ВремяСоздания)*Процент #Чем старее объект, тем дольше он содержится в кэше, но не дольше заданного максимального времени #Подробности: http://etutorials.org/Server+Administration/Squid.+The+definitive+guide/Chapter+7.+Disk+Cache+Basics/7.7+refresh_pattern/ # #Время жизни объектов для FTP-протокола #refresh_pattern ^ftp: 1440 20% 10080 #Нулевое время жизни для динамического контента refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 #Время жизни по умолчанию refresh_pattern . 0 20% 4320
Создаем папку для списков контроля доступа
mkdir /usr/local/etc/squid/AccessLists
Создаем необходимые списки, значения в списке разделяются новой строкой.
Список IP-адресов с неограниченным доступом:
ee /usr/local/etc/squid/AccessLists/AdminsIP.txt
Список сайтов, доступ к которым запрещен пользователям. Точка в начале адреса блокирует доступ ко всем адресам в заданном домене. Для массовой блокировки развлекательных ресурсов потребуется установка редиректора SquidGuard.
ee /usr/local/etc/squid/AccessLists/RestrictedDomains.txt
Фильтр рекламы:
ee /usr/local/etc/squid/AccessLists/AdDomains.txt
Фильтр рекламы с учетом типа контента:
ee /usr/local/etc/squid/AccessLists/AdDomains_Content.txt
Рассмотренные фильтры рекламы использовались во времена помегабайтной оплаты за интернет. Основной задачей тогда была экономия трафика. В список вручную заносились домены, генерирующие значительный объем трафика. Для борьбы с рекламой, более эффективным решением будет установка редиректора SquidGuard, либо настройка фильтров в браузере клиента. Так же данный список может быть полезен для блокировки вредоносных сайтов и блокировки загрузки обновлений с внешних ресурсов, при наличии внутренних служб распространения обновлений.
Некоторые сайты используют протокол https, фильтровать который при прозрачном проксировании невозможно. Для ограничения доступа к таким сайтам придется использовать брандмауэр либо DNS-сервер, либо проксировать https традиционным, непрозрачным, способом.
Создаем папку для кэша, задаем права доступа:
mkdir -p /usr/local/squid/cache && chown root:squid /usr/local/squid/cache && chmod 770 /usr/local/squid/cache
Создаем структуру кэша:
/usr/local/sbin/squid -z
Создаем папку для логов доступа, задаем права доступа:
mkdir /usr/local/squid/log && chown root:squid /usr/local/squid/log && chmod 770 /usr/local/squid/log
Лог доступа за месяц может занимать достаточно большой объем, по этой причине в рассматриваемой конфигурации лог был размещен в /usr. Если свободного места в /var достаточно, лог доступа можно оставить в /var/log/squid.
Отображение местного времени на страницах ошибок Squid
По умолчанию на страницах ошибок Squid отображает время по Гринвичу, для отображения местного времени необходимо скорректировать шаблоны ошибок. Параметр шаблона %T указывает мировое время, %t — местное.
Копируем шаблоны ошибок в папку erros.local:
mkdir -p /usr/local/etc/squid/errors.local/ru cp /usr/local/etc/squid/errors/ru/* /usr/local/etc/squid/errors.local/ru
Заменяем общемировое время (%T), на местное (%t):
sed -i .bak "s/%T/%t/g" /usr/local/etc/squid/errors.local/ru/* && rm /usr/local/etc/squid/errors.local/ru/*.bak
Задаем путь к измененным шаблонам ошибок в squid.conf:
printf "\n\n#Отображение местного времени на страницах ошибок\nerror_directory /usr/local/etc/squid/errors.local/ru\n" >> /usr/local/etc/squid/squid.conf
Запуск Squid
Включаем Squid в rc.conf:
printf '\nsquid_enable=\"YES\"\n' >>/etc/rc.conf
Запускаем демон:
/usr/local/etc/rc.d/squid start
Проверяем, стартанул ли демон:
ps -ax | grep squid
Проверяем, слушается ли сокет:
netstat -an | grep 3128
Проверяем лог:
cat /var/log/squid/cache.log
В случае успешного старта вывод будет примерно следующим:
2013/03/03 21:29:54 kid1| Starting Squid Cache version 3.2.7 for i386-portbld-freebsd9.1... 2013/03/03 21:29:54 kid1| Process ID 40625 2013/03/03 21:29:54 kid1| Process Roles: worker 2013/03/03 21:29:54 kid1| With 7149 file descriptors available 2013/03/03 21:29:54 kid1| Initializing IP Cache... 2013/03/03 21:29:54 kid1| DNS Socket created at [::], FD 7 2013/03/03 21:29:54 kid1| DNS Socket created at 0.0.0.0, FD 8 2013/03/03 21:29:54 kid1| Adding nameserver 127.0.0.1 from /etc/resolv.conf 2013/03/03 21:29:54 kid1| Logfile: opening log daemon:/usr/local/squid/log/access.log 2013/03/03 21:29:54 kid1| Logfile Daemon: opening log /usr/local/squid/log/access.log 2013/03/03 21:29:54 kid1| WARNING: no_suid: setuid(0): (1) Operation not permitted 2013/03/03 21:29:54 kid1| WARNING: no_suid: setuid(0): (1) Operation not permitted 2013/03/03 21:29:55 kid1| Unlinkd pipe opened on FD 14 2013/03/03 21:29:55 kid1| Store logging disabled 2013/03/03 21:29:55 kid1| Swap maxSize 3072000 + 262144 KB, estimated 256472 objects 2013/03/03 21:29:55 kid1| Target number of buckets: 12823 2013/03/03 21:29:55 kid1| Using 16384 Store buckets 2013/03/03 21:29:55 kid1| Max Mem size: 262144 KB 2013/03/03 21:29:55 kid1| Max Swap size: 3072000 KB 2013/03/03 21:29:55 kid1| Rebuilding storage in /usr/local/squid/cache (clean log) 2013/03/03 21:29:55 kid1| Using Least Load store dir selection 2013/03/03 21:29:55 kid1| Set Current Directory to /usr/local/squid/cache 2013/03/03 21:29:55 kid1| Loaded Icons. 2013/03/03 21:29:55 kid1| HTCP Disabled. 2013/03/03 21:29:55 kid1| Squid plugin modules loaded: 0 2013/03/03 21:29:55 kid1| Accepting HTTP Socket connections at local=[::]:3128 remote=[::] FD 17 flags=9 2013/03/03 21:29:55 kid1| Accepting NAT intercepted HTTP Socket connections at local=127.0.0.1:3128 remote=[::] FD 18 flags=41 2013/03/03 21:29:55 kid1| Done reading /usr/local/squid/cache swaplog (0 entries) 2013/03/03 21:29:55 kid1| Store rebuilding is 0.00% complete 2013/03/03 21:29:55 kid1| Finished rebuilding storage from disk. 2013/03/03 21:29:55 kid1| 0 Entries scanned 2013/03/03 21:29:55 kid1| 0 Invalid entries. 2013/03/03 21:29:55 kid1| 0 With invalid flags. 2013/03/03 21:29:55 kid1| 0 Objects loaded. 2013/03/03 21:29:55 kid1| 0 Objects expired. 2013/03/03 21:29:55 kid1| 0 Objects cancelled. 2013/03/03 21:29:55 kid1| 0 Duplicate URLs purged. 2013/03/03 21:29:55 kid1| 0 Swapfile clashes avoided. 2013/03/03 21:29:55 kid1| Took 0.04 seconds ( 0.00 objects/sec). 2013/03/03 21:29:55 kid1| Beginning Validation Procedure 2013/03/03 21:29:55 kid1| Completed Validation Procedure 2013/03/03 21:29:55 kid1| Validated 0 Entries 2013/03/03 21:29:55 kid1| store_swap_size = 0.00 KB 2013/03/03 21:29:56 kid1| storeLateRelease: released 0 objects
По поводу «WARNING: no_suid: setuid(0): (1) Operation not permitted», отслеживаем баг-репорт: http://bugs.squid-cache.org/show_bug.cgi?id=3785.
В брандмауэре разрешаем исходящие подключения для Squid (порядковый номер правила и внешний интерфейс необходимо задать свой):
ipfw add 110 allow tcp from me to any out via em0 keep-state uid squid
Перенаправляем веб-трафик с тестового компьютера в Squid:
ipfw add 120 fwd 127.0.0.1,3129 tcp from 192.168.0.2 to any 80-83,8080-8088 out via em0
Инициируем веб-трафик с тестового компьютера и проверяем лог доступа:
cat /usr/local/squid/log/access.log
В случае проблем проверяем, работает ли правило брандмауэра:
ipfw show
Счетчик для правила перенаправления не должен быть нулевым.
Если при тестировании проблем не выявлено, заворачиваем в прокси всю подсеть:
ipfw add 120 fwd 127.0.0.1,3129 tcp from 192.168.0.0/16 to any 80-83,8080-8088 out via em0
Протокол управления кэшем
Если управление кэшем не было запрещено в конфиге, используем squidclient для получения статистики и оперативного управления.
Получить общую статистику сервера:
squidclient -h 127.0.0.1 cache_object://localhost/info
Получить список доступных команд:
squidclient -h 127.0.0.1 cache_object://localhost/menu
Управление кэшем возможно также из браузера. Статистика сервера доступна по адресу: http://адрес.прокси.сервера:3128/squid-internal-mgr/info, список команд: http://адрес.прокси.сервера:3128/squid-internal-mgr/menu.
Ротация лога доступа Squid
Настраиваем ежемесячную ротацию и архивацию access.log
Создаем скрипт RotateAccessLog:
ee /usr/local/etc/squid/RotateAccessLog
Со следующим содержимым:
#!/bin/sh #Задаем число хранимых архивов ArcCount=12 #Предварительно запускаем парсер LightSquid #/usr/local/www/lightsquid/lightparser.pl today #Выполнить ротацию, выход при ошибке. /usr/local/sbin/squid -k rotate || return 1 #Ротация производится в фоновом режиме, ждем завершения 10 секунд. sleep 10 #Удаляем старый cache.log.1, новый сохраняется с именем cache.log.0. rm /var/log/squid/cache.log.1 2>/dev/null #Удаляем старый store.log.1 rm /var/log/squid/store.log.1 2>/dev/null i=$(($ArcCount-1)) #Переходим в папку с логами, выход, если папка не существует. cd /usr/local/squid/log || return 1 #Удаляем самый старый архив. rm access.log.$i.bz2 2>/dev/null #Выполняем ротацию while [ $i -gt 0 ] do mv access.log.$(($i-1)).bz2 access.log.$i.bz2 2>/dev/null i=$(($i-1)) done #Архивируем лог доступа. bzip2 access.log.0
Разрешаем запуск скрипта:
chmod 700 /usr/local/etc/squid/RotateAccessLog
Выполняем тестовый запуск:
/usr/local/etc/squid/RotateAccessLog
Проверяем, создан ли архив:
ls -l /usr/local/squid/log/*.bz2
Настраиваем cron на ежемесячный запуск первого числа в полночь:
printf '\n0\t0\t1\t*\t*\troot\t/usr/local/etc/squid/RotateAccessLog\n' >>/etc/crontab && cat /etc/crontab
Автоматический перезапуск Squid при отказе
Squid 2.7 изредка грешил периодическими отказами, оставляя при этом сеть без доступа к вебу. Хотя в третьей версии таких безобразий более не замечено, лишняя проверка не повредит. Проверяем сценарием, загружен ли Squid и запускаем при необходимости. Попутно, чистим кэш, при обнаружении сообщения о нехватке дискового пространства.
Создаем сценарий AutoRestart:
ee /usr/local/etc/squid/AutoRestart
Со следующим содержимым:
#!/bin/sh #Точка монтирования файловой системы FS=/usr #Путь к кэшу CacheDir=/usr/local/squid/cache #Проверяем, загружен ли Squid, выходим в случае успеха /usr/local/sbin/squid -k check >/dev/null 2>&1 && return #При нехватке дискового пространства, удаляем кэш #Если обнаружено сообщение filesystem full в журнале messages if grep $fs:\ filesystem\ full /var/log/messages; then #Уведомляем об ошибке echo Disk full detected, cleanup #Удаляем кэш с предварительной проверкой, что заданный путь указывает именно на кэш test -f $CacheDir/swap.state && rm -R $CacheDir/* #Создаем структуру кэша /usr/local/sbin/squid -z fi #Запускаем демон /usr/local/etc/rc.d/squid start
Разрешаем запуск скрипта:
chmod 700 /usr/local/etc/squid/AutoRestart
Выполняем тестовый запуск:
/usr/local/etc/rc.d/squid stop /usr/local/etc/squid/AutoRestart
Запускаем через cron каждые 15 минут:
printf '\n*/15\t*\t*\t*\t*\troot\t/usr/local/etc/squid/AutoRestart\n' >>/etc/crontab && cat /etc/crontab
В случае проблем на почту root’у будет отправлено уведомление.
Анализ логов Squid
LightSquid — анализатор лога доступа, написанный на Perl. Каждые полчаса сканирует лог доступа и формирует отчеты по трафику для каждого пользователя (IP-адреса) за день, за месяц, за год. Фиксирует загрузку больших файлов, почасовую активность пользователя, строит рейтинг сайтов по объему потребленного трафика. Для просмотра отчетов потребуется веб-сервер. Инструкции по настройке ищем здесь.
Список других анализаторов доступен на сайте проекта: http://www.squid-cache.org/Misc/log-analysis.html
Решение проблем
Если в cache.log постоянно пишутся предупреждения:
WARNING: transparent proxying not supported
При сборке не была включена поддержка прозрачного прокси для вашего брандмауэра. Переустановите Squid из коллекции портов с включением соответствующих параметров.
Если получаем следующие предупреждения:
WARNING: (A) '192.168.0.0/16' is a subnetwork of (B) '::/0' WARNING: because of this '192.168.0.0/16' is ignored to keep splay tree searching predictable WARNING: You should probably remove '192.168.0.0/16' from the ACL named 'all'
Обнаружена декларация acl all. В третьей версии список доступа all создается сквидом автоматически, его декларация не требуется. Удалите или переименуйте acl all.
Дополнительная информация
Список всех параметров конфигурации: /usr/local/etc/squid/squid.conf.documented
Документация на сайте проекта: http://www.squid-cache.org/Doc/
Bog BOS: Squid (кеширующий прокси для http): установка, настройка и использование
По материалам: itadept.ru/freebsd-squid/