Особенность совместного использования delay_pools и icap состоит в том, что на момент написания
этой статьи при включении icap в squid3, delay_pools перестают ограничивать потоки. Единственное
решение - запустить две копии squid3 (первую с icap, вторую с delay_pools).
Рассмотрим как
это можно реализовать на примере openSUSE 11.1.
Этапы настройки squid3 с delay_pools и icap
-
Подготовить файл конфигурации для связки squid3+delay_pools;
-
Подготовить файл конфигурации для связки squid3+icap;
-
Создать модифицированный init скрипт для запуска squid3 с двумя конфигурациями.
Интерфейсы и файлы конфигурации
Итак, будем считать, что на сервере есть интерфейсы:
- внутренний - 10.0.0.1 (eth0 смотрит в локальную сеть),
- внешний - x.x.x.x (eth1 смотрит в интернет),
- локальная петля - 127.0.0.1 (lo localhost).
Порт по умолчанию - 3128.
Мы хотим ограничивать потоки по некоторым группам пользователей, тогда настроим связки:
- squid3+delay_pools на eth0 интерфейсе (squid-noicap.conf),
- squid3+icap на lo интерфейсе (squid-icap.conf без кэширования).
Для перенаправления запросов squid-noicap на squid-icap используем cache_peer.
Настройка squid3 с delay_pools и icap
Этап 1. Пример файла конфигурации для связки squid3+delay_pools
/etc/squid/squid-noicap.conf
http_port 10.0.0.1:3128
visible_hostname proxy.domain.local
#
#Note: never_direct overrides this option.
#hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin \?
cache deny QUERY
cache_peer 127.0.0.1 parent 3128 0 no-query no-digest no-netdb-exchange name=icap_server default
#
access_log /var/log/squid/access-noicap.log squid
cache_log /var/log/squid/cache-noicap.log
cache_store_log /var/log/squid/store-noicap.log
pid_filename /var/run/squid-noicap.pid
#
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern (cgi-bin|\?) 0 0% 0
refresh_pattern . 0 20% 4320
#
cache_dir ufs /var/cache/squid-noicap 1024 16 256
coredump_dir /var/cache/squid-noicap
error_directory /usr/share/squid/errors/Russian-1251
# Запрещаем добавлять IP пользователя в запрос
forwarded_for off
# Разрешаем выявлять зависшие соединения и отрубать их
detect_broken_pconn on
# Отключаем поддержку полузакрытых клиентов (чтобы не висели по чем зря)
half_closed_clients off
# Не использовать постоянные соединения с серверами и клиентами, когда
# для нескольких http-запросов используется одно и то же tcp-соединение
server_persistent_connections off
#client_persistent_connections off
# Разрешаем принудительный запрос на обновление страницы
refresh_all_ims on
# Наши сети
acl our_networks src 10.0.0.0/24
#
# 3 network ACL
#
acl users_network src 10.0.0.10-10.0.0.200
acl admins_network src 10.0.0.1-10.0.0.9
acl vip_person src 10.0.0.20/32 10.0.0.30/32 10.0.0.40/32
acl proxy src 10.0.0.1/32
#
# Заблокированные пользователи. Чтоб не лазяли в инет
#
acl blockedusers src 10.0.0.15/32 10.0.0.25/32
#
# Заблокированные адреса для всех
#
acl banallurl url_regex -i "/etc/squid/banned_urlregex.acl"
#
# Заблокированные адреса (метод POST)
#
acl POST method POST
acl banposturl url_regex -i "/etc/squid/banned_urlregex_post.acl"
#
# Заблокированные mime_type
#
acl banrepmimetype rep_mime_type -i "/etc/squid/banned_repmimetype.acl"
#
# Сайты с пониженной скоростью доступа
#
acl slow_sites dstdomain "/etc/squid/slow_dmsites.acl"
#
# Сайты с повышенной скоростью доступа
#
acl fast_sites dstdomain "/etc/squid/fast_dmsites.acl"
#
# Сайты не пересылаемые на проверку в icap
#
acl no_icap_sites url_regex -i "/etc/squid/no_icap_url_regex.acl"
#
# Внутренние сайты напрямую
#
acl local_dst dst 10.0.0.0/24
#
# Основные списки доступа
#
acl manager proto cache_object
acl localhost src 127.0.0.1/32
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
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 port873 port 873 # порт 873 rsync.opensuse.org (синхронизация обновлений openSUSE)
acl rsync_opensuse dstdomain rsync.opensuse.org # rsync.opensuse.org (синхронизация обновлений openSUSE)
#
# Основные списки доступа
#
http_access allow manager localhost
http_access deny manager
# Запрещаем доступ тем кто не из нашей сети
http_access deny !our_networks
# Здесь описываем заблокированных пользователей нашей сети
http_access deny blockedusers
# Здесь описываем заблокированные адреса для ВСЕХ пользователей
http_access deny banallurl
# Здесь описываем заблокированные mime type для групп пользователей
http_reply_access deny users_network banrepmimetype
http_reply_access deny vip_person banrepmimetype
# Здесь описываем заблокированные адреса, методы и т.д. для групп пользователей
http_access deny users_network POST banposturl
#
# Доступ по специальным спискам
#
http_access allow CONNECT proxy rsync_opensuse port873
#
# Основные списки доступа продолжение
#
# Запрещающие ACL
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny to_localhost
# Разрешающие ACL
# allow SSL_ports - не обязательное условие, если все стандарнтые SSL порты прописаны в Safe_ports
#http_access allow SSL_ports
http_access allow Safe_ports
http_access allow localhost
# Завершающий ACL
http_access deny all
# Что не нужно прогонять через icap - отправляем напрямую
always_direct allow our_networks local_dst
always_direct allow our_networks CONNECT
always_direct allow our_networks no_icap_sites
# Все остальное через cache_peer
never_direct allow all
# Пулы ограничение скорости
# A pair of delay parameters is written restore/maximum, where restore is
# the number of bytes (not bits - modem and network speeds are usually
# quoted in bits) per second placed into the bucket, and maximum is the
# maximum number of bytes which can be in the bucket at any time.
delay_pools 3 # 3 pools
delay_class 1 3 # pool 1 is class 3: aggregate network individual
delay_parameters 1 32000/32000 8000/8000 500/2000
delay_access 1 allow vip_person slow_sites
delay_access 1 allow users_network slow_sites
delay_access 1 deny all
delay_class 2 1 # pool 2 is class 1: aggregate
delay_parameters 2 -1/-1
delay_access 2 allow admins_network
delay_access 2 allow vip_person
delay_access 2 allow users_network fast_sites
delay_access 2 deny all
delay_class 3 2 # pool 3 is class 2: aggregate individual
delay_parameters 3 1024000/1024000 12800/51200
delay_access 3 allow users_network
delay_access 3 deny all
#
# Прогон через icap, кроме метода CONNECT и no_icap_sites
#
cache_peer_access icap_server deny our_networks CONNECT
cache_peer_access icap_server deny our_networks no_icap_sites
cache_peer_access icap_server allow our_networks
В этом примере принудительно установлены значения: access_log, cache_log, cache_store_log,
pid_filename, cache_dir и coredump_dir в соответствии с именем конфигурационного файла.
!!!Убедитесь, что создан каталог для cache_dir и coredump_dir!!!
Кроме того, используются acl ссылающиеся на файлы *.acl для удобства добавления/удаления
адресов в acl (синтаксис см. в руководстве по squid3).
Этап 2. Пример файла конфигурации для связки squid3+icap
/etc/squid/squid-icap.conf
http_port 127.0.0.1:3128
visible_hostname localhost
#
hierarchy_stoplist cgi-bin ?
cache deny all
#
access_log /var/log/squid/access-icap.log squid
cache_log /var/log/squid/cache-icap.log
cache_store_log /var/log/squid/store-icap.log
pid_filename /var/run/squid-icap.pid
#
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern (cgi-bin|\?) 0 0% 0
refresh_pattern . 0 20% 4320
#
cache_dir ufs /var/cache/squid-icap 100 16 256
coredump_dir /var/cache/squid-icap
error_directory /usr/share/squid/errors/Russian-1251
# Запрещаем добавлять IP пользователя в запрос
forwarded_for off
# Разрешаем выявлять зависшие соединения и отрубать их
detect_broken_pconn on
# Отключаем поддержку полузакрытых клиентов (чтобы не висели по чем зря)
half_closed_clients off
# Не использовать постоянные соединения с серверами и клиентами, когда
# для нескольких http-запросов используется одно и то же tcp-соединение
server_persistent_connections off
client_persistent_connections off
#
# Основные списки доступа
#
acl manager proto cache_object
acl localhost src 127.0.0.1/32
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
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
#
# Основные списки доступа
#
http_access allow manager localhost
http_access deny manager
#
# Основные списки доступа продолжение
#
# Запрещающие ACL
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny to_localhost
# Разрешающие ACL
# allow SSL_ports - не обязательное условие, если все стандарнтые SSL порты прописаны в Safe_ports
#http_access allow SSL_ports
http_access allow Safe_ports
http_access allow localhost
# Завершающий ACL
http_access deny all
#
# Перенаправление в ICAP для проверки на вирусы
#
icap_enable on
icap_preview_enable on
icap_preview_size 64
icap_persistent_connections on
icap_send_client_ip on
# Request Modification
#
# origin-server
# | /|\
# 5 | | 4
# \|/ | 2
# ICAP-client ------------> ICAP-resource
# (squid3) <------------ on ICAP-server
# | /|\ 3
# 6 | | 1
# \|/ |
# client
#
# Направить localhost через class_avdw_req.
# В связке с drweb-icapd:
icap_service service_avdw_req reqmod_precache 0 icap://localhost:1344/reqmod
icap_class class_avdw_req service_avdw_req
icap_access class_avdw_req allow localhost
# Или в связке с c-icap+clamav:
#icap_service service_av_req reqmod_precache 0 icap://localhost:1344/srv_clamav
#icap_class class_av_req service_av_req
#icap_access class_av_req allow localhost
# Response Modification
#
# origin-server
# | /|\
# 3 | | 2
# \|/ | 4
# ICAP-client ------------> ICAP-resource
# (squid3) <------------ on ICAP-server
# | /|\ 5
# 6 | | 1
# \|/ |
# client
#
# Направить localhost через class_avdw_req.
# В связке с drweb-icapd:
icap_service service_avdw_res respmod_precache 0 icap://localhost:1344/respmod
icap_class class_avdw_res service_avdw_res
icap_access class_avdw_res allow localhost
# Или в связке с c-icap+clamav, разрешив обход ошибки:
#icap_service service_av_res respmod_precache 1 icap://localhost:1344/srv_clamav
#icap_class class_av_res service_av_res
#icap_access class_av_res allow localhost
В этом примере принудительно установлены значения: access_log, cache_log, cache_store_log,
pid_filename, cache_dir и coredump_dir в соответствии с именем конфигурационного файла.
!!!Убедитесь, что создан каталог для cache_dir и coredump_dir!!!
Кроме того, приведен пример настройки icap в связке с модулем drweb-icapd и c-icap+clamav.
Этап 3. Создаем модифицированный init скрипт для запуска squid3 с двумя конфигурациями
Применяем патч к оригинальному скрипту /etc/init.d/squid, входящему в состав
squid3-3.0.STABLE10-2.11 и сохраняем как /etc/init.d/squid-mi
Приведен текст патча:
--- squid 2009-10-22 14:10:57.000000000 +0400
+++ squid-mi 2009-11-20 11:18:13.000000000 +0300
@@ -5,10 +5,10 @@
#
# Author: Frank Bodammer, Peter Poeml, Klaus Singvogel <feedback@suse.de>
#
-# init.d/squid
+# init.d/squid-mi
#
### BEGIN INIT INFO
-# Provides: squid
+# Provides: squid-mi
# Required-Start: $local_fs $remote_fs $network $time
# Should-Start: apache $named
# Required-Stop: $local_fs $remote_fs $network
@@ -22,8 +22,8 @@
SQUID_BIN=/usr/sbin/squid
-SQUID_PID=/var/run/squid.pid
-SQUID_CONF=/etc/squid/squid.conf
+SQUID_PID_MI=/var/run/_squid_.pid
+SQUID_CONF_MI="/etc/squid/squid-icap.conf /etc/squid/squid-noicap.conf"
SQUID_SYSCONFIG=/etc/sysconfig/squid
if [ ! -x $SQUID_BIN ] ; then
@@ -47,25 +47,32 @@
ulimit -n 4096
+GetCACHE_SWAP() {
+CONF_NAME="${1##*/}"
# determine which one is the cache_swap directory
CACHE_SWAP=`perl -n -e \
- '/^cache_dir\s+\S+\s+(.*)\s+\d+\s+\d+\s+\d+/ && print "\$1 "' $SQUID_CONF`
-[ -z "$CACHE_SWAP" ] && CACHE_SWAP=/var/cache/squid
+ '/^cache_dir\s+\S+\s+(.*)\s+\d+\s+\d+\s+\d+/ && print "\$1 "' $1`
+[ -z "$CACHE_SWAP" ] && CACHE_SWAP=/var/cache/${CONF_NAME%.*}
+}
case "$1" in
start)
- echo -n "Starting WWW-proxy squid "
+ for SQUID_CONF in $SQUID_CONF_MI; do
+ CONF_NAME="${SQUID_CONF##*/}"
+ echo -n "Starting WWW-proxy squid MI=${CONF_NAME%.*} "
+ SQUID_PID="${SQUID_PID_MI/_squid_/${CONF_NAME%.*}}"
checkproc -p $SQUID_PID $SQUID_BIN
if [ $? -eq 0 ] ; then
echo -n "- Warning: squid already running ! "
rc_failed
else
[ -e $SQUID_PID ] && echo -n "- Warning: $SQUID_PID exists ! "
+ GetCACHE_SWAP "$SQUID_CONF"
for adir in $CACHE_SWAP ; do
if [ ! -d $adir/00 ]; then # create missing cache directories
umask 027 # prevent users reading any cache data
echo -n " ($adir)"
- $SQUID_BIN -z -F > /dev/null 2>&1
+ $SQUID_BIN -f $SQUID_CONF -z -F > /dev/null 2>&1
fi
if [ ! -d $adir/00 ]; then
echo " - failed while creating cache_dir ! "
@@ -76,13 +83,17 @@
done
sleep 2
fi
- startproc -p $SQUID_PID -l /var/log/squid/rcsquid.log $SQUID_BIN -sYD
+ startproc -f -p $SQUID_PID -l /var/log/squid/rcsquid-mi.log $SQUID_BIN -f $SQUID_CONF -sYD
rc_status $RC_OPTIONS
+ done
;;
stop)
- echo -n "Shutting down WWW-proxy squid "
+ for SQUID_CONF in $SQUID_CONF_MI; do
+ CONF_NAME="${SQUID_CONF##*/}"
+ echo -n "Shutting down WWW-proxy squid MI=${CONF_NAME%.*} "
+ SQUID_PID="${SQUID_PID_MI/_squid_/${CONF_NAME%.*}}"
if checkproc -p $SQUID_PID $SQUID_BIN ; then
- $SQUID_BIN -k shutdown
+ $SQUID_BIN -f $SQUID_CONF -k shutdown
sleep 2
if [ -e $SQUID_PID ] ; then
echo -n "- wait a minute or two... "
@@ -103,6 +114,7 @@
rc_failed 7
fi
rc_status -v
+ done
;;
try-restart)
$0 status >/dev/null && $0 restart
@@ -118,25 +130,37 @@
rc_status
;;
reload)
- echo -n "Reloading WWW-proxy squid "
+ for SQUID_CONF in $SQUID_CONF_MI; do
+ CONF_NAME="${SQUID_CONF##*/}"
+ echo -n "Reloading WWW-proxy squid MI=${CONF_NAME%.*} "
+ SQUID_PID="${SQUID_PID_MI/_squid_/${CONF_NAME%.*}}"
if checkproc -p $SQUID_PID $SQUID_BIN ; then
- $SQUID_BIN -k rotate
+ $SQUID_BIN -f $SQUID_CONF -k rotate
sleep 2
- $SQUID_BIN -k reconfigure
+ $SQUID_BIN -f $SQUID_CONF -k reconfigure
rc_status
else
echo -n "- Warning: squid not running ! "
rc_failed 7
fi
rc_status -v
+ done
;;
status)
- echo -n "Checking for WWW-proxy squid "
+ for SQUID_CONF in $SQUID_CONF_MI; do
+ CONF_NAME="${SQUID_CONF##*/}"
+ echo -n "Checking for WWW-proxy squid MI=${CONF_NAME%.*} "
+ SQUID_PID="${SQUID_PID_MI/_squid_/${CONF_NAME%.*}}"
checkproc -p $SQUID_PID $SQUID_BIN
rc_status -v
+ done
;;
probe)
+ for SQUID_CONF in $SQUID_CONF_MI; do
+ CONF_NAME="${SQUID_CONF##*/}"
+ SQUID_PID="${SQUID_PID_MI/_squid_/${CONF_NAME%.*}}"
test $SQUID_CONF -nt $SQUID_PID && echo reload
+ done
;;
*)
echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}"
После проверки настроек, отключаем squid (если был включен) и включаем squid-mi (icap
должен быть запущен заранее):
chkconfig -del squid; /etc/init.d/squid stop
chkconfig -add squid-mi; /etc/init.d/squid-mi start