Disabling WordPress XML-RPC to be used DDOS attacks

WordPress XML-RPC issues

XML-RPC e протокол ползван от WordPress за комуникация със други компоненти. Освен XML-RPC може да се срещне и като XMLRPC въпреки, че със тирето е правилния начин за изписването му.  XML-RPC протокола позволяващ на WP да си комуникира със други инструменти, сайтове и потребители и се използва за pingback, trackback, достъп от мобилни или десктоп устройства и много други. Повече за WordPress XML-RPC API можете да намерите във WordPress Codex.

Disabling WordPress XML-RPC to be used DDOS attacks
Пример за използването на WordPress XML-RPC върху съществуващ реален сайт от ботове

Какъв е проблема във XML-RPC?

До версия 3.5 протокола е изключен и трябваше да се активира изрично за да се достъпва от външни услуги. От версия 3.5 този програмен интерфейс е активиран и няма възможност за изключването му във базовата версия без използване на плъгин. Както и се очакваше беше въпрос на време да се случи нещо непредвидено и непланирано. На 10 Март Securi обявиха на техния сайт че са забелязали атака на над 162 хиляди WordPress инсталации свързани във botnet мрежа. За съжаление атакуващия е останал във сянка и е използвал метод за усилване на атаката като са използвани напълно реални WordPress сайтове към сайта-жертва. Всичко става със използването на XML-RPC интерфейса като се симулира pingback.ping към жертвата. За да се избегне влиянието на кеширащите плъгини се прибавят случайни параметри към линка, това извиква страницата на жертвата и генерира трафик.

Какво мога да направя за да защитя XML-RPC?

За да се защити сайта участие във подобни атаки може да се използват няколко подхода:

  • изтриване на xmlrpc.php
  • защитаване на xmlrpc.php със парола
  • забрана на pingback метода

Разбира се всички методи си имат плюсове и минуси. Уви изтриването или защитаването на XML-RPC има неблагоприятен ефект – мобилните приложения няма да могат повече да функционират, JetPack също и много други плъгини. Друг недостатък е че при последвщите обновления горния файл пак ще се появи, което прави „защитата“ леко безмислена. Затова възможно най-доброто решение е да се забрани pingback метода. За тази цел може да се използват тези плъгини Remove XMLRPC Pingback PingDisable Pingbacks или дори Disable XML-RPC като крайна мярка.

Важно допълнение относно WordPress и останалите

Ако си мислите, че „тази глупост няма как да ми повлияе“ уви сте във грешка. ВСЕКИ WordPress може да се използва за нуждите на тази атака. По никакъв начин не може да се установи участието на блога освен ако не се преглеждат ръчно файловете access.log на web server-a. От личен опит – малцина правят тази операция защото е трудоемка и времеемка, отделно изисква доста добри познания по web, WordPress и дори и unix. За сметка на това всички пасиви са за сметка на участника – трупа се паразитен трафикк, генерира процесорно време и се правят обръщения към базата. Проблема е дори малко по-голям, защото XML-RPC не може да се кешира и обясненията „ама аз имам кеширащ плъгин“ и този път не минават. Интересно ми е какво ли ще направят този път хостинг доставчиците. Когато беше wp-login атаката голяма част от тях направо сложиха http password на файловете, а някой дори преименуваха файловете при което поддръжката им беше на тръни няколко дена от недоволни клиенти. Този път обаче подобни действия няма да може да се изпълнят защото проблема е вътре във самия WordPress и не може да се реши без плъгин.

Reddit shadowban

Reddit е широко разпространена социална мрежа и продължава да расте. За съжаление апетита идва със яденето и спамърите идват със потребителите. Във reddit имат голям опит със борбата им и са изобретили един много хитър начин за преборването им – shadowban. Когато потребител е маркиран като спамър видимо всичко продължава както по старо му за него. Проблема е, че никой не му вижда коментарите, вотовете и публикуваните истории. Разбира се има модератори във различните раздели които могат да ви разрешат индивидуално достъпа до техните раздели. Обаче става досадно да се молиш на различните модератори за достъп. Много по-добре е да се свържеш директно със администраторите на сайта за да бъде решен проблема със акаунта отколкото да се разрешава достъпа до разделите. Сега ще ви покажа как може да се провери това. Преди известно време установих, че акаунта ми има проблем – публикувах неща, но не можеха да се видят от не логнат потребител. За мое съжаление не разбирах, че съм бил изключен от системата. Писах на модераторите във единия раздел и там ми вдигнаха забраната, но във втория раздел ми казаха че имам проблем със самия акаунт и имам shadowban забрана. Сега ще ви покажа когато акаунта има такава забрана какво се вижда:

curl -I http://www.reddit.com/user/peternikolow
HTTP/1.1 404 Not Found
Content-Type: text/html; charset=UTF-8
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
Server: ‘; DROP TABLE servertypes; –
Date: Thu, 23 Jan 2014 12:50:56 GMT
Connection: keep-alive
Vary: accept-encoding

Когато потребителя няма shadowban то горното изглежда ето така:

curl -I http://www.reddit.com/user/peternikolow
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Last-Modified: Thu, 23 Jan 2014 20:57:00 GMT
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
Server: ‘; DROP TABLE servertypes; –
Cache-Control: private, must-revalidate, max-age=0
Date: Thu, 23 Jan 2014 23:47:36 GMT
Connection: keep-alive
Vary: accept-encoding

След като се установи със сигурност, че акаунта е маркиран пътя към пречистването минава оттук /r/reddit.com и съобщение към администраторите със молба да бъдете отписан от позорния списък. Разбира се не е задължително молбата да ви бъде удовлетворена, всичко зависи от прегрешенията ви. Затова е хубаво да се спазва редикета / reddiquette и правилата на сайта. Специално за оплаквания и мрънкания има отделна секция /r/ShadowBan/ където и блокирани потребители могат да пишат без проблем. Секцията /r/reportthespammers е специално запазена за оплаквания от спамъри.В тази секция модераторите гласуват и потребителя получава shadowban.

Google AdSense ban

Google AdSense ban check

Google AdSense ban
Google AdSense ban

Сега ще ви покажа как можем да проверим дали даден домейн не е изключен от системата за реклами Google AdSense без да кандидатстваме. Разбирате, че това е доста полезно ако планирате да закупите домейн и искате да проверите историята му, без да го закупувате. Досега видях как IsBanned.com и няколко други сайта могат да покажат тази информация и ми е било чудно как я достъпват. Разбира се те няма как да се знаят всички домейни на света както и всички блокирани домейни, това могат само Google да го знаят. Значи все пак има някакъв начин.

Въоръжен с малко доза самоувереност намерих едно извикване към кода за рекламите което на стандартен сайт изглежда така:

http://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-3352121096311701&output=html&h=60&slotname=1063815394&adk=3923217926&w=468&lmt=1387959683&flash=11.9.900&url=http%3A%2F%2Fpeter.nikolow.me%2F&dt=1387966883521&bpp=20&shv=r20131210&cbv=r20131209&saldr=sa&correlator=1387966883579&frm=20&ga_vid=1021565215.1387966884&ga_sid=1387966884&ga_hid=805616736&ga_fc=0&u_tz=120&u_his=3&u_java=0&u_h=800&u_w=1280&u_ah=716&u_aw=1280&u_cd=24&u_nplug=13&u_nmime=91&dff=verdana&dfs=11&adx=537&ady=26&biw=1261&bih=151&oid=3&rs=0&vis=0&fu=0&ifi=1&pfi=0&dtd=148&xpc=PSJmvuzmr8&p=http%3A//peter.nikolow.me

Ако го извикваме през curl горния линк връща някакви реклами, както и 200 OK което е сигурен признак че домейна не е блокиран дори и да няма пуснати реклами в момента на него. Нека сега да проверим един „лош“ домейн който е бил наказан. В горния линк редактираме всички обръщения към http://peter.nikolow.me и ги заместваме със http://www.budo-zone.com/. Линка придобива следния вид:

http://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-3352121096311701&output=html&h=60&slotname=1063815394&adk=3923217926&w=468&lmt=1387959683&flash=11.9.900&url=http%3A%2F%2Fwww.budo-zone.com%2F&dt=1387966883521&bpp=20&shv=r20131210&cbv=r20131209&saldr=sa&correlator=1387966883579&frm=20&ga_vid=1021565215.1387966884&ga_sid=1387966884&ga_hid=805616736&ga_fc=0&u_tz=120&u_his=3&u_java=0&u_h=800&u_w=1280&u_ah=716&u_aw=1280&u_cd=24&u_nplug=13&u_nmime=91&dff=verdana&dfs=11&adx=537&ady=26&biw=1261&bih=151&oid=3&rs=0&vis=0&fu=0&ifi=1&pfi=0&dtd=148&xpc=PSJmvuzmr8&p=http%3A//www.budo-zone.com

При извикването му вече получаваме код за грешка: 403 Forbidden. Това е сигурен признак, че домейна е бил блокиран от системата на Google AdSense.

Кода връщан от сървърите може да се провери по няколко начина. Един от най-лесните е да се използва FireBug при Firefox. Ако използвате Safari/Chrome може да се провери при използването на Develop при единия и Developer Tools при другия. Феновете на Opera могат да използват DragonFly за целта. Ако все още ползвате Internet Explorer можете да използвате ieHTTPHeaders или Fiddler. Разбира се това е лесния начин.

Далеч по-елегантния подход е да се използва curl или wget за целта. Няма нужда от научни степени за използването им. При curl трябва да се напише curl -I „URL“ (кавичките не са задължителни, но при адреси използващи поне един амперсанд & се стартират фонови процеси във *nix което чупи линка и прави задачата неизползваема). За wget може да се използва следния начин за извикване wget -v „URL“ (и тук важи предходния коментар относно амерсандите &).

Разбира се това е само начин за една проста проверка дали домейна е със забрана за показване. Съществуват 2 основни причини за забрана на рекламите – invalid activity и policy reasons. На този адрес Top reasons for account closure можете да проверите какви са разликите между тях. За съжаление и двата типа причини за забрана са заради груби нарушения и не може да се определи кое е по-малкото зло. Ако домейна ви е със забрана за обслужване на реклами поради „policy reasons“ можете да поискате преразглеждане на забраната ако попълните заявка на следния адрес: Policy Violation Appeal. Изключително важно е преди попълването на молбата да проверите дали сайта ви отговаря на всички критерии за програмата намиращи се AdSense program policies както и на официалния им блог Inside AdSense. Важно е защото молбата ви ще бъде преразгледана само един единствен път! Всички останали молби ще бъдат директно отказвани със мълчалив отказ. Ако причината за забрана ви е „invalid activity“ то можете да се опитате да си вдигнете забраната като попълните тази молба: Invalid Activity appeal.

Facebook embedded post за новаци

Преди минути Facebook обновиха, че вече постовете може да се вкарват в сайтове. По-долу можете да видите пример в реално действие. И ето и как става:

<script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/en_US/all.js#xfbml=1"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script>
<fb:post href="https://www.facebook.com/MobilioDevelopment/posts/575096699200112">


Защо това е важно? Ако преди трябваше да се покаже отделен и специфичен пост във сайт се използваше добре познатата техника – изрязан screenshot което водеше до неудобство при изтрити, променени или обновени постове. В момента ще можете директно да вмъкнете поста във сайта като всеки клик върху поста ще доведе до съответното действие – харесване, коментар или споделяне.

За момента услугата е активна на определени акаунти, но горния код е универсален и позволява използването му и за такива където услугата все още не е налична. Единственния проблем е, че линка във <fb:post&gr; трябва да се дописва на ръка което е известно неудобство.

SSH for novices – brief introduction

Allways use SSH when connecting to remote hosts!
Allways use SSH when connecting to remote hosts!
За повечето от интернет потребителите SSH е нещо като наследник на FTP или е известно като „онова с което се качват файловете“ което е ГРУБА грешка. Всъщност корените на SSH датират от telnet и неговата липса на всякаква липса на шифриране. ФАКТ е, че първоначално на сигурността не се е гледало сериозно в telnet/rsh/rlogin паролите и изобщо цялата информация тече некриптирана. Млад изследовател се е заел да отстрани тази несправедливост и се е появил SSH като напълно нов протокол създаден да замести изцяло telnet и събратята му. SSH не само замества telnet, но и се превръща в доминиращ протокол в интернет за отдалечен достъп. Към настоящия момент SSH се разработва активно от SSH, но съществуват няколко версии с отворен код като най-известните са OpenSSH и dropbear.

