Etc.: Proxy сервер под Linux. Squid
Содержание
| Использование дополнительного канала для доступа в Интернет | 
Имеем маршрутизатор (Cisco) с двумя каналами доступа в Интернет через двух различных провайдеров. Клиентские компьютеры расположены в адресном пространстве одного из них, а хочется нагрузить оба канала на прием. Создаем файл as.list, содержащий список AS ,к которым мы хотим обращаться через второй канал. Конфигурируем squid: 
- acl all src 0.0.0.0/0.0.0.0  
- acl second dst_as "as.list"  
- cache_peer второй-squid parent 3129 0 no-query default (описываем вспомогательный squid как старший для нас)  
- cache_peer_access второй-squid allow second (обращаться к нему только, если сервер находится в AS из списка)  
- hierarchy_stoplist какой-нибудь-бред deny all (чтобы cgi-bin и QUERY тоже шли по этому маршруту)  
- never_direct allow second (не обращаться напрямую к серверам из AS списка)  
- never_direct deny all  
Конфигурируем вспомогательный squid-сервер (можно даже на том же хосте - специально выбран нестандартный порт; только прямого доступа к нему давать не надо): 
 
Для сбора статистики с помощью встроенного агента SNMP Squid должен быть собран с ключом --enable-snmp. По умолчанию, squid слушает SNMP запросы на порту 3401 (вместо стандартного 161). 
Для обеспечения прав доступа надо записать в squid.conf (не забывайте про сетевой экран): 
acl snmppublic snmp_community имя-сообщества
# snmp_port 3401
snmp_access allow snmppublic localhost
  
MIB файл называется /usr/local/squid/share/mib.txt: надо убрать фигурные скобки со всем содержимым из описания модуля, положить его в /usr/share/snmp/mibs. Извлечение полного дерева объектов:
   snmpwalk -p 3401 -m SQUID-MIB имя-хоста имя-сообщества squid 
При описании использована форма записи SMIv2, хотя поддерживается только SNMPv1. Единственная переменная, определенная как read-write: cacheLoggingFacility (нечаянно?). trap отсутствуют. Все объекты лежат в поддереве iso.org.dod.internet.private.enterprises.nlanr.squid (1.3.6.1.4.1.3495.1): 
- cacheSystem  - cacheSysVMsize (объем кеша в оперативной памяти, в KB)  
- cacheSysStorage (объем кеша на диске, в KB)  
- cacheUptime (в 1/100 секунды)  
 
- cacheConfig  - cacheAdmin (e-mail)  
- cacheSoftware  
- cacheVersionId  
- cacheLoggingFacility  
- cacheStorageConfig  - cacheMemMaxSize (значение cache_mem в MB)  
- cacheSwapMaxSize (значение cache_dir в MB)  
- cacheSwapHighWM  
- cacheSwapLowWM  
 
 
- cachePerf  - cacheSysPerf  - cacheSysPageFaults (потребовавших физического в/в)  
- cacheSysNumReads (число команд ввода для HTTP)  
- cacheMemUsage (в KB, у меня -1 :)  
- cacheCpuTime (секунд)  
- cacheCpuUsage (%, у меня всегда 3% :)  
- cacheMaxResSize (в KB, у меня 0 :)  
- cacheNumObjCount (число объектов в кеше)  
- cacheCurrentLRUExpiration  
- cacheCurrentUnlinkRequests (число запросов к unlinkd)  
- cacheCurrentUnusedFDescrCnt (свободных дескрипторов файлов)  
- cacheCurrentResFileDescrCnt (зарезервированных fd)  
 
- cacheProtoStats  - cacheProtoAggregateStats  - cacheProtoClientHttpRequests  
- cacheHttpHits  
- cacheHttpErrors  
- cacheHttpInKb (от клиентов)  
- cacheHttpOutKb (клиентам)  
- cacheIcpPktsSent  
- cacheIcpPktsRecv  
- cacheIcpKbSent  
- cacheIcpKbRecv  
- cacheServerRequests (к HTTP серверам и родителям)  
- cacheServerErrors  
- cacheServerInKb (от серверов)  
- cacheServerOutKb  
- cacheCurrentSwapSize (в KB)  
- cacheClients (число клиентских кешей)  
 
