30 апр. 2011 г.

Атака на FreeSWITCH закончилась

Уфф... DOS атака на мой сервер закончилась. Вот какой траффик порождала атака сегодня:


Это уже после того, как я активировал iptables, соответственно мы видим, что исходящий трафик практически нулевой - мой телефонный сервер не отвечал на эту атаку, потому что до него запросы не доходили.

Суммарно на мой сервер было отправлено 2475 Mb данных, атака длилась 30 часов. Сервер выдержал.

Смотря внимательно на данные, которые отправляли хакеры на мой сервер, мы видим, что они в SIP пакетах использовали прокси (поле VIA), в результате телефонный сервер слал ответ не на сервер хакеров, а на другой сервер, таким образом мой собственный сервер выступал в роли хакерского сайта, долбящего пакетами совершенно невинный сервер! Пока я не заметил атаку, мой сервер успел отправить на невинную жертву 1 Гб данных! Сервер этот, кстати, был сайтом по нелегальному заработку - они предлагали отдать им деньги и зарабатывать 1% в день.

Причина атаки

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

Выводы

В результате всего этого я сделал для себя неожиданные открытия. Посмотрев другие логи на сервере в папке /var/log(sshd.log, apache2/error_log, messages, warn), я заметил, что мой сайт уже неоднократно пытались хакать! Были попытки подобрать пароль и имя пользователя при логине по SSH, были попытки произвести взлом через дыру в веб-сервере ("client sent HTTP/1.1 request without hostname (see RFC2616 section 14.23)") - дыры не было, но я узнал про такой способ атаки.
В результате тепеь у меня на сервере работает fail2ban с несколькими "тюрьмами", которые ловят и сажают в тюрьму злоумышленников, атакующих SSH, SIP, HTTP. Это уже лучше, чем быть совсем беззащитным перед атаками.

UPD

Атака, как оказалось, закончилась только на пару часов и продолжилась с новой силой в мае. Сегодня, 11-го мая, атака, по-видимому, окончательно прекратилась:


Суммарно хакеры нагнали мне траффика 21,1 Гб (!).

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

Сегодня моя защита на основе fail2ban поймала еще одну попытку взломать телефонный сервер - эта попытка была сразу же пресечена. Думаю подействует и очередной brute force атаки не будет, поскольку мой сервер перестал существовать в сети для атакующих и нет смысла делать атаку :)

29 апр. 2011 г.

Ну вот и первый хак

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



За 10 часов атаки суммарно получается 670Мб входящего траффика и 1 Гб исходящего.

