On-Line Библиотека www.XServer.ru - учебники, книги, статьи, документация, нормативная литература.
       Главная         В избранное         Контакты        Карта сайта   
    Навигация XServer.ru








 

Эхо боя, оптимизация логов

Дмитрий Лебедев

Дал знакомому посмотреть сайт, который дома тестирую. Он посмотрел, похвалил, а я решил посмотреть, что он видел. Открываю логи Апача, смотрю и через некоторое время обнаруживаю, что кроме товарища ещё кто-то лазил на мой домашний сервер.

Вот он, вирус CodeRed, о котором так долго твердили большевики.



"GET /default.ida?XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX%u9090%u6858%ucbd3%u780
1%u9090%u6858%ucbd3%u7801%u9090%u6858%ucbd3%u7801%u90
90%u9090%u8190%u00c3%u0003%u8b00%u531b%u53ff%u0078%u0
000%u00=a HTTP/1.0" 404 270


В те моменты, когда я подключался к сети по диалапу со включенным Апачем, ко мне, словно звуки далёкой канонады, приходили такие запросы. Учитывая то, что в IPv4 2^32 адресов, по которым вирус рассылается случайным образом, можно восхищаться масштабами его распространения.

Заодно перенастроил правила в Atguard, чтобы не разрешать соединяться с Апачем откуда-то ни было кроме 127.0.0.1.

Кстати, именно как по эху - вернее как по кругам на воде - недавно замерили активность и направленность DoS-атак во всём интернете (русский комментарий к результатам - здесь [1]). При отправке запроса на соединение хулиган, чтобы не быть пойманным, меняет обратный адрес IP-пакета на случайный. Имея много ip-адресов, можно собирать приходящие ответы от атакуемых серверов и делать расчёты. Интересно, можно ли, слушая запросы из сети и имея алгоритм выбора случайного числа вируса CodeRed (насколько я понял из сетевых обзоров, две его версии можно отличить по строке запроса), подсчитывать количество заражённых?



RomikChef прислал описание оптимизации работы с логами.

О! Какая статья интересная, а я и не читал :-( А может, и хорошо, что не читал, потому что всё по-другому сделал. Мне кажется, что у Димы не очень удачная организация базы.

У меня запись занимает ровно 20 байт. может быть, это тоже не самая удачная, но, сами понимаете, размер на порядок, а то и на два меньше.

id - 4 байта
ip - 4 байта
таймстамп - 4 байта
дальше идут ссылки на словари, каждая по 2 байта
page - $PHP_SELF
agent - бровзер
реферер - реферер
баннер - баннер

Теперь по пунктам.

- ip, упакованный в 4 байта, это, конечно, короче, чем хост. Тем более, что толку от хоста в базе нет. И группировать по int, мне кажется, база будет быстрее, чем по строкам. Да, вывод информации происходит медленнее, поскольку надо ресолвить сразу кучу адресов. Но я могу и подождать - при просмотре торопиться некуда. Имхо. А вот при записи на ресолвинг времени не тратится.
- таймстамп не родной, а юниксовский. И не потому, что родной занимает на 1 байт больше, а потому, что когда пришлось логи малость подправить, сами понимаете, стампы все сбились.
- page. Это понятно. Словарь всех страниц сайта. Таблица небольшая, всё летает.
- агент. То же самое.
- баннер - тоже понятно. Какой баннер был показан.
- реферер. Самое шаткое место. Да, таблица растет. но, как вы понимаете, 90% рефереров - со своего сайта. В принципе, одиночные реферера можно и почистить. Query_string у внутренних рефереров отсекается. У чужих - отсекается тоже и пишется отдельно, для анализов.

Теперь по замечаниям в обсуждениях. Да, я пишу все хиты. Во-первых, при моем размере записи это не напряжно. во-вторых, если чувак нажал релоад, ему показался другой баннер, мне это надо учитывать.

И ещё. Вопрос. Кто как отличает роботов от людей? Я определяю по включенной графике. И в принципе, моя статистика не сильно разнится со спайлоговской.


Что там у меня было раньше?



CREATE TABLE logs (
date datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
(можно TIMESTAMP)
ip varchar(16) NOT NULL,
host varchar(255) NOT NULL,
browser varchar(64) NOT NULL,
referer varchar(255) NOT NULL,
request_uri varchar(255) NOT NULL,
);


Признаться, я делал эту систему, когда не знал существования функций ip2long [2] и long2ip [3]. Потом переделывать руки не доходили. А преобразуется ip-адрес в целое число переведением всех четырёх чисел адреса в двоичный код (с дополнительными нулями: 255 переводится в 11111111, а 4 - в 00000100), убираются точки, и получившееся число переводится обратно в десятичный. В IPv4 может быть 2^32 адресов, т.е. (2^8)^4 - итого число занимает четыре байта.

Timestamp из Юникса пишется просто - функция UNIX_TIMESTAMP. Выбирается так же просто - для группировки по дням, неделям, дням недели или чему-то ещё используется стандартная функция MySQL FROM_UNIXTIME:



SELECT DATE_FORMAT(FROM_UNIXTIME(date),'%e.%m.%Y') AS date_group, COUNT(ip) AS visits FROM logs GROUP BY date_group ORDER BY DATE_FORMAT(FROM_UNIXTIME(date),'%Y%m%d');

Чем больше узнаёшь возможностей MySQL, тем больше кажется, что ты ничего не знаешь. Каких там функций только нет!

В чём я не уверен, так это в целесообразности держания словарей адресов, рефереров и броузеров. Надо при записи лога выбирать идентификаторы, проверять, вставлять новую запись, если таковой не нашлось.



$page_result = mysql_query("SELECT id FROM page WHERE address='$PHP_SELF'");
if (@mysql_num_rows($page_result)==1)
  $page_id = mysql_result($page_result, 0);
elseif (!mysql_error()) {
  mysql_query("INSERT INTO page (address) VALUES ('$PHP_SELF')");
  $page_id = mysql_insert_id();
  };


Не хочется объединять таблицы при запросе, хотя меньше данных надо обрабатывать - в главной таблице объём файла становится гораздо меньше, что ускоряет работу. Неясно, правда, сколько дополнительного времени это займёт при записи логов. По этому вопросу и мне, и Ромику хотелось бы услышать мнение общественности. Прошу высказываться в отзывах.



Литература по Internet