- cacheMedianSvcTable (усредненная статистика за интервал времени, указанный в cacheMedianTime)  - cacheMedianSvcEntry (индекс доступа к экземпляру: cacheMedianTime)  - cacheMedianTime (интервал времени усреднения: 1, 5 и 60 минут)  
- cacheHttpAllSvcTime (среднее время обслуживания всех запросов, милисекунд)  
- cacheHttpMissSvcTime (среднее время обслуживание запросов, отсутствующих в кеш или устаревших)  
- cacheHttpNmSvcTime (HTTP near miss service time)  
- cacheHttpHitSvcTime (среднее время обслуживание запросов, найденных в кеш; по-моему, считается неправильно: TCP_HIT для локального хоста без обращения к серверу картинки в 8 кБ иногда требует больше получаса)  
- cacheIcpQuerySvcTime  
- cacheIcpReplySvcTime  
- cacheDnsSvcTime (среднее время обслуживания DNS)  
- cacheRequestHitRatio (%, можно вычислить по cacheProtoClientHttpRequests и cacheServerRequests)  
- cacheRequestByteRatio (%, можно вычислить по cacheServerInKb и cacheHttpOutKb)  
 
 
 
 
- cacheNetwork  - cacheIpCache (статистика кеша IP: получение IP адреса по имени и доступность сервера)  - cacheIpEntries (элементов в кеше IP)  
- cacheIpRequests  
- cacheIpHits  
- cacheIpPendingHits  
- cacheIpNegativeHits  
- cacheIpMisses  
- cacheBlockingGetHostByName  
- cacheAttemptReleaseLckEntries  
 
- cacheFqdnCache (определение полного имени по простому)  - cacheFqdnEntries (у меня их всего 2)  
- cacheFqdnRequests  
- cacheFqdnHits  
- cacheFqdnPendingHits  
- cacheFqdnNegativeHits  
- cacheFqdnMisses  
- cacheBlockingGetHostByAddr  
 
- cacheDns  - cacheDnsRequests  
- cacheDnsReplies  
- cacheDnsNumberServers  
 
 
- cacheMesh (таблицы соседей и клиентов, их состояние и статистика, у меня не работает, да и в описании ошибки)  
 
Для мониторинга работы Squid можно использовать MRTG или rrdtool. В последнее время я потихонечку перевожу весь свой мониторинг с MRTG на rrdtool. Хотя использование rrdtool более трудоемко, зато он требует меньше ресурсов при работе и не заполняет всю имеющуюся память при проблемах с сетью. К тому же он позволяет выводить больше 2 графиков на одну картинку. При этом я имитирую внешний вид и поведение mrtg. К сожалению, не вся статистика доступна по SNMP (например, доля прерванных соединений), а часть той статистики, что должна извлекаться согласно документации, извлекается с ошибками. Нам надо: спроектировать структуру БД и создать ее; обеспечить внесение изменений каждые 5 минут; обеспечить регулярное обновление суточных, недельных, месячных и годовых графиков; создать набор HTML страниц для доступа к графикам. 
Все данные, связанные с работой Squid, у меня хранятся в одной БД. К сожалению, rrdtool не позволяет добавлять или удалять DS (data source) из существующей БД (разве что с помощью dump/restore), так что если в дальнейшем потребуется собирать дополнительную информацию, то ее придется хранить во второй БД. Интервал измерения как в mrtg - 300 секунд. Значения каждой DS хранятся в четырех RRA с использованием усреднения по 1, 6, 24 и 288 отсчетам соответственно. Размер RRA выбран достаточным для построения графиков за 2 дня, 2 недели, 2 месяца и 2 года соответственно. Информация извлекается с помощью протокола SNMP. Команду для создания БД можно взять в архиве. Имена DS совпадают с простыми дескрипторами объектов Squid MIB (некоторые пришлось "укоротить" из-за ограничения на длину имени DS в rrdtool): 
- cacheSysPageFaults  
- cacheSysNumReads  
- cacheCpuTime  
- cacheCpuUsage (не используется для построения графиков)  
- cacheNumObjCount  
- cacheCurrentUnlink  
- cacheCurrentUnusedF  
- cacheProtoClientHtt  
- cacheHttpHits  
- cacheHttpErrors  
- cacheHttpOutKb  
- cacheServerRequests  
- cacheServerErrors  
- cacheServerInKb  
- cacheCurrentSwap  
- cacheHttpAllSvcTime  
- cacheHttpMissSvc  
- cacheHttpHitSvcTime  
- cacheDnsSvcTime  
- cacheRequestHit (не используется для построения графиков)  
- cacheRequestByte (не используется для построения графиков)  
- cacheIpEntries  
- cacheIpRequests  
- cacheIpHits  
- cacheIpNegativeHits  
- cacheDnsRequests  
- cacheDnsReplies  
 