Това което е уникалното е, че благодарение на SSH са се появили цял набор от услуги които работят върху него:
– файловия трансфер за който споменах в началото
– тунелизиране или пренасочване на портове
– проксифирицане на връзката със SOCKS прокси
– изграждане на архиви или огледала със rsync
– пренасочване на X
– и други

Сега ще ви покажа как го използвам в ежедневните си нужди в 2 варианта. Имам една машина намираща се зад по-сложна огнена стена и не мога да я достъпвам отдалечено лесно през GUI. Машината има отворен един единствен порт 22 (SSH) към нея от огнената стена. На същата машина има стартиран vnc server на порт 5900 както и разни други интересни услуги до които обаче нямам никакъв достъп. Затова отварям терминал и пиша заветната команда:
ssh -L 5999:127.0.0.1:5900 -N username@my.server.com
натискам enter, пиша си паролата и ако всичко е наред ще бъде стартирано пренасочването, отварям нов терминал и си влизам във vnc-то по следния начин:
open vnc://localhost:5999
Сега какво правят горните две команди – първата стартира пренасочване от локален порт 5999 към отдалечена машина 127.0.0.1 на порт 5900 (което е порта на vnc). Със -N инструктирам SSH да не стартира команден промпт и само да пренасочи портовете. Когато VNC сесията ми приключва излизам от VNC клиента, връщам се в конзоната където SSH е стартиран и натискам ctrl-c. Разбира се SSH се оплаква по следния начин:
^CKilled by signal 2.
което е сигнал че връзката към отдалечената машина е затворена. Порт 5999 вече не е отворен и пренасочването вече не работи.

Вторият сценарий е малко по-странен. Болшинството от потребителите не знаят, но под SSH е възможно да се стартира локален socks сървър който ще пренасочва всичко към отдалечения сървър. Разбира се не се изисква нещо супер сложно. Напълно достатъчно е да се напишa следната комбинация в терминала:
ssh -D 1080 -N username@my.server.com
натискам enter с което socks проксито е стартирано. След което си стартирам приложението което отчаяно се нуждае от прокси (в дадения случай Firefox), набивам в опциите че имам socks прокси с параметри 127.0.0.1:1080 и готово. Ако се налага порта да бъде отворен мрежово т.е. да бъде наличен и за други машини в локалната мрежа, а не само за локалната машина нейде в параметрите е необходимо да се напише просто едно -g след ssh. Разбира се това е една МНОГО малка част от възможностите на SSH. Например е възможно да се отвори пренасочи порт от сървъра към локалната машина (подобно на -L, но се пише -R), възможно е използването на отдалечена файлова система (SSHFS) и много други.

Може би по-голяма част от вас ще използват SSH под Windows с използването на putty. В момента уви не разполагам със Windows, но скоро ще публикувам как по-горните примери може да се използват и под Windows.

Cheating Blitz comment voting

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

Направи ми впечатление как в Blitz.bg понякога оценките за коментарите се развиват за секунди и чуждото мнение се потапя с много на брой отрицателни гласове, а „правилното“ се подкрепя.

Седнах и намерих една статия с която да експериментирам за целта – http://www.blitz.bg/article/33765 и един безобиден коментар от нея

Ето и избрания коментар за целта.
Ето и избрания коментар за целта.

След което отваряме конзола и пишем заветния ред:
curl --data "vote=1&tag=show&id=143698" "http://www.blitz.bg/libs/commentsajax.php?vote=1&tag=show&id=143698"

Ето и резултата от няколко извиквания на реда:

curl --data "vote=1&tag=show&id=143698" "http://www.blitz.bg/libs/commentsajax.php?vote=1&tag=show&id=143698"
<span class=\"ocenka\">Оценка<br />-0 <span>+16</span></span>
curl --data "vote=1&tag=show&id=143698" "http://www.blitz.bg/libs/commentsajax.php?vote=1&tag=show&id=143698"
<span class=\"ocenka\">Оценка<br />-0 <span>+17</span></span>
curl --data "vote=1&tag=show&id=143698" "http://www.blitz.bg/libs/commentsajax.php?vote=1&tag=show&id=143698"
<span class=\"ocenka\">Оценка<br />-0 <span>+18</span></span>
curl --data "vote=1&tag=show&id=143698" "http://www.blitz.bg/libs/commentsajax.php?vote=1&tag=show&id=143698"
<span class=\"ocenka\">Оценка<br />-0 <span>+19</span></span>
curl --data "vote=1&tag=show&id=143698" "http://www.blitz.bg/libs/commentsajax.php?vote=1&tag=show&id=143698"
<span class=\"ocenka\">Оценка<br />-0 <span>+20</span></span>