Смотрим логи:
/usr/local/freeswitch/log # ll freeswitch.log.*
-rw----r-- 1 root root 815562 Apr 2 03:07 freeswitch.log.2011-04-02-03-07-07.1
-rw----r-- 1 root root 190 Apr 2 03:07 freeswitch.log.2011-04-02-03-07-07.2
-rw----r-- 1 root root 10485904 Apr 29 15:13 freeswitch.log.2011-04-29-15-13-18.1
-rw----r-- 1 root root 10485899 Apr 29 15:44 freeswitch.log.2011-04-29-15-44-41.1
-rw----r-- 1 root root 10485899 Apr 29 16:12 freeswitch.log.2011-04-29-16-12-55.1
-rw----r-- 1 root root 10485899 Apr 29 16:33 freeswitch.log.2011-04-29-16-33-08.1
-rw----r-- 1 root root 10485899 Apr 29 16:53 freeswitch.log.2011-04-29-16-53-30.1
-rw----r-- 1 root root 10485899 Apr 29 17:16 freeswitch.log.2011-04-29-17-16-00.1
-rw----r-- 1 root root 10485835 Apr 29 17:39 freeswitch.log.2011-04-29-17-39-05.1
-rw----r-- 1 root root 10485835 Apr 29 18:00 freeswitch.log.2011-04-29-18-00-45.1
-rw----r-- 1 root root 10485899 Apr 29 18:21 freeswitch.log.2011-04-29-18-21-57.1
-rw----r-- 1 root root 10485899 Apr 29 18:42 freeswitch.log.2011-04-29-18-42-27.1
-rw----r-- 1 root root 10485899 Apr 29 19:03 freeswitch.log.2011-04-29-19-03-20.1
-rw----r-- 1 root root 10485899 Apr 29 19:23 freeswitch.log.2011-04-29-19-23-07.1
-rw----r-- 1 root root 10485899 Apr 29 19:41 freeswitch.log.2011-04-29-19-41-55.1
-rw----r-- 1 root root 10485899 Apr 29 20:01 freeswitch.log.2011-04-29-20-01-10.1
-rw----r-- 1 root root 10485899 Apr 29 20:19 freeswitch.log.2011-04-29-20-19-27.1
-rw----r-- 1 root root 10485899 Apr 29 20:37 freeswitch.log.2011-04-29-20-37-57.1
-rw----r-- 1 root root 10485899 Apr 29 20:57 freeswitch.log.2011-04-29-20-57-18.1
-rw----r-- 1 root root 10485899 Apr 29 21:21 freeswitch.log.2011-04-29-21-21-10.1
-rw----r-- 1 root root 10485899 Apr 29 21:39 freeswitch.log.2011-04-29-21-39-17.1
-rw----r-- 1 root root 6906631 Apr 29 22:58 freeswitch.log.2011-04-29-22-58-56.1
-rw----r-- 1 root root 71 Apr 29 22:58 freeswitch.log.2011-04-29-22-58-56.2
/usr/local/freeswitch/log #


Вот как началась атака:
2011-04-29 06:41:38.351078 [WARNING] sofia_reg.c:1246 SIP auth challenge (REGISTER) on sofia profile 'internal' for [1610258589@myserverip] from ip 66.199.232.98
2011-04-29 06:46:09.164120 [WARNING] sofia_reg.c:1246 SIP auth challenge (REGISTER) on sofia profile 'internal' for [3623987258@myserverip] from ip 66.199.232.98
2011-04-29 14:39:42.604125 [WARNING] sofia_reg.c:1246 SIP auth challenge (REGISTER) on sofia profile 'internal' for [2917801763@myserverip] from ip 91.220.62.140
2011-04-29 14:39:42.616121 [WARNING] sofia_reg.c:1246 SIP auth challenge (REGISTER) on sofia profile 'internal' for [1882527475@myserverip] from ip 91.220.62.140
2011-04-29 14:39:43.139079 [WARNING] sofia_reg.c:1246 SIP auth challenge (REGISTER) on sofia profile 'internal' for [china@myserverip] from ip 91.220.62.140
2011-04-29 14:39:43.159069 [WARNING] sofia_reg.c:1246 SIP auth challenge (REGISTER) on sofia profile 'internal' for [koreea@myserverip] from ip 91.220.62.140
2011-04-29 14:39:43.170114 [WARNING] sofia_reg.c:1246 SIP auth challenge (REGISTER) on sofia profile 'internal' for [korea@myserverip] from ip 91.220.62.140
2011-04-29 14:39:43.179114 [WARNING] sofia_reg.c:1246 SIP auth challenge (REGISTER) on sofia profile 'internal' for [japan@myserverip] from ip 91.220.62.140
2011-04-29 14:39:43.343117 [WARNING] sofia_reg.c:1246 SIP auth challenge (REGISTER) on sofia profile 'internal' for [taiwan@myserverip] from ip 91.220.62.140
2011-04-29 14:39:43.350107 [WARNING] sofia_reg.c:1246 SIP auth challenge (REGISTER) on sofia profile 'internal' for [000000@myserverip] from ip 91.220.62.140
2011-04-29 14:39:43.363118 [WARNING] sofia_reg.c:1246 SIP auth challenge (REGISTER) on sofia profile 'internal' for [00000000@myserverip] from ip 91.220.62.140


