W3TC and Yoast SEO sitemap problem

Проблем със генерирането на sitemap под WordPress

WordPress е много хубава CMS система и работи out-of-box. Но за да работи още по-добре се слагат разни плъгини, уиджети, модули и други благинки. Сега ще ви покажа как 2 перфектни и много известни плъгини се сбиват и правят живота ви със една идея по-труден дори при генерирането на един прост sitemap. От дълго време ползвам W3TC както и Yoast SEO. И двата плъгина са лидери във своята област и всекидневно се използват от милиони блогове. За съжаление има малка уловка при тях която се отразява на XML sitemap-a.

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

correct-yoast-seo-sitemapдруг път така:

broken-yoast-seo-sitemapПоради липса на време (и интерес) не обърнах внимание защо и как се получава това. Отделно роботите продължават да ми посещават сайта без проблем, все едно няма такъв. Обаче има проблем: веднъж когато работи сайта ми връща text/xml, друг път text/html. В момента работя разни неща за проверка на sitemap и не ми трябва просто някакъв сайтмап, ами ми трябва перфектният сайтмап.

След 30 минутно разследване се оказа че когато съм логнат винаги виждам нещата перфектно независимо колко пъти ги презаредя. Когато изляза и почистя W3TC кеша ги виждам перфектно веднъж като xml, след което при презареждане ми се сервират html файлове. Което е сигурен признак, че проблема е нейде във W3TC.

Малко предистория
W3TC има няколко режима на работа от които на мен най-ми харесва Disk: Enhanced. Във този режим готовите страници се записват на диска и със няколко ловки пренасочвания със .htaccess или nginx правила се достъпват. Това е един от най-добрите режими защото веднъж след като WordPress и PHP генерират страницата повече не се изпълнява нито ред код от тях. На практика дори WP/PHP не знаят че страницата е достъпвана след като я генерират. Единственния вариант да се достъпи е когато човек се логне или когато кеша се инвалидира. Другия вариант е Disk: Basic, но там веднъж след като се генерира страницата и се записва после достъпа пак минава през WP/PHP. Там плюса е че не се извикват всички плъгини и модули за целта и направо се връща готовата страница. На практика плъгина Hyper Cache Extended на Marto Lazarov прави същата функционалност. Другия подобен плъгин е WP Super Cache на Donncha O Caoimh, но той е малко по-комплексен и съчетава едновременно Basic и Еnhanced.

Сега Disk: Enhanced след като генерира файла го обслужва със серия правила за web server-a. Но проблема е че по дефиниция той приема че всички кеширани файлове са text/html докато във моя случай трябва да връща text/xml. За да бъде хаоса пълен тези файлове не съществуват физически на диска а WordPress ги виртуализира през едно негово API. Yoast SEO ги генерира от базата данни и ги връща на клиента. Затова и W3TC ги прихваща.

Разбира се W3TC има правила при които може да се изключи файл от кеширането. При мен просто във Performance -> Page Cache -> Never cache the following pages:

sitemap_index\.xml
main-sitemap\.xsl
post-sitemap\.xml
page-sitemap\.xml
category-sitemap\.xml
author-sitemap\.xml
post_tag-sitemap\.xml

При вас разбира се може файловете малко да се различават. Затова отворете sitemap_index.xml и добавете във горния списък необходимите файлове.

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

Извода е, че колкото по-голям и комплексен е даден плъгин толкова по-голяма е вероятността да повреди нещо друго. И винаги проверявайте какво се случва след плъгините. Понякога малки и незначителни на вид неща имат катастрофални последици.

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