Изглежда оценките може да се манипулират. Забелязах същото в сайтовете на 24Часа, Дир, Дневник, Капитал и още много други. Но няма да ви помагам със скриптове за тях.
Затова когато видите мнения с много плюсове или минуси имайте едно на ум, че е възможно да са манипулирани.

Autopost to Svejo.net

Ако преди седмица ви показах как можете да публикувате във Facebook то днес ще ви покажа как можете да го направите във Svejo.net

Svejo add url to site
Svejo add url to site


<?PHP
/*******************************
* Svejo Status Updater
* Peter Nikolow
* http://peter.nikolow.me
* March 29, 2013
*******************************/

$login_email = 'type-here-your-mail';
$login_pass = 'type-here-your-password';
$url_4submit = 'type-here-your-url';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://svejo.net/user/login');
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIEJAR, "my_cookies.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE, "my_cookies.txt");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; Linux 2.6.22) NetFront/3.4 Kindle/2.0 (screen 600x800)");
$loginpage = curl_exec($ch);

curl_setopt($ch, CURLOPT_POST, 1);
preg_match("/input name=\"authenticity_token\" type=\"hidden\" value=\"(.*?)\"/", $loginpage, $form_authtoken);
curl_setopt($ch, CURLOPT_POSTFIELDS,'authenticity_token='.urlencode($form_authtoken[1]).'&user%5Bemail_or_username%5D='.urlencode($login_email).'&user%5Burl_referer%5D=http%3A%2F%2Fsvejo.net%2F&user%5Bremember_me%5D=0&user%5Bpassword%5D='.urlencode($login_pass).'&commut=%D0%92%D0%BB%D0%B5%D0%B7');
$loginpage = curl_exec($ch);

sleep(10);
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_URL, 'http://svejo.net/publish/');
$page = curl_exec($ch);

sleep(10);
curl_setopt($ch, CURLOPT_POST, 1);
preg_match("/input name=\"authenticity_token\" type=\"hidden\" value=\"(.*?)\"/", $page, $form_authtoken);
$formvars = array();
$formvars['authenticity_token'] = $form_authtoken[1];
$formvars['story[url]'] = $url_4submit;
$formvars['commit'] = "Добави";
curl_setopt($ch, CURLOPT_POSTFIELDS, $formvars);
curl_setopt($ch, CURLOPT_URL, 'http://svejo.net/publish/submit');
$page2 = curl_exec($ch);

curl_close($ch);
?>

А сега малко разшифровка на горния код.

  1. Трябва да се заредим страницата http://svejo.net/user/login
  2. От горната страница вземаме изключително важния параметър authenticity_token който го подаваме заедно с името/паролата към същата страница
  3. Зареждаме тази страница http://svejo.net/publish/ с цел вземането на authenticity_token
  4. Извършваме POST към http://svejo.net/publish/submit като подаваме token-a и URL-a които трябва да бъдат предадени

За всеки случай сме прибавили едно временно заспиване от 10 секунди между заявките за да не може системата да ни разпознае като ботове, каквито всъщност сме. Средно дневно в системата се прибавят около 2100 линка (информацията е от 30 Март 2013 година) което прави 87,5 линка на час. Или приблизително 2,5 линка на минута. Ако горния код се модифицира също като предходния би могъл денонощно да публикува всякакви линкове независимо от времето,но не е това целта на упражнението. Задачата е приключена и вече имаме скрипт за автоматично публикуване във Svejo.net

Facebook status update

Autopost to Facebook

От известно време ме тормози идеята за автоматично обновяване (autopost) на статуса във Facebook и други социални мрежи без други системи и приложения. Затова взех задачата присърце, седнах и преправих един прост скрипт който да свърши черната работа.

