Enabling HTTP/2 on nginx over Amazon AMI

Една от любимите oперационни системи на Amazon EC2 е тяхната Amazon AMI. Разбира се няма нищо по-хубаво когато производителя на хардуера ти доставя оптимизиран софтуер за него. УВИ има няколко проблема като най-големия е, че отделни модули са доста стари. Това е защото AMI използва някакъв миш-маш от няколко операционни системи – RHEL6, RHEL7 и дори Fedora. Във моя случай nginx е версия 1.8, но за да активирам HTTP/2 се нуждая поне от версия 1.9.5 (докато актуалната е 1.10.1). Разбира се ако изчакам още някой месец може и да ме огрее… но чакам вече година и ми писна. Затова взех нещата във свои ръце и си прекомпилирах своя версия на nginx.

1. Инсталирайте nginx – ще ви спести поне писане на конфигурационни файлове. Конфигурирайте си го по свой вкус.
2. sudo yum install pcre-devel openssl-devel #библиотечки… ще ви потрябват
3. wget https://www.openssl.org/source/openssl-1.0.2j.tar.gz
4. tar zxvf openssl-1.0.2j.tar.gz -c /lib/opt
5. wget http://nginx.org/download/nginx-1.10.1.tar.gz
6. tar zxvf nginx-1.10.1.tar.gz
7. cd nginx-1.10.1
8. ./configure –prefix=/usr/share/nginx –sbin-path=/usr/sbin/nginx –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –http-client-body-temp-path=/var/lib/nginx/tmp/client_body –http-proxy-temp-path=/var/lib/nginx/tmp/proxy –http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi –http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi –http-scgi-temp-path=/var/lib/nginx/tmp/scgi –pid-path=/var/run/nginx.pid –lock-path=/var/lock/subsys/nginx –user=nginx –group=nginx –with-file-aio –with-ipv6 –with-http_ssl_module –with-http_realip_module –with-http_addition_module –with-http_sub_module –with-http_dav_module –with-http_flv_module –with-http_mp4_module –with-http_gunzip_module –with-http_gzip_static_module –with-http_random_index_module –with-http_secure_link_module –with-http_degradation_module –with-http_stub_status_module –with-mail –with-mail_ssl_module –with-http_v2_module –with-openssl=/opt/lib/openssl-1.0.2j –with-pcre –with-pcre-jit –with-debug –with-cc-opt=’-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector –param=ssp-buffer-size=4 -m64 -mtune=generic’ –with-ld-opt=’ -Wl,-E’
9. make
10. /etc/init.d/nginx stop
11. sudo cp objs/nginx /usr/sbin
12. /etc/init.d/nginx start

ВАЖНО! Ако обновление ви презапише по-стара версия на nginx ще се наложи да изпълните точка 9 поне още веднъж. Защото това е един дърт пач върху оригиналния nginx.

Сега вече ако напишете nginx -V ще видите нейде:
nginx version: nginx/1.10.1

Оттук насетне е лесно. Отивате във конфигурационния файл и издирвате това:
listen 443 ssl;
за да го замените със:
listen 443 ssl http2;

Честито! Вече имате работещ nginx със http/2.

Забележка!!! Оригиналния nginx във AMI е компилиран със малко повечко опции. Липсващите са:
–with-http_xslt_module
–with-http_image_filter_module
–with-http_geoip_module
–with-http_perl_module
–with-google_perftools_module
но аз така или иначе не ги използвам тях.

Спиране на спам ботове и линкове във Аналитикс

От няколко години във интернет се подвизава един метод за създаване на трафик към сайт. Говорим за spambot referrers които посещават сайт X като са дошли от сайт Y. По този начин те правят refferer трафик към сайт Х от името на сайт Y. Само администраторите и потребителите на Analytics подобен софтуер (Google Analytics, KissMetrics, Moz Analytics, Piwik, HubSpot Analytics и други) може да го видят уви. Но това са предимно администратори, web програмисти, дизайнери, оптимизатори или самите собственици на сайтове и има голям интерес от тяхна страна. Все пак всеки би се заинтригувал точно как сайт Y ни е линкнал.

Уви този метод не е етичен и напоследък доста се злоупотребява със него във интернет. Сега ще ви покажа прост метод как този спам трафик може да се блокира под Apache, nginx и Google Analytics.

за Apache .htaccess:

SetEnvIfNoCase Referer semalt.com spambot=yes
SetEnvIfNoCase Referer buttons-for-website.com spambot=yes
SetEnvIfNoCase Referer darodar.com spambot=yes
SetEnvIfNoCase Referer 7makemoneyonline.com spambot=yes
SetEnvIfNoCase Referer ilovevitaly.co spambot=yes
SetEnvIfNoCase Referer myftpupload.com spambot=yes
SetEnvIfNoCase Referer econom.co spambot=yes
SetEnvIfNoCase Referer iskalko.ru spambot=yes
SetEnvIfNoCase Referer ilovevitaly.ru spambot=yes
SetEnvIfNoCase Referer ilovevitaly.com spambot=yes
SetEnvIfNoCase Referer o-o-8-o-o.ru spambot=yes
SetEnvIfNoCase Referer o-o-6-o-o.ru spambot=yes
SetEnvIfNoCase Referer cenoval.ru spambot=yes
SetEnvIfNoCase Referer priceg.com spambot=yes
SetEnvIfNoCase Referer cenokos.ru spambot=yes
SetEnvIfNoCase Referer seoexperimenty.ru spambot=yes
SetEnvIfNoCase Referer gobongo.info spambot=yes
SetEnvIfNoCase Referer vodkoved.ru spambot=yes
SetEnvIfNoCase Referer adcash.com spambot=yes
SetEnvIfNoCase Referer websocial.me spambot=yes
SetEnvIfNoCase Referer cityadspix.com spambot=yes
SetEnvIfNoCase Referer luxup.ru spambot=yes
SetEnvIfNoCase Referer ykecwqlixx.ru spambot=yes
SetEnvIfNoCase Referer superiends.org spambot=yes
SetEnvIfNoCase Referer slftsdybbg.ru spambot=yes
SetEnvIfNoCase Referer edakgfvwql.ru spambot=yes
SetEnvIfNoCase Referer socialseet.ru spambot=yes
SetEnvIfNoCase Referer screentoolkit.com spambot=yes
SetEnvIfNoCase Referer savetubevideo.com spambot=yes
Order allow,deny
Allow from all
Deny from env=spambot

вмъкнете горния код някъде във основния код на .htaccess. Ако имате друг лош referrer просто го допишете във списъка.

за nginx:

if ($http_referer ~* (semalt.com)) {return 403;}
if ($http_referer ~* (buttons-for-website.com)) {return 403;}
if ($http_referer ~* (darodar.com)) {return 403;}
if ($http_referer ~* (7makemoneyonline.com)) {return 403;}
if ($http_referer ~* (ilovevitaly.co)) {return 403;}

добавете във конфирурационния файл на виртуалния сървър само тези редове които ви трябват. Ако има друг сървър просто го добавете като конфигурация.

за Google Analytics:

Admin tab > View Section > Filters Add a filter > Custom > Filter Field трябва да бъде Referral Pattern > и прибавяме сайта като www\.domain\.com
или
Admin tab > Property Section > JS tracking Info и прибавяме сайтовете към referral exclusion list

Разбира се това няма да попречи на “Лошите Момчета” да продължават да се опитват да ви заразят статистиките във аналитикса, но ще ги намали драстично. Винаги трябва да проверявате лог файловете си и аналитикса за подозрителен трафик от сайтове и да реагирате своевременно.

robots.txt wordpress example usage

robots.txt and WordPress

Във предния материал ви показах колко лесно е да се използва WordPress не по предназначение и как да се предпазите от това. Сега ще ви покажа как едно тривиално извикване на robots.txt под WordPress също води до неочаквани резултати, как да му противодействате и още нещо.

Предистория на robots.txt

Имало едно време Интернет и едни сайтове които не били индексирани от никого. На няколко младежа им е хрумнало да направят търсачки които да обхождат денонощно интернет-а и да позволява на потребителите да търсят информация върху вече индексираната информация. Както винаги се случва обаче се оказва как някои страници не трябва да бъдат индексирани и през 1994 се е достигнало до консенсус относно начина по който да става това. Именно тогава се е зародила идеята за robots.txt и неговата спецификация. Тук можете да намерите оригиналната версия на документа. Както виждате няма нищо сложно имаме 2 реда User-agent и Disallow, във първия се описва робота а последващите един или няколко реда описват какво да не индексира. Както може да се забележи стандарта е силно повлиян от Unix и може да се използва # за коментар. През далечната 1996-та година обаче все пак са го вкарали като чернова за IETF и тук е оригинала на документа. Единственната разлика е, че този път е прибавен Allow където се описва изрично какво може да се индексира. Принципа си остава, че всичко което не е забранено е разрешено. В наши дни е широкоразпространено използването на robots.txt във всички сайтове. Едно от първите действия при пускането на сайт е да се настрои правилно robots.txt за да бъде сайта правилно обходен от роботите. Както може и да се очаква почти всички системи за съдържание CMS разполагат със поддръжка на този стандарт. WordPress не прави изключение и е robots.txt съвместим.

