Часть 3

Я не поклонник киберсквоттинга, но и осуждать его не могу: он не нарушает букву закона, а потому имеет право на жизнь, как и любой другой законный бизнес. Каждый из нас сам выбирает, чем заниматься и как зарабатывать деньги. Главное условие, как говаривал известный персонаж, — чтить Уголовный кодекс.

Тем, кто решил попробовать свои силы в этом деле, предлагаю обзавестись инструментами, облегчающими работу начинающему хапперу.

Как вам, должно быть, известно, необходимую информацию о том, занят или свободен домен, а также кто его владелец и когда истекает срок регистрации, можно получить с помощью специальных сервисов, названных WhoIs.

Можно, конечно, проверять занятость интересующих доменов вручную, записывая в блокнот дату окончания их регистрации. Но это неудобно: запросто можно пропустить освобождение «лакомого» доменного имени. Почему бы не автоматизировать процесс слежения, тем более что это не так сложно?

Все, что вам понадобится, — это не слишком глубокие познания в веб-программировании, а также наличие хостинга с поддержкой PHP (Perl или другого языка, на котором вы пишете) и серверной панели кронтаб1 (crontab).

Что должен делать наш скрипт? Будучи запускаемым с определенной периодичностью, он должен подключаться к службе WhoIs и с помощью несложных манипуляций «вытаскивать» дату освобождения доменов. Если по какому-нибудь домену эта дата вот-вот наступит и пора готовиться к «захвату», наш скрипт должен отправить своему хозяину соответствующее напоминание на почтовый ящик. Вот, собственно, и все. Единственная загвоздка заключается в том, что формат базы WhoIs для разных доменных зон различен: для .ru он один, для .com совсем другой. Однако при грамотном подходе это не проблема.

Полностью скриптовый код я приводить не буду. Каким бы простым он ни был, у вас останется лишний повод поупражняться в программировании (или начать его изучать). Короче говоря, самым вкусненьким я вас угощу, а остальное додумаете сами.

Итак, нам понадобится два скрипта — admin.php и check.php. Первый будет выполнять функцию визуальной панели управления, на второй же возложим всю черную работу по проверке состояния доменов.

Моя реализация — язык PHP, мне он наиболее близок. Как вы понимаете, подобные инструменты можно реализовать на любом языке, ориентированном на Web.

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

Общий принцип работы скриптов будет таким: пользователь задает список доменов, которые необходимо отслеживать. Кроме того, он определяет, на какие ящики отправлять предупреждение о скором освобождении домена и за сколько суток до этого события должно быть отправлено письмо. Можно также предусмотреть возможность настройки формата письма. Проверка всех доменов из списка в службе WhoIs будет происходить с определенной периодичностью, скажем раз в сутки. В случае если у какого-то из доменов дата окончания регистрации уже близка, на наш ящик направляется соответствующее письмо.

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

Файл admin.php будет интерактивным. В нем мы отредактируем:

  • список почтовых ящиков для отправки оповещения;
  • контрольный срок оповещения;
  • тему и тело сообщения;
  • собственно список доменов.

Всю эту информацию мы будем сохранять в разных текстовых файлах, например, список доменов — в list.txt, список почтовых ящиков — в email.txt, тело письма — в body.txt и т.д.

На этой же странице можно приводить результаты последней проверки в виде таблицы: «домен — дата последней проверки — дата освобождения».

Все, что нам необходимо, — это создать интерфейс (с помощью соответствующих html-тегов) и обеспечить редактирование и сохранение данных.

Рис. 1. Внешний вид «интерфейсного» скрипта

На рис. 1 можно видеть, что мы должны получить в результате, и с первым проблем у вас, уверен, не возникнет.

А со вторым я немного помогу.

По нажатию кнопки «Обновить» (у нее может быть любое другое название) необходимо обеспечить обновление содержимого текстовых файлов. Делаем это, допустим, так:

if($action=="update"){
$a1 = explode("
", $list_box);
$fp1 = fopen("email.txt", "w");
if(count($a1)>0){
while (list($key, $val) = each($a1))
{
$em = stripslashes(trim(chop($val)));
fputs($fp1, $em."
");
}
}
fclose($fp1);

Это пример для файла email.txt, в котором у меня хранятся адреса ящиков для отправки напоминаний.

Переменная $list_box содержит список ящиков. Строкой:

$a1 = explode(?
?, $list_box);

мы распределяем содержимое переменной на адреса отдельных ящиков, ориентируясь по символу переноса каретки, поскольку заранее знаем, что каждый ящик в форме был введен с новой строки. Для указания ящиков послужит элемент textarea с именем list_box:


В результате имеем массив $a1, содержащий список ящиков, и далее в цикле while записываем содержимое этого массива в текстовый файл.

Не забудьте закрыть файл функцией fclose(). Аналогичным образом заносим в «родные» файлы и другую информацию.

Кстати, для того чтобы сработало условие по if, как вы уже догадались, в текст формы нужно включить скрытое поле с именем action и значением update:

На этой же странице admin.php для удобства можно предусмотреть возможность проверки всех доменов прямо сейчас, по требованию.

Для этого делаем вторую форму, в которую помещаем лишь два элемента — кнопку и скрытое поле:

Обработка этой формы может быть такой:

if($action=="run_check"){
$time = (count($list_domain)*9);
echo "Началась проверка доменов. Время проверки
 ".$time." секунд";
include("check.php");
flush();
}

В массиве $list_domain хранится список доменов для проверки, потому что именно такое имя имеет элемент textarea, в котором пользователь этот список просматривает и редактирует.

Как видите, для проверки доменов мы запускаем скрипт check.php, включая его в наш код функцией include(). Сам check.php мы рассмотрим позже, а пока обратим внимание на одну интересную деталь реализации, а конкретно на следующую строку:

$time = (count ($list_domain)*9);

В течение именно такого времени (в секундах) будет выполняться проверка всего списка. Почему так?

Дело в том, что в правилах использования службы WhoIs РосНИИРОСа значится следующее: «С одного IP-адреса допускается делать не более 12 запросов в минуту. Если с одного IP-адреса в течение минуты приходят запросы сверх допустимого количества, то вместо их обработки возможна выдача предупредительного сообщения. Если в течение часа пользователь неоднократно превышал скорость поступления запросов, то предоставление WhoIs-сервиса пользователю прекращается». Нам, конечно, не хочется попасть в немилость к РосНИИРОСу, а потому между проверками двух соседних доменов в цикле будет использоваться задержка в девять секунд (с запасом). Напомню: задержка в выполнении скрипта может быть достигнута с помощью функции sleep(), параметром которой должна быть цифра, обозначающая количество секунд задержки.

Конечно, в нашем списке могут оказаться не только домены в зоне .ru, их может и вообще там не быть, но мы все равно введем такое правило для подстраховки. Лучше подождать чуть подольше, чем вообще лишиться возможности пользоваться российским WhoIs.

Теперь настало время рассмотреть, как работает скрипт check.php, который, как вы помните, запускается с кронтаба и выполняется с определенной периодичностью, зададанной ему вами в файле кронтаба. Какую периодичность задать, решите сами, главное, чтобы проверка происходила не реже установленного срока отправки напоминания, иначе освобождение домена можно прозевать. Например, если вы установили (как в нашем случае, см. рис. 1), что напоминание необходимо высылать за два дня до даты освобождения, то позаботьтесь о том, чтобы check.php запускался не реже чем каждые двое суток, а лучше ежедневно.

Итак, check.php.

Для начала необходимо задать параметры WhoIs-серверов тех доменных зон, за которыми мы будем следить (рис. 2). Пусть нас интересуют домены в .com, .net, .ru и .ua. Тогда создадим в самом начале скрипта следующий массив:

$whois_server = array(
"com" => array("whois.internic.net",
 "No match for", "Expiration Date:"),
"net" => array("whois.internic.net",
 "No match for", "Expiration Date:"),
"ru" => array("whois.ripn.net",
 "No entries found for the selected source",
 "paid-till:"),
"ua" => array("whois.com.ua",
 "No entries found for domain", "OK-UNTIL"),
);
Рис. 2. С помощью такой формы можно проверить состояние домена

К каждой доменной зоне, как видим, привязываются подмассивы, содержащие по три элемента:

  • адрес сервера WhoIs;
  • запись, которую выдает сервер в ответ на запрос по незарегистрированному домену;
  • запись, которая предваряет дату освобождения домена.

Как видим, форматы у разных WhoIs-серверов разные. Например, для доменов в интернациональных зонах сигналом о дате освобождения будет запись «Expiration Date», а для .ru-доменов — запись «paid-till» (рис. 3, 4, 5). Различие в форматах ответа разных WhoIs-серверов создает основную проблему, из-за которой громоздкость нашего скрипта, к сожалению, значительно увеличивается.

Рис. 3. Формат ответа российского WhoIs
Рис. 4. Формат ответа международного WhoIs INTERNIC
Рис. 5. Формат ответа украинского WhoIs

Весь программный код я приводить здесь не буду. Остановлюсь только на самых интересных моментах.

Для начала необходимо проверить, зарегистрирован ли вообще интересующий нас домен. Для этого нужно определить, к какому WhoIs-серверу подключаться, поэтому начнем с функции — назовем ее domain_tld(), — которая будет определять, к какой доменной зоне принадлежит выбранный домен. Все, что нам нужно, — «вытащить» из доменного имени то, что находится после точки. Для этого задействуем регулярные выражения:

if(ereg(".([^.]+)$", $domain, $answer))
$ret = strtolower($answer[1]);

Функция ereg() возвращает истину, если вхождение первого параметра во второй найдено. Результат при этом записывается в массив $answer. После этого на всякий случай преобразуем содержимое $answer в нижний регистр.

Далее в зависимости от полученного результата подключаемся к нужному WhoIs-серверу. Для соединения с серверами WhoIs напишем такую простенькую функцию:

function whois_request($server, $domain){
$data = "";
$fp = fsockopen($server, 43);
if($fp){
fputs($fp, $domain."
");
while(!feof($fp))
{$data .= fread($fp, 1000);}
fclose($fp);
}
return $data;
}

Как видим, соединение с WhoIs происходит обычным способом, обязательно по порту 43. Для передачи проверяемого доменного имени серверу используем функцию fputs(). В ответ получаем определенную информацию и записываем ее в переменную $data. Естественно, $server и $domain выбираем на основании данных в массиве $whois_array в зависимости от того, какой результат был получен функцией domain_tld() на предыдущем этапе.

Итак, мы получили от WhoIs информацию о домене. Пока она хранится в том виде, в каком нам выдал ее сервер. Теперь предстоит самое главное — обработать ее и определить дату освобождения домена. Но для начала проверим, а не свободен ли он уже. Как вы помните, это можно определить по наличию контрольных строк: «No match for» для интернациональных доменов, «No entries found for the selected source» — для RU, и так далее. Эти контрольные строки мы еще в самом начале внесли в массив $whois_server.

Наличие этих строк в полученной информации определим так:

if(strstr($data, $whois_server[$tld][1])
 != ??){...}

Если соответствующая сигнальная строка найдена, то мы принимаем, что домен не зарегистрирован (рис. 6), в противном случае — продолжаем разбор.

Рис. 6. Результаты последней проверки по списку

Нам осталось фактически лишь определить дату освобождения домена. Для этого напишем функцию get_date():

function get_date($data){
global $whois_server, $last_tld;

Контрольную строку, предваряющую дату освобождения, сохраним в переменной $control:

$control = $whois_server[$last_tld][2];

Найдем позицию, с которой начинается эта контрольная строка:

$position = strpos($data, $control);

Теперь обрежем весь текст, находящийся до даты:

$new_data = substr($data,
 ($position + strlen($control)));

В переменной $new_ data останется текст начиная с даты освобождения. Нам необходимо отделить эту дату от следующего за ней «мусора». Сделаем это, найдя первый за датой перенос строки и обрезав все, что находится за ним, параллельно избавившись и от лишних пробелов:

$position2 = strpos($new_data, "
");
$new_data2 = trim(chop(substr($new_data,
 0, $position2)));

В результате в переменной $new_data2 имеем дату освобождения домена в том виде, в каком нам ее выдал WhoIs. Увы, этот вид не всегда удобоварим и в каждом WhoIs он свой. Например, в интернациональных доменах дата содержится в виде «26-oct-2004», в русском WhoIs та же дата будет выглядеть как «2004.10.26», а в украинском — вообще «20031026», т. е. без разделителей. Наша задача — привести все форматы к одному виду. Для этого воспользуемся функцией strtotime(). Она «понимает» множество различных форматов даты и преобразует их в 32-битовый timestamp. К сожалению, она «не дружит» с форматом ГГ.ММ.ДД, поэтому для доменов .ru сначала немного преобразуем формат, заменив точки на тире:

if($last_tld=="ru"){
$new_data2 = str_replace(".", "-", $new_data2);
}

И последний штрих — приведение всех дат к одному виду:

$ret = date(?Y-m-d?, strtotime($new_data2));

Завершаем функцию get_date():

return $ret;
}

Вот, пожалуй, и все. Вернее, почти все.

Все определенные выше функции будут вызываться в цикле при проверке доменов из списка. После того как состояние очередного домена установлено, записываем его в файл в виде «домен;дата_проверки;состояние». В качестве разделителей я использовал точку с запятой, но это, естественно, не суть важно:

while (list($key, $val) = each($list_domain))
{
...
fputs($fp1, $domain.";".$now.";".$status."
");
...
}

Здесь $list_domain — массив, содержащий список доменов, — предварительно формируется чтением этого самого списка из соответствующего текстового файла, в котором он хранился. Параметр $fp1 функции fputs() — это дескриптор того файла, куда мы хотим записать информацию о результатах проверки.

Напомню, что для отправки оповещения по почте в PHP может быть использована функция mail(). В нашем случае она должна иметь три параметра — адрес получателя, тему письма и тело сообщения. Можно также задать четвертый параметр — обратный адрес:

mail($to, $subject, $body, ?from: me@site.com?);

На этом предлагаю остановиться. Не сомневаюсь: те из вас, кто имел дело с Web-программированием, додумают оставшиеся за кадром части кода самостоятельно.

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

Рис. 7. Услуги для киберсквоттеров от WebNames.ru

Регистратор WebNames. ru предлагает всем желающим воспользоваться несколько необычной услугой «Освобожденные домены .ru» (рис. 7). С ее помощью вы можете просматривать списки доменов в зоне .ru, которые только-только освободились, а следовательно, представляют для вас, начинающего киберсквоттера, некоторый интерес. Эта услуга бесплатная.

Однако куда большую ценность может иметь другой сервис — предоставление списка доменов, освобождающихся завтра. Таким образом, вы можете заранее выбрать себе домен и подготовиться к его захвату. Стоит это 5 долл. за полгода или 9 долл. за год. Правда, никаких дополнительных возможностей (например, отправка списка на e-mail) не предусмотрено. К тому же информация отображается только по завтрашнему дню, поэтому вам придется ежедневно заходить на сайт и просматривать список.

Если вы оплатили услугу «Освобождаемые домены», то для вас становится доступным еще один сервис. Вы можете поручить регистрацию домена, который завтра должен освободиться, работникам WebNames.Ru. Они берут на себя отслеживание того момента, когда домен станет свободным, и тут же регистрируют его на вас. Таким образом, ваши шансы на то, что домен достанется вам, а не какому-нибудь другому киберохотнику, существенно возрастут. Стоит это 3 долл. плюс собственно стоимость регистрации домена.

За 9 долл. в год WebNames.ru покажет домены, ожидающие освобождения

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

На этом, пожалуй, все. Удачи!

К автору можно обращаться по адресу e-mail: nikita@lintec.net.ua.


Окончание. Начало см. в № 10, 11/03.


1Кронтаб — размещенный на сервере небольшой файл, в который можно записать какую-либо задачу, указав период ее работы для автоматического выполнения.