mod_uid.c version 1.0

модуль, выдающий "правильные" cookies для подсчета посетителей сайта

Оглавление

  1. Copyright
  2. Назначение
  3. Установка (Apache 1.x)
  4. Установка (Apache 2.0.x)
  5. Конфигурация
  6. Формат cookie
  7. Что можно записать в лог
  8. Почему не mod_usertrack
  9. TODO

Copyright

Copyright (C) 2000-2002 Alex Tutubalin, lexa@lexa.ru

Допускается распространение и использование в производных продуктах на условиях аналогичных Apache License - должен быть сохранен копирайт автора и ссылка на http://www.lexa.ru/lexa, производный продукт не должен называться mod_uid

Прототип этого модуля был сделан автором при работе в компании Rambler, данная версия cущественно переработана

Автор благодарит Дмитрия Хрусталева за ценные советы.

Описание

Стандартные средства Apache не дают разумных средств трэкинга пользователей (о проблемах mod_usertrack написано ниже), данный модуль их предоставляет.

Что он делает:

Достоинства:

Установка (Apache 1.x)

При конфигурации Apache к параметрам ./configure нужно добавить --add-module=/path/to/mod_uid.c:
tar xzvf apache_1.3xxx
tar xzvf mod_uid-1.0.xx.tar.gz
cd apache_1.3xx
./configure --prefix=/usr/local/apache \
... --add-module=../mod_uid_1.0.xx/mod_uid.c other-params
make
make install

Установка (Apache 2.0)

Для работы с Apache 2.0 предназначен модуль mod_uid2.c
Сначала необходимо установить Apache 2.0.x, предположим, мы сделали это в директорию /usr/local/apache
Для установки модуля mod_uid2 нужно использовать программу apxs:
tar xzvf mod_uid-1.xx.tar.gz
cd mod_uid-1.xx
/usr/local/apach/bin/apxs -i -c -a mod_uid2.c
эта команда скомпилирует модуль (ключ -c), установит его в каталог Apache (ключ -i) и активирует модуль добавлением команды LoadModule в httpd.conf (ключ -a)

Конфигурационные директивы

Все конфигурационные директивы можно указывать где угодно - Server/VirtualServer/Location/... При указании в .htaccess должно быть разрешено AllowOverride FileInfo (или All)

UIDActive On/Off
включить-выключить выдачу cookie.
Если выдача выключена, то полученные от клиента cookies все-равно раскодируются и могут быть записаны в log.
Default: On

UIDCookieName string
Имя cookie (default - uid)
Имя cookie, выдаваемой клиенту. Не должно пересекаться с какими-то другими именами, используемыми на сайте.

UIDService number
"Номер сервиса" - строго положительное (ненулевое) уникальное число, идентифицирующее данный сервер в кластере, либо данный документ/набот документов.
Данный номер используется для двух целей:
  1. Если используется несколько серверов внутри одного домена (с одинаковым параметром cookie domain=), либо с одним hostname, то задание разных UIDService приводит к тому, что выдаваемые разными серверами cookies с гарантией будут уникальными.
  2. Использование разных UIDService для разных разделов сервера позволяет при анализе логов выяснить, на какой из разделов клиент пришел в первый раз.
Default: IP-адрес сервера.

UIDDomain .domain.name
Имя домена для которого выдается кука
В многосерверных конфигурациях позволяет иметь общее пространство cookies для всех серверов (например, для mail.rambler.ru, www.rambler.ru, info.rambler.ru используется домен .rambler.ru)
Если нужно выключить domain= для какого-то набора документов, оставив его включенным для сервера в целом, в соответствующем разделе конфигурации (Location/Directory/...) нужно использовать UIDDomain none
Defaulut: нет домена т.е. пользовательский браузер будет возвращать cookie только на исходный сервер.

UIDPath string
Путь для которого выдается cookie (параметр path= в Set-Cookie:)
Default: /

UIDExpires number
UIDExpires plus 3 year 4 month 2 day 1 hour 15 minutes
Задание Expiration date для cookie.
UIDExpires number - прибавить number секунд к текущему времени UIDExpires plus 3 year 4 month 2 day 1 hour 15 minutes - то же самое, но выраженное по человечески.
Default: прибавляется 10 лет к текущей дате

