Статьи :Операционные системы :Железо :
OS FAQ :
Кодинг :
Сейчас на сайте :0 пользователей, 13 гостей : |
Когда речь заходит о системах учета трафика, невольно вспоминаются сомнительного вида патчи для ядра, вереницы зависимостей, хитрые парсеры лог-файлов на перле, тяжелые SQL.ные базы и приблуды на php. В результате такой конструкции существенно увеличивают
Автор: Разместил: Amro Дата: 2006-06-03 20:14 Комментарии: ![]() ![]()
Средняя оценка участников (от 1 до 10): Пока не оценено
Проголосовавших: 0 Система учета трафика в считанные минутыОригинал статьи в журнале Xakep Когда речь заходит о системах учета трафика, невольно вспоминаются сомнительного вида патчи для ядра, вереницы зависимостей, хитрые парсеры лог-файлов на перле, тяжелые SQL.ные базы и приблуды на php. В результате такой конструкции существенно увеличиваются системные требования и снижаются надежность и безопасность хоста в целом. Поэтому сегодня я хочу поведать тебе об одном довольно простом и элегантном способе подсчета трафика, который можно применять в домашних сетях. Chillin Возьмем самый распространенный случай, когда в твой подъезд/универ/офис заведен кабель от прова, выделен статический IP-адрес, а в роли маршрутизатора выступает старенький комп с двумя сетевухами и установленной FreeBSD 5.х. Что касается фряхи, то она у нас (для остроты ощущений) будет не совсем обычной. Мы откажемся от использования штатных файрволов ipfw2/ipfilter и прикрутим OpenBSD.шный pf, по фичам и возможностям не имеющий себе равных среди свободно распространяемых брандмауэров. Ядра - чистый изумруд Наличие поддержки интерфейса обратной петли (loopback), сети Ethernet и фильтров пакетов Беркли обязательно: device loop device ether device bpf Следующим шагом будет объявление директивой options переменных PFIL_HOOKS и RANDOM_IP_ID (генерируем случайное значение в поле ID IP-пакета вместо того, чтобы каждый раз увеличивать его на единицу). Только так мы получим практически полноценную поддержку packet filter нашим ядром: options PFIL_HOOKS options RANDOM_IP_ID Поддержка практически полноценная, так как ALTQ и работа с протоколом IPv6 пока находится в стадии бета-тестирования, но не волнуйся: ни то ни другое нам не понадобится. С помощью утилиты config производим синтаксический анализ конфигурационного файла ядра и создаем компиляционный каталог со всеми необходимыми заголовочными файлами: # config MIDIAN Ненадолго отвлекаемся от ядерных экспериментов и устанавливаем packet filter из портов: # cd /usr/ports/security/pf # make install clean Далее переходим в директорию с сырцами и не спешим, так как дедовский метод сборки ядра (make clean && make depend && make && make install) для пятой ветки уже не подходит: # cd /usr/src # make buildkernel KERNCONF=MIDIAN # make installkernel KERNCONF=MIDIAN Ставим на автомат В отличие от большинства файрволов, packet filter не использует систему Syslog и регистрирует все события с помощью собственного журнального демона pflogd. Отслеживаемые на псевдоустройстве /dev/pf пакеты перенаправляются на сетевой интерфейс pflog0, откуда, попав в компетенцию pflogd, в двоичном формате tcpdump методично записываются в файл /var/log/pflog. В конфиге /etc/rc.conf следующими записями разрешаем автоматическую загрузку pf и pflogd при старте системы (последней директивой pf_conf задается путь к файлу с правилами fw): # vi /etc/rc.conf pf_enable="YES" pf_logd="YES" pf_conf="/usr/local/etc/pf.conf" Но этого недостаточно, так как по умолчанию фряшные системные файлы ничего не знают о директивах pf_*, поэтому придется подготовить init-скрипт, содержащий всю необходимую информацию о специальных переменных и модулях pf. К счастью, кодить нам не придется, все уже сделано до нас: # mv /usr/local/etc/rc.d/pf.sh.sample /usr/local/etc/rc.d/pf.sh Создать универсальный набор рулесетов файрвола, ввиду специфики условий работы, не представляется возможным, поэтому опишу только общую часть, которая затрагивает систему NAT и редирект http-трафика: # vi /usr/local/etc/pf.conf // внешний сетевой интерфейс ext_if="fxp0" // внутренний сетевой интерфейс int_if="fxp1" // в таблицы радикса заносим айпишники клиентов и доверенные подсети table persist file "/usr/local/etc/nat.conf" table { 192.168.5.0/24, 192.168.7.0/24 } // NAT.им юзверей (производим трансляцию адресов) nat on $ext_if from to any -> $ext_if // заворачиваем на проксик все клиентские http-запросы rdr on $int_if inet proto tcp from to ! port \ { 80, 8080, 8101 } -> 127.0.0.1 port 3128 Предлагаю дальнейшую разработку правил firewall.а возложить на твои мужественные/женственные плечи и перейти непосредственно к нашим клиентам, страстно жаждущим получить доступ в Сеть: # vi /usr/local/etc/nat.conf 192.168.5.2/32 192.168.5.3/32 192.168.5.9/32 Теперь с помощью механизма sysctl включаем перенаправление IPv4-пакетов между сетевыми интерфейсами (скажу по секрету: сетевые подсистемы Linux и BSD спроектированы так, что форвардинг должен работать по дефолту, однако такое поведение запрещено рабочими документами RFC, именно поэтому нам приходится ручками ковырять sysctl): # vi /etc/sysctl.conf net.inet.ip.forwarding=1 Чтобы все изменения вступили в силу, перезагружаемся: # reboot Считаем трафик, не отходя от кассы Коллекция портов FreeBSD . настоящая панацея для ленивого юниксоида. Заботливые разработчики подготавливают правила сборки программ, размещая рядом тщательно протестированные diff.чики, конфиги и скрипты. Отказаться от таких удобств было бы просто преступлением: # cd /usr/ports/net/ipfm # make install clean # cd /usr/ports/www/apache13 # make install clean # mkdir /usr/local/www/data/traffic Этими нехитрыми командами мы поставили саму считалку трафика и web-сервер Apache. Для отображения пользовательской статистики воспользуемся встроенным средством апача, а именно опцией Indexes директивы Options (листинг каталога при отсутствии index.html). Но об этом чуть позже, а пока конфигурим его величество ipfm: # vi /usr/local/etc/ipfm.conf // определяем внутренний сетевой интерфейс DEVICE fxp1 // не учитываем локальный трафик LOG 192.168.5.0/255.255.255.0 NOT WITH 192.168.0.0/255.255.0.0 // задаем имя журнального файла в формате год/месяц_прописью/число FILENAME "/var/log/ipfm/%Y/%B/%d" // сбрасываем данные из буферов каждые полчаса DUMP EVERY 30 minutes // никогда не очищаем статистику, за нас это делает cron CLEAR NEVER
// не преобразовываем IP-адреса в доменные имена NOPROMISC Далее утилитой crontab вызываем текстовый редактор (тот, что определен в переменной окружения $EDITOR) для постановки следующих команд на исполнение в заданное время: # crontab .e 5,35 * * * * cp .p .R /var/log/ipfm/* /usr/local/www/data/traffic 30 7 1 * * kill .s HUP `cat /var/run/ipfm.pid` Таким образом, всякий раз при наступлении пятой и тридцать пятой минуты будет происходить рекурсивное копирование каталогов с полученной от ipfm статистикой в директорию, доступную апачу. Сам web-сервер Apache можно вообще не конфигурировать, нас вполне устроят настройки по умолчанию. Хотя особо педантичные товарищи могут проверить, установлена ли опция Indexes для корневого каталога /usr/local/www/data: # egrep -n 'data|Indexes' /usr/local/etc/apache/httpd.conf 378: 387:Options Indexes FollowSymLinks MultiViews Вот, собственно, и все. Последние приготовления сделаны, считалку трафика и апач можно запускать на орбиту: # /usr/local/sbin/ipfm -c /usr/local/etc/ipfm.conf -p /var/run/ipfm.pid # /usr/local/sbin/apachectl start Теперь, чтобы посмотреть статистику, достаточно в браузере набрать ip.address.http.server/traffic/. Подсчитал? Теперь сэкономь! Роль заботливого экономиста традиционно выполняет кэширующий прокси-сервер squid. Поставить кальмара из портов нам не удастся, так как в правилах сборки не реализована поддержка pf. Поэтому с официального сайта забираем последнюю версию (в данном случае ежедневно генерируемый тарболл), распаковываем полученный архив и переходим в созданный каталог: % wget www.squid-cache.org/Versions/v2/2.5/squid-2.5.STABLE4- YEARMONTHDAY.tar.gz % tar zxvf squid-2.5.STABLE4-YEARMONTHDAY.tar.gz % cd squid-2.5.STABLE4-YEARMONTHDAY После выполнения этой стандартной процедуры начинаем выяснять, с какими параметрами нам нужно скомпилировать кальмара (не советую здесь баловаться с флажками оптимизации, так как squid беспечно работает с памятью, выделяемой под хранимые объекты, sigh): % ./configure --help | more % ./configure --prefix=/usr/local/squid --sysconfdir=/etc/squid --enable-storeio="ufs diskd" --enable-poll --enable-pf-transparent --disable-ident-lookups --enable-removal-policies="lru heap" --disable-wccp --enable-err-language=Russian-koi8-r В данном случае ключевым аргументом сценария configure является параметр.enable-pf-transparent. Именно он дает нам возможность насладиться прелестями прозрачного проксирования. Поясню для тех, кто не в курсе: с помощью прозрачного проксирования для клиентских хостов создается иллюзия прямого соединения с www-узлами интернета (клиентские браузеры не нужно настраивать специальным образом, что очень удобно при наличии в сети большого числа машин), так как все пакеты, в адресах назначения которых содержится 80/tcp порт, будут автоматически перенаправляться squid.у на 3128/tcp порт. С этим разобрались, теперь давай от теории вернемся к созидательной практике, тем более что configure подкинул нам повод для размышлений: WARNING: Cannot find necessary PF header file Transparent Proxy support WILL NOT be enabled Однако не все так просто, как могло показаться на первый взгляд. Попробуем с этим разобраться: % grep pf config.log configure:3843: checking for net/pfvar.h configure:3849:23: net/pfvar.h: No such file or directory Как видно из сообщения об ошибке, сценарий configure в директории /usr/include/net не смог найти необходимый для успешной компиляции заголовочный файл pfvar.h. Что ж, придется ему помочь: # ln -s /usr/local/include/pf/net/pfvar.h /usr/include/net/pfvar.h А теперь, чтобы вновь не получить от configure отрицательный результат (уже скэшированный), правильнее будет удалить текущий каталог и повторить пункты с распаковкой архива и запуском configure. После проделанных манипуляций сценарию не остается ничего другого, кроме как сдаться: PF Transparent Proxy enabled Вот теперь можно переходить к самой компиляции кальмара: % gmake И, убедившись в отсутствии ошибок при сборке, инсталлируем: # gmake install Для удобства просмотра логов squid.а можно сразу после установки сделать символическую ссылку на более привычный каталог: # ln -s /usr/local/squid/var/logs /var/log/squid Игры с кальмаром Ниже перечислю только первостепенные параметры кэша. Более подробную инфу по настройке squid.а ты найдешь в многочисленных руководствах на сайте squid.opennet.ru. # vi /etc/squid/squid.conf // указываем адрес, на котором squid будет слушать клиентские запросы http_port 127.0.0.1:3128 // выделяем под кэш требуемый объем оперативки и дискового пространства (в данном случае 1 Gb) cache_mem 128 MB cache_dir diskd /usr/local/squid/var/cache 1024 16 256 Q1=72 Q2=64 // не ленимся вести журналы работы cache_access_log /usr/local/squid/var/logs/access.log cache_log /usr/local/squid/var/logs/cache.log cache_store_log none // снижаем привилегии cache_effective_user squid cache_effective_group squid // работаем в режиме транспарентной прокси httpd_accel_host virtual httpd_accel_port 80 httpd_accel_with_proxy on httpd_accel_uses_host_header on С главным конфигурационным файлом сквида закончили, теперь нужно создать группу и учетную запись непривилегированного пользователя, от имени которых будет запускаться и работать наша прокся: # pw groupadd squid -g 3128 # pw useradd squid -u 3128 -c "squid caching-proxy pseudo user" -g squid -d /usr/local/squid -s /sbin/nologin Назначаем корректные права доступа для кэша, директории с журнальными файлами, а также для специального псевдоустройства, позволяющего программам (скажем, pfctl) контролировать поведение packet filter через системные вызовы ioctl(2): # chown squid:squid /usr/local/squid/var/cache # chown squid:squid /usr/local/squid/var/logs # chgrp squid /dev/pf # chmod g+rw /dev/pf Создаем кэш прокси-сервера, иначе говоря, обнуляем структуру каталогов: # /usr/local/squid/sbin/squid -z 2004/01/30 17:24:28| Creating Swap Directories # /usr/local/squid/sbin/squid Альтернативным вариантом будет запуск кальмара с аргументами: ?-D> для пропуска DNS-теста (помогает при модемном соединении либо при неверно настроенном сервере имен) и ?-Y> для более быстрого восстановления после сбоев: # /usr/local/squid/sbin/squid .DY Вуаля. Транспарентный проксик созрел и готов принимать наши запросы: # netstat -na --inet | grep 3128 tcp4 0 0 127.0.0.1.3128 *.* LISTEN Разбор полетов Да, все шустро и безглючно воркает, но если ты взглянешь в /var/log/squid, то, скорее всего, тебе станет дурно: за какие-то пару часов работы сквид произведет на свет вагон и маленькую тележку журнальных записей о www-соединениях в неудобочитаемом виде (конечно, все зависит от количества клиентов и интенсивности подключений). Чтобы разобрать эту кашу, никакие калькуляции в уме/в столбик не помогут. Поэтому воспользуемся sarg.ом - одной из самых популярных на сегодняшний день программ для построения детальных html-отчетов на основе лог-файлов squid.а. И здесь нас выручает дерево портов: # cd /usr/ports/www/sarg # make install clean Большинство параметров sarg.а можно оставить без изменений, перечислю только те, на которые стоит обратить особое внимание: # vi /usr/local/etc/sarg/sarg.conf // абсолютный путь до лог-файла squid access_log /usr/local/squid/var/logs/access.log // директория, куда будут помещаться html-отчеты output_dir /usr/local/www/data/reports // не учитываем локальный www-трафик exclude_hosts 192.168.5.0 // создаем отметки времени в европейском формате date_format e // для экономии места перезаписываем отчеты overwrite_report yes И, наконец, через crontab передаем демону cron новые задания: каждое первое число месяца производить ротацию логов сквида и ежечасно обрабатывать логи sarg.ом (если ты считаешь, что запускать такие задания от имени суперпользователя несколько рискованно, то используй команду crontab .u username): # crontab -e 0 8 1 * * /usr/local/squid/sbin/squid -k rotate 0 * * * * /usr/local/bin/sarg -f /usr/local/etc/sarg/sarg.conf Chillout Вот так, в сжатые сроки и без единой строчки кода, у нас получилась полноценная система учета трафика. Если будут проблемы/комментарии/идеи - мыль, по возможности отвечу. Таблицы радикса Таблицы радикса (radix tables) - это именованные массивы, предназначенные для хранения IP-адресов и целых подсетей. Таблицы очень удобно использовать, когда нужно оперировать большими диапазонами адресов. К примеру, немедленно блокируем все соединения с айпишниками, зарезервированными для внутреннего использования (см. RFC 1918): table const { 10/8, 172.16/12, 192.168/16 } block in log quick on $ext_if inet from to any block in log quick on $ext_if inet from any to Приручаем VPN Для того чтобы клиенты могли выходить в инет, используя виртуальные частные сети, нужно с помощью packet filter разрешить исходящие соединения по протоколу gre: pass out on $ext_if inet proto tcp from any to any flags S/SA keep state pass out on $ext_if inet proto { udp, icmp, gre } all keep state Интересные тулзы pftop (www.eee.metu.edu.tr/~canacar/pftop/) . утилита для мониторинга работы pf в реальном времени. pfstat (www.benzedrine.cx/pfstat.html) . утилита для сбора статистики pf и построения красивых графиков с использованием библиотеки gd. hatchet (www.dixongroup.net/hatchet/) . анализатор лог-файлов pf. INFO В данном примере fxp0 . это внешний сетевой интерфейс, имеющий выделенный статический IP-адрес, а fxp1 . внутренний интерфейс с айпишником из диапазона адресов класса С (fxp - это драйвер семейства сетевых карт Intel EtherExpress 100). DANGER Если в роли шлюза выступает маломощный компьютер, то для более быстрой обработки данных при настройке ipfm не задавай сортировку логов и используй опции NORESOLVE, NOPROMISC. WWW www.openbsd.org/faq/pf/index.html www.aei.ca/~pmatulis/pub/obsd_pf.html Деликатный сивисап Грамотно синхронизировать дерево портов и исходный код FreeBSD нам поможет система cvsup. Фича заключается в том, что достаточно всего один раз получить полный набор исходных текстов, а затем с помощью cvsup мержить только произошедшие изменения. Создаем конфигурационный файл, содержащий всю информацию, необходимую для обновления системы. Здесь мы выбираем ближайший миррор, указываем месторасположение сырцов, задаем релизный тег, а также, помимо сырцов, обновляем и коллекцию портов: Конфиг ~/cvs-supfile *default host=cvsup5.ru.FreeBSD.org *default base=/usr *default prefix=/usr *default release=cvs tag=RELENG_5_1 *default delete use-rel-suffix *default compress src-all ports-all tag=. Теперь проапдейтиться можно следующим образом: # /usr/local/bin/cvsup -g -L 2 ~/cvs-supfile Подробнее об используемых параметрах cvsup: -g . не используем графическую версию сивисапа; -L 2 . устанавливаем степень журналирования событий. Автор: Andrey Matveev |