Facebook status update
Facebook status update


<?PHP
/*******************************
* Facebook Status Updater version 0.1
* Peter Nikolow
* http://peter.nikolow.me
* March 22, 2013
*******************************/

function random_string( )
{
$character_set_array = array( );
$character_set_array[ ] = array( 'count' => 7, 'characters' => 'abcdefghijklmnopqrstuvwxyz' );
$character_set_array[ ] = array( 'count' => 1, 'characters' => '0123456789' );
$temp_array = array( );
foreach ( $character_set_array as $character_set )
{
for ( $i = 0; $i < $character_set[ 'count' ]; $i++ ) { $temp_array[ ] = $character_set[ 'characters' ][ rand( 0, strlen( $character_set[ 'characters' ] ) - 1 ) ]; } } shuffle( $temp_array ); return implode( '', $temp_array ); } $status = random_string(10); $login_email = 'type-here-your-mail'; $login_pass = 'type-here-your-pass'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://m.facebook.com/login.php?refsrc=http%3A%2F%2Fwww.facebook.com%2Flogin.php&refid=9'); curl_setopt($ch, CURLOPT_POSTFIELDS,'email='.urlencode($login_email).'&pass='.urlencode($login_pass).'&login=Login'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_COOKIEJAR, "my_cookies.txt"); curl_setopt($ch, CURLOPT_COOKIEFILE, "my_cookies.txt"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; Linux 2.6.22) NetFront/3.4 Kindle/2.0 (screen 600x800)"); $loginpage = curl_exec($ch); curl_setopt($ch, CURLOPT_POST, 0); curl_setopt($ch, CURLOPT_URL, 'http://m.facebook.com/home.php'); $page = curl_exec($ch); curl_setopt($ch, CURLOPT_POST, 1); preg_match("/input type=\"hidden\" name=\"fb_dtsg\" value=\"(.*?)\"/", $page, $form_id); preg_match("/form method=\"post\" id=\"composer_form\" action=\"(.*?)\"/", $page, $form_num); curl_setopt($ch, CURLOPT_POSTFIELDS, 'fb_dtsg=' . $form_id[1] . '&privacy=&charset_test=%E2%82%AC%2C%C2%B4%2C%E2%82%AC%2C%C2%B4%2C%E6%B0%B4%2C%D0%94%2C%D0%84&target=&status=' . urlencode($status) . '&update=' . urlencode("Share")); curl_setopt($ch, CURLOPT_URL, 'http://m.facebook.com' . $form_num[1]); $page2 = curl_exec($ch); curl_close($ch); ?>

Скрипта е сравнително глупав, но ще ви го обясня накратко:

  1. Генерира се случаен стринг от 10 символа който ще бъде нашия нов статус. Това е много важно защото FB блокира показването на еднакви статуси и ми коства няколко часа докато го проумея. С това се избягва блокирането на статуса и е винаги уникален.
  2. До първия curl_exec се изпълнява логване във Facebook с указаното потребителско име и парола. За да се избегне тежкия desktop ajax се представяме като много прост мобилен браузър. Така избягваме получаването на iOS/Android ajax версия която също е по-тежка за обработка. Кукитата се запазват във външен файл с цел последващо използване.
  3. Със втория curl_exec се насочваме към основната страница на Facebook където ще обновим статуса на потребителя.
  4. До третия curl_exec се изпълнява основната функция на обновяването. Проблема е че FB използва динамични форми и първо трябва да обработим втория резултат като вземем изключително важните параметри fb_dtsg - уникално id за формата и composer_form - сочещ към url-a който трябва да бъде извикан с третата заявка. Така композираме третата заявка която обновява статуса с няколко фиксирани параметъра.
  5. Последния ред затваряме curl и задачата е приключена. Можем да изтрием файла с cookies защото вече не е необходим.

С което задачата е изпълнена с няколко особенности:

  • Скрипта има проблеми с кирилицата! За момента не може да се публикува статус без да се счупи кирилицата. Тук проблема е по-тежък защото самия FB кара браузъра със специфично HTML поле "charset_test" да върне какво поддържа като езици и подозирам че нещо и оттам обърква кирилицата.
  • Скрипта се представя за мобилен агент което води до показването на "from mobile" под поста.
  • За момента показването на линкове не е много ефективно.
  • Не могат да се качват снимки във timeline.
  • Липсва проверка дали предходните операции са се случили безпроблемно. Например ако потребителското име/паролата са грешни не се спира изпълнението както и не се проверява дали обновяването на статуса минава безпроблемно.
  • Не може да се контролира видимоста на поста (Public/Friends/Me). Мисля че се използва настройката на потребителя.
  • Публикуването е фиксирано от името на човека и не може да се публикува от страница. Засега...

Надявам се със следващите версии да подобря част от недъзите на съществуващия скрипт. Системата е много гъвкава и на тази база може сравнително лесно да се направи подобен скрипт за публикуване във Twitter, Linkedin, Sharetronix, StatusNet и други подобни системи. Малко по-сложно ще е публикуването в Google+, но принципа е същия както в горните системи и не виждам причина да не бъде налична и тази социална мрежа.
С горния скрипт може да се направят много неща - примерно може да се настрои сървър да отчита параметрите си в интернет, може да се настрои автоматично постване през час от база данни, може да се извърши постване от името на потребител за вирална реклама и т.н. Общо взето възможностите са неограничени с тънкия момент, че не е много по правилата на Facebook. Ако трябва да бъде по правилата трябва да бъде приложение което потребителя с OAuth да упълномощи да извърши няколко дейности включително промяна на статуса.
За моя радост използвам скрипта САМО за лично ползване и то не и под основния ми акаунт. Ако имате въпроси ще бъда радостен да ви отговоря.

Amazon Route53 – Cloud DNS for novices

В серия постове ще ви запозная с облачните услуги на Amazon. Сега ще ви покажа как се пуска облачен DNS в облака на Amazon. След фиаското с GoDaddy е по-добре да се прехвърлят сървърите в облачен DNS.

Сега ще ви демонстрирам как работи този домейн – nikolow.me на обикновен език. Amazon Route 53 поддържа облачни DNS сървъри и има много лесен административен панел – https://console.aws.amazon.com/route53/home Натискаме бутона „Created Hosted Zone“, в панела написваме името на зоната и коментар. За да управлявам зоната не се изпосва нищо преди домейна. Т.е. ако домейна е nikolow.me изписвам за име на зоната само nikolow.me! В никакъв случай не се изписва www. или mail. или нещо друго. Коментара е незадължителен, но препоръчителен – ако се управляват много повече от един домейн винаги става някаква невероятна каша. Затова в коментарите свободен текст можете да си опишете текст който после да го търсите по-лесно в полето за търсене. Когато зоната е готова от дясно ще се появят 4 DNS сървъра – това са сървърите на домейна. Тези сървъри трябва да се настроят в  регистратора самия домейн. Ако регистрираме нов домейн – в момента на регистрация, ако ще обновяваме съществуващ домейн е ще е по-добре първо да изпълним останалите стъпки преди да обновим тази информация в регистратора. В първия случай в момента на регистрирането домейна ще бъде стартиран без записи до момента на създаването им, което не е голям проблем за нови домейни. Проблем възниква във втория случай защото времето на обновяване на DNS сървърите отема от няколко часа до няколко дена – удобното е че дотогава едновременно и стария и новия DNS сървър и няма да се случи срив в обслужването на домейна.

След регистрацията на зоната е момента да прибавим самите записи – ако нямате опит е крайно препоръчително да прочетете малко относно материята! DNS не е за новаци, нито момента за научаване върху домейни които са реална употреба. Добре ще е да започнете с някакъв тестов домейн в този случай. Най-простото – всеки домейн има A записи с които се описват името на записа и се насочва към IP адрес. Пример всички са свикнали да пишат www.домейн затова правим запис www.домейн който да сочи към IP адреса на самия сървър. Отделно е хубаво да се направи запис за самия домейн (без префикс!) който пак да сочи към сървъра. Следващия запис който е задължителен е SOA – Amazon го попълва автоматично и ако не знаете какво правите е по-хубаво да не го пипате!  В дадения случай сочи към един от 4-те сървъра които обслужват домейна. Друг тип записи е MX – mail exchange това е запис описващ към останалите в публичното пространство кои са сървърите обслужващи входящата поща за съответния домейн. Заедно с MX вървят и SPF – те описват кои са разрешените MX записи за изпращане на мейл. Предназначението му е да се намали SPAM-а като изрично се опишат мейл сървърите. Ако сте параноици ще е хубаво да се направи и DKIM за съответния домейн което ще  удостовери и изпращача. Записите тип NS са други – те описват самите DNS сървъри на домейна. За наше щастие Amazon ги попълва автоматично и не е необходимо да се настройват допълнително.

Сега ще ви обясня и избрах Amazon:

  • сървърите са географски ограничени и се намират на различни IP адреси
  • обработката на заявките е бърза, за разлика от домейните на регистраторите които често са претоварени
  • (това е специфично за България) обработката на международни заявки е много бърза
  • позволява гъвкава настройка специфична за облачни услуги – Amazon позволява да се настроят допълнителни флагове и в зависимост от геолокацията да се връщат различни отговори
  • поддръжка на API – това позволява цялата дейност да се автоматизира

Сега и минусите:

  • услугата не е безплатна! В момента цените са $0.5 месечно за обработка на зона за първите 25 зони и $0.1 месечно за зоните над 25. Освен обработката на зони доставчика ни брои и броя на заявките закръглени на милион. Цената е $0.75 за милион заявки, ако заявките минат милиард за месец, цената става $0.375 което предполагам, че не би трябвало да е голям проблем в този случай.
  • има ограничение от 100 зони на акаунт, в момента не знам дали има ограничение на записите на зона

В крайна сметка борбата за ускоряване на достъпа до уеб включва и ускоряване на DNS защото това е първото което се случва при опит за достъп до сайта ви. Случвало се е времето на обработка на заявки да е около секунда което не може да се ускори по никакъв начин. При използване на облачни услуги времето на обработка на заявките спада драстично което е и нашата цел.

DisableProcessWindowsGhosting

Днес ще ви запозная с една интересна функция – DisableProcessWindowsGhosting ще ви покажа и как да се използва от Delphi. Ето какво е предназначението и… нека имаме процес който по някаква причина не може да си обработва опашката от съобщения. Той не може да я обработва, но има Windows Manager-a по някаква причина съумява да извършва следните дейности – resize, close, minimize на прозорците. Което разбира се води до още по-голям хаос когато процеса най-сетне съумее да обработи заявката.

За да се спре това поведение е разработена следната функция: DisableProcessWindowsGhosting в user32.dll която до спирането на процеса изключва тази особенност. Функцията е от най-любимите ми – нито има параметри, нито има резултат. Дефиницията на C e:

VOID WINAPI DisableProcessWindowsGhosting(void);

За първи път се среща в Windows XP (NT 5.1 SP1) и Windows 2003 (NT 5.2). Ето и примерен код на Delphi:

procedure DisableProcessWindowsGhosting;
var
DisableProcessWindowsGhostingProc: procedure;
begin
DisableProcessWindowsGhostingProc := GetProcAddress(
GetModuleHandle('user32.dll'), 'DisableProcessWindowsGhosting');
if Assigned(DisableProcessWindowsGhostingProc) then
DisableProcessWindowsGhostingProc;
end;

Понякога при използването на Delphi 7 под WinXP+ се получава странен проблем – ако се изведе модален прозорец със ShowModal и от този прозорец се изведе 2-ри модален (примерно с MessageDlg) се случва втория модален да се подпъхне между основния прозорец и първия модален. Което води до аматьорско поведение на приложението – решението е потребителя да натисне alt-tab и още веднъж alt-tab така, че приложението да изчертае наново всички прозорци коректно ИЛИ да се използва горния код.

Проблема възниква с приложения до Delphi7 и не може да се възпроизведе на Win2000 или WinNT поради бъг във VCL. Нямам представа дали вече проблема е отстранен в актуалните версии, носят се слухове че в Delphi 2006 проблема вече бил фиксиран на ниво VCL, но там проблемите са на малко идеологическо ниво. Според мен едва Delphi 2007 успява да стабилизира средата до някакво по-прилично ниво. Delphi 2005 и 2006 ще ги запомня с грандиозните сривания на самата среда и затова много разработчици останаха на старите и стабилни версии (5,6 и 7).