UIDP3P On/Off/Always
Управление выдачей заголовка P3P одновременно с выдачей cookie.
Варианты: Default: Off
Эта директива нужна для удовлетворения ME IE6+ в многосерверной конфигурации и, например, включения кода "счетчика" с другого сервера на страницу. В случае, когда cookie выдается без domain= или domain "покрывает" текущее имя сервера для основного документа MS IE6+ с настройками по-умолчанию удовлетворится и так, однако для составных документов, собранных с разных серверов, cookie могут подавляться.
mod_uid выдает только заголовок P3P (по-умолчанию - только с compact policy), поддержка /w3c/p3p.xml и подобного остается задачей владельца сервера.
Заголовок P3P выдается только если mod_uid выдает заголовок Set-Cookie, т.е. если у вас выдаются и другие cookie и для них тоже нужен P3P, то задачу выдачи P3P нужно решать отдельно и самостоятельно.

UIDP3PString string
Текст заголовка P3P, выдаваемый клиенту.
Default: CP="NOI PSA OUR BUS UNI"

Формат Cookie

Формат куки: В двоичном виде: unsigned int cookie[4], где
Эти 128 бит переводятся в network byte order, кодируются в base64 и отдаются клиенту (в версии 1 все отдавалось в host order, что затрудняло поддержку кластеров серверов с разной архитектурой).

Уникальность

Очевидно, что полную гарантию может дать только страховой полис и если в пределах одного домена будет выдано более чем 2^128 cookies, то какие-то из них будут повторяться. Однако при разработке формата cookie были приложены усиля к тому, чтобы при разумном количестве cookies они были бы уникальными.
  1. В случае, если "номера сервиса" уникален (свой у каждого сервера) в пределах данного домена, разные серверы будут с гарантией выдавать разные cookies.
  2. Включение в cookie времени выдачи и pid подразумевает, что pid-ы разных процессов не повторяются в течение одной секунды. На всех известных мне Unix-системах это так - pid-ы монотонно возрастают до некоего максимума - 2^16 или более - т.е. для повторения cookie[1]/cookie[2] в рамках одного сервера нужно делать больше чем 2^16 fork() в секунду, что на сегодняшний день малореально.
  3. Секвенсер (старшие 24 бита в cookie[3]) позволяет удостовериться в уникальности cookie в пределах одного процесса в течение одной секунды. Разрядность секвенсера позволяет выдавать до 1.0E+07 cookies одним процессом в секунду.

Что можно записать в лог

mod_uid пишет в notes ("заметки") одно из двух значений:
  1. Если от клиента была получена cookie, она помещается в note "uid_got"
  2. Если клиенту была выдана cookie, она помещается в note "uid_set"
Cookies пишутся в лог как 4 32-битных 16-ричных числа в host-order (т.е. для версии 2 производится преобразование network-host, для версии 1 - все пишется как есть в предположении, что архитектура сервера с момента выдачи cookie не изменилась) В LogFormat эти notes можно использовать в виде \"%{uid_got}n\" и \"%{uid_set}n\" соответственно.
При использовании LogFormat такого вида:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{uid_got}n\" \"%{uid_set}n  combined_cookie
мы получим примерно такие записи в log-е
Выданная клиенту Cookie:
62.104.212.93 - - [05/Jan/2002:00:02:06 +0300] "GET / HTTP/1.0" 200
13487 "-" "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98; Win 9x
4.90)" "-" "ruid=000000013C36184E00009A2100002901" 

Полученная от клиента Cookie:
216.136.145.172 - - [05/Jan/2002:00:14:59 +0300] "GET /buttons/but-support-e.gif
 HTTP/1.0" 200 252 "http://apache.lexa.ru/english/meta-http-eng.html" 
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" 
"ruid=000000013C361B5000009A0100009501" "-" 
Такой формат без проблем понимается распространенными анализаторами логов, включая Webtrends, который по такому логу с удовольствием считает Visitors.

Почему не mod_usertrack из поставки Apache

Потому что у него есть несколько недостатков:

TODO

  1. Поддержка разных форматов (Netscape/Cookie/Cookie2 - как в mod_usertrack), но только если появится реальная необходимость - пока таковой необходимости не замечено.
  2. Есть смутное подозрение, что на multithread-apache и многопроцессорных машине инкремент sequencer-а нужно обложить mutex-ами