Изменения запрашиваются и вносятся в БД каждые 5 минут с помощью скрипта squid_update.sh (вызывается из crontab). 
Суточные, недельные, месячные и годовые графики генерируются скриптом squid_graph.sh соответственно раз в 5 минут, 30 минут, 2 часа и 1 день (вызывается из crontab). Скрипт имеет 2 параметра: начало отсчета (-2days, -14days, -50days и -20month) и суффикс имени PNG-файла (5min, 30min, 2h, 1d). Получаются следующие графики (за дизайн извиняйте - мне в детстве медведь наступил не только на ухо :): 
- squid_hr_???.png (эффективность кеширования в хитах и байтах)  
- squid_cpu_???.png (использование CPU)  
- squid_svctime_???.png (среднее время обслуживания запросов)  
- squid_traffic_???.png (траффик от серверов и к клиентам)  
- squid_request_???.png (число запросов в секунду)  
- squid_ipreqs_???.png (число запросов в секунду к DNS-кешу)  
- squid_ipentries_???.png (число объектов в DNS-кеше)  
- squid_dnsreqs_???.png (число запросов в секунду к DNS-серверу)  
- squid_pf_???.png (число обращений в секунду к файлу подкачки)  
- squid_reads_???.png (число чтений HTTP в секунду)  
- squid_unlinks_???.png (число удалений объектов из кеша в секунду)  
- squid_unusedfd_???.png (число используемых и свободных дескрипторов файлов)  
- squid_swapsize_???.png (используемое под кеш место на диске)  
- squid_objects_???.png (число объектов в дисковом кеше)  
- squid_errors_???.png (число ошибок в секунду)  
 
Все 4 графика каждого типа объединяются в одну HTML страницу. Чтобы не писать 15 почти одинаковых страниц, используется SSI, а именно: сделан шаблон и 15 страниц типа (title - заголовок страницы, groupprefix - начало имени файла, к которому в шаблоне добавлются суффиксы вида "_5min.png"): 
<!--#set var="title" value="Squid CPU Usage" -->
<!--#set var="groupprefix" value="squid_cpu" -->
<!--#include file="rrdtool_template.shtml" -->
  
Все страницы, посвященные мониторингу Squid, объединяются индексной страницей, содержащей 5-минутные графики всех типов и ссылки на соответствующие страницы. 
В действительно, мониторится не только Squid, так что вызовы описанных выше скриптов включены в вызовы скриптов верхнего уровня, а ссылка на индексную страницу - в управляющую консоль. 
Утилита purge позволяет извлекать сохраненные объекты из кеша (с сохранением информации о структуре URL и самих файлах) или удалять их (как "правильные" объекты с помощью обращения к Squid методом PURGE, так и ошибочные файлы напрямую). 
Сборка производится с помощью команды make (не надо читать про RCS в README!). Извлечение файлов MP3 из кеша (ограничитель шаблона - $ - ставить не надо, так как некоторые сервера добавляют всякий мусор в конце URI дабы избежать кеширования): 
./purge -n -a -s -C /tmp/MP3s/ -e '\.mp3|\.wav'|fgrep -v 'strange file'