robots.txt wordpress example usage

Какъв е проблема със robots.txt под WordPress?

WordPress текущо поддържа 2 режима на индексиране управляващи се от Settings -> Reading Settings:

  • Забрана за индексиране на сайта – използва се когато сайта е във режим на разработка, някакви промени или други причини и съответно не трябва да се индексира. Тогава трябва да се укаже “Search Engine Visibility” и да бъде избрано.
  • Разрешаване на индексиране на сайта – използва се когато сайта е във работен режим и индексирането му е разрешено. Във този случай “Search Engine Visibility” не трябва да е избрано.

Единственното което прави тази настройка е да активира във базата данни една опция “blog_public”. Ако е забранено индексирането се връща следния код за robots.txt:

User-agent: *
Disallow: /

и съответно ако е разрешено кода има следния вид:

User-agent: *
Disallow: /wp-admin/
Disallow: /wp-includes/

Горните редове са всичко което ви трябва и се намират във файла wp-includes/functions.php във функцията do_robots. Проблема е, че да се върнат 3 реда се изпълнява сложна комбинация от код – зарежда се целия WordPress като фреймуорк, установява се връзка към базата, правят се няколко запитвания и на финала се връщат 2-3 реда които винаги са едни и същи.

Как можем да подобрим нещата?

Във момента се занимавам по ускоряване на WordPress със създаването на статични файлове и забелязах през административния панел, че виждам всички заявки към robots.txt. Това ме наведе на мисълта, че този файл не съществува реално, а е виртуален и се генерира от системата. Направих проверка и точно така се указа. Във сървъра такъв файл липсва, но през уеб браузър може да го видя. Разбира се всяка заявка към такива виртуални натоварва сървъра и технически е много по-добре да се направи статичен файл robots.txt във основната папка на WordPress и да се сложат вътре следните редове:

User-agent: *
Disallow: /wp-admin/
Disallow: /wp-includes/

Така малко ще ускорим работата на системата като спестим време. При мен условно от около 100 посещения дневно имам приблизително 100 зареждания на файла. Разбира се при вас стойностите може да се различават във зависимост от натовареността на сайта, социалните сигнали и индексирането му.

Има ли минуси при горния подход?

Има три минуса при този подход. Първия е, че повече няма да можем да управляваме файла от интерфейса. Втория е че повече няма да може да се активира това при обновяване на системата или плъгините. Обикновенно докато обновлението тече се забранява достъпа до сайта и когато свърши се разрешава отново. Технически във този период от няколко секунди може да мине бот и няма да индексира правилно страниците. Лично във моя случай това не е толкова фатално защото WordPress връща грешка и търсещата машина така или иначе узнава, че нещо не е наред и ще дойде пак. Третия минус е при използването на допълнителни плъгини за управлението на robots.txt тогава просто повече няма да може да работят.

Може ли да подобрим нещата още повече?

По време на тазгодишната конференция SMXWest имаше отделна секция Meet the Search Engines където за пореден път се изказа мнението, че е добра практика да се разреши на търсещите машини да индексират JS, CSS и други файлове. Още по въпроса можете да намерите SMX West Liveblog. При горния пример за разрешаване това е частично невъзможно, защото самия ядрото на WordPress се намира във горните две папки. Ето защо ако желаете да разрешите на ботовете да индексират целия сайт кода на robots.txt трябва да изглежда ето така:

User-agent: *
Disallow:

Евентуално може да се прибави и още един ред със sitemap съдържащ пълен URL към файла указващ картата на сайта.

Разбира се целите при които аз правя тази кръпка към WordPress относно robots.txt при мен са различни и може да не са подходящи за Вас. Моята цел е да генерирам статично съдържание от WP със цел качване по CDN без да изгубвам контрол върху съдържанието.

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 и не може да се реши без плъгин.

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 защото това е първото което се случва при опит за достъп до сайта ви. Случвало се е времето на обработка на заявки да е около секунда което не може да се ускори по никакъв начин. При използване на облачни услуги времето на обработка на заявките спада драстично което е и нашата цел.