и дальше пошел перебор всех возможных цифровых и буквенных номеров SIP телефонов. На момент обнаружения мной этой атаки хакеры перебрали 1,3 млн. комбинаций!

Пришлось в срочном порядке добавлять правило в iptables:

iptables -I INPUT -s 91.220.62.140 -j DROP

Это спасло.

Похоже, это DOS атака. Детали атаки такие (здесь IP адрес моего сервера замнен на myserverip на всякий случай):

FreeSWITCH получает пакет:
REGISTER sip:myserverip SIP/2.0
Via: SIP/2.0/UDP 91.220.62.36:5137;branch=z9hG4bK-1132046786;rport
Content-Length: 0
From: "5988"

Accept: application/sdp
User-Agent: friendly-scanner
To: "5988"

Contact: sip:123@1.1.1.1
CSeq: 1 REGISTER
Call-ID: 1008625951
Max-Forwards: 70


FreeSWITCH ругается:


2011-04-30 01:28:44.511139 [WARNING] sofia_reg.c:1246 SIP auth challenge (REGISTER) on sofia profile 'internal' for [5988@myserverip] from ip 91.220.62.140



FreeSWITCH отправляет ответ на хакерский сайт:
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 91.220.62.36:5137;branch=z9hG4bK-1132046786;rport=5137;received=91.220.62.140
From: "5988"
To: "5988" ;tag=g0BXD9pv6mjBe
Call-ID: 1008625951
CSeq: 1 REGISTER
User-Agent: FreeSWITCH-mod_sofia/1.0.head-git-e52e44e 2011-03-31 13-44-24 -0500
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, UPDATE, INFO, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, precondition, path, replaces
WWW-Authenticate: Digest realm="myserverip", nonce="a9360d6c-72a7-11e0-b622-f7c8239c6915", algorithm=MD5, qop="auth"
Content-Length: 0

Нашел замечательную утилиту fail2ban, чтобы в будущем рубить хакеров на корню.

Настройка простая:
zypper in fail2ban

Создаем файл /etc/fail2ban/filter.d/freeswitch.conf
# Fail2Ban configuration file
[Definition]
failregex = .* SIP auth challenge .* from ip
<HOST>
ignoreregex =

Дописываем вот этот кусок в конец файла /etc/fail2ban/jail.conf
[freeswitch]
enabled = true
port = 5060,5061,5080,5081
protocol = udp
filter = freeswitch
logpath = /usr/local/freeswitch/log/freeswitch.log
action = iptables-allports[name=freeswitch, protocol=all]
maxretry = 3
findtime = 600
bantime = 18000

Запускаем
/etc/init.d/fail2ban restart

И наслаждаемся результатом:
Сюда будут добавляться заблокированные хосты:

/usr/local/freeswitch/conf # iptables -L fail2ban-freeswitch
Chain fail2ban-freeswitch (1 references)
target prot opt source destination
DROP all -- 91.220.62.140 anywhere
RETURN all -- anywhere anywhere

/usr/local/freeswitch/conf # cat /var/log/fail2ban.log
2011-04-30 02:27:19,580 fail2ban.filter : DEBUG Found 91.220.62.140
2011-04-30 02:27:19,581 fail2ban.filter : DEBUG Found 91.220.62.140
2011-04-30 02:27:19,581 fail2ban.filter.datedetector: DEBUG Sorting the template list
2011-04-30 02:27:19,583 fail2ban.actions.action: DEBUG iptables -N fail2ban-freeswitch
iptables -A fail2ban-freeswitch -j RETURN
iptables -I INPUT -p all -j fail2ban-freeswitch returned successfully
2011-04-30 02:27:19,583 fail2ban.actions.action: DEBUG iptables -n -L INPUT | grep -q fail2ban-freeswitch
2011-04-30 02:27:19,587 fail2ban.actions.action: DEBUG iptables -n -L INPUT | grep -q fail2ban-freeswitch returned successfully
2011-04-30 02:27:19,587 fail2ban.actions.action: DEBUG iptables -I fail2ban-freeswitch 1 -s 91.220.62.140 -j DROP
2011-04-30 02:27:19,590 fail2ban.actions.action: DEBUG iptables -I fail2ban-freeswitch 1 -s 91.220.62.140 -j DROP returned successfully
2011-04-30 02:27:19,590 fail2ban.actions: WARNING [freeswitch] 91.220.62.140 already banned

Ура :)

26 апр. 2011 г.

Оффлайн бизнес должен идти в онлайн

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

В онлайне сейчас находится достаточно большое число ваших потенциальных клиентов, в связи с широким распространением интернета в домах и на телефонах обывателей. В то же время, рынок традиционных средств продвижения продукта или услуги сокращается. Скажите, вы когда-либо слышали по телевизору, читали в газете или видели на дорожном биллборде информацию о том, что ИП Пупкин на Сормовском шоссе предлагает скидку 50% на шиномонтаж? Или то, что в подвальчике на Нартова открылось новое ателье по пошиву брюк на заказ? Названия выдуманные, но смысл нет: малому бизнесу зачастую не под силу организовать для себя хорошую оффлайновую рекламную кампанию, и в результате эти начинающие предприниматели ограничиваются простым: распечатыванием объявления "скидка 50%" на листе А4 на входной двери в предприятие, и публикацией рекламного сообщения в бесплатной рекламной газетенке, которую все равно никто не читает.

Трудности перехода
Трудности, на мой взгляд, связвны с тем, что начинающие предприниматели, по натуре своей, находятся далеко от высоких интерент-технологий. Они этому нигде не учились, среди их знакомых - таких же ИПшников - никто так не делает, поэтому они ориентируются исключительно на "проходимость" места - т.е. на пассивную роль: авось кто-нибудь, проходя мимо нашего ателье/шиномонтажа, разглядит на нашей двери листочек с объявлением что "мы открылись" и с графиком работы. Авось ему как раз нужно будет пошить брюки или совершенно случайно потенциальный клиент будет на машине на зимней резине в апреле, и заедет к нам на шиномонтаж.

Пути решения проблемы
Выход состоит в более тесной интеграции бизнеса с онлайн технологиями. Этот процесс начинается. Хотя Россия, как всегда, сильно отстает от запада, я уверен, будет и на нашей улице праздник, придет время, когда все будут онлайн.
Я наблюдаю начало этой тенденции на примере фотографов, которые не только, как по старинке, публикуют свои фотографии на специализированных фото-сайтах, но и начинают пользоваться livejournal и вконтакте для раскрутки своего бренда, для привлечения на свою страничку в интернете потенциальных клиентов через распространение ссылки на ресурс довольными клиентами. Такие потуги кажутся наивными, поскольку технология "блог" известна уже лет эдак 10, а фотографы еще не научились писать правильные тексты в своем блоге, для повышения своего рейтинга в поисковых системах, не говоря уж о подключении к блоку аналитики.

Технологии, за которыми будущее
Что нас ожидает в ближайшие пару лет? Более тесная "социализация", т.е. проникновение социальных сетей во все сферы жизни. Уход от персональных компьютеров, замена их сотовыми телефонами и коммуникаторами со встроенным веб-браузером. Компьютеры, и ноутбуки - это прошлый век, и нужны они только программистам. Все компьютеры опять превратятся в гигантских супермощных монстров и перетекут в дата-центры (облака), оставив у обывателей только "остатки" компьютерных технологий вроде телевизора с браузером, медиаплеера с торрент-клиентом, читалки книг с mp3-плеером, фотоаппарата со встроенной функцией редактирования фото/видео.

Этим постом я открываю цикл статей на эту тему.

22 апр. 2011 г.

Репликация базы данных PostgreSQL на основе SymmetricDS



+

В этой статье я расскажу, как настроить репликацию баз данных PostgreSQL. Что такое репликация? По сути, это механизм автоматической синхронизации содержимого баз данных, работающих на разных серверах.


В результате репликации эти базы данных содержат абсолютно идентичные данные. Это нужно например для того, чтобы обеспечить отказоустойчивость системы (в случае падения первого сервера баз данных в работу вступает второй), или чтобы осуществить балансировку нагрузки - разных клиентов могут обслуживать разные сервера.
Для экспериментов будем использовать дистрибутив линукса CentOS 5.3, хотя это не принципиально. Версия PostgreSQL, используемая в статье: 8.4.7. Она еще не умеет сама реплицироваться - это фича 9-й версии постгреса.

Для репликации нужно как минимум два сервера баз данных, поэтому готовим два одинаковых сервера с базой данных PostgreSQL на каждом. У первого будет IP адрес 10.0.2.20, у второго - 10.0.2.21, у обоих гейтвей 10.0.2.2.
Можно обойтись виртуальной машиной, например VirtualBox, создать в ней два виртуальных сервера и запустить их на своем собственном компе.

В приведенных командах первым символом будет стоять знак # либо $, эти знаки означают, что команда запускается из-под root или из-под обычного пользователя, соответственно.
Итак, какие действия нужно предпринять:

17 апр. 2011 г.

Распознавание голоса с помощью технологий Google

В этом посте я расскажу, как сделать автоматическое распознавание голоса с помощью технологий Google.

Что нам потребуется:
- Perl с модулями JSON::XS и LWP,
- утилита flac для работы со звуком,
- исходный звуковой файл test.wav, 11025Hz mono 16 bit, для распознавания.

Вкратце, что надо делать: отправить flac в POST-запросе на адрес гугловского сервиса, а как результат получить JSON с распознанным текстом.

Код очень прост. Вот такой:

#!/usr/bin/perl

use Encode;
use JSON::XS;
use LWP::UserAgent;
$ua = LWP::UserAgent->new;

$file = "test.wav";
$res = `flac $file >/dev/null 2>&1`;
$flacfile = "$file";
$flacfile =~ s/\.wav$/\.flac/;
$filesize = -s "$flacfile";

open(flac, "$flacfile");
binmode flac;
read(flac, $data, $filesize);
close(flac);
unlink("$flacfile");

$url = 'http://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=ru-RU';
my $req = HTTP::Request->new(POST=>$url);
$req->content_type('audio/x-flac; rate=11025');
$req->content_length($filesize);
$req->content($data);

$res = $ua->request($req);
$jstxt = JSON::XS->new->utf8->decode($res->content);
$decoded = $jstxt->{hypotheses}[0]->{utterance};

use utf8;
print "\nDecoded:\n$decoded\n";
no utf8;

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

На вход гугловскому сервису подается звук в формате FLAC, который мы предварительно кодируем из исходного файла WAV. Потребуется указать частоту дискретизации звука: в моем случае это 11кГц (11025).

Из проблем этого гугловского сервиса, которые стоит отметить:
-он, похоже, еще очень сырой. Постоянно, вместо ответа с распознанным текстом приходят HTTP 500 Server Error.

Я провел простой эксперимент: запустил распознавание звука 20 раз подряд.
Для длинных звуковых файлов, размер которых больше 300.000 байт (11кГц моно 16 бит звук), сервис Гугла ни разу (!) не вернул результат, все 20 раз было Internal Server Error 500.
При ограничении отправляемого звукового файла размером 200.000 байт (до кодирования его во flac) расклад стал такой: 6 из 20 запусков - Internal Error 500; при повторном запуске этого теста результаты лучше: 2 из 20 запусков вернули Error 500.
Видимо, этот сервис заточен исключительно на поиск, когда юзер говорит поисковую фразу из 2-3 слов (типа, "пицца Нижний Новгород") и получает результаты поиска.