javascript

Мониторинг WordPress-сайтов на бесплатном Cloudflare Workers: 8 подводных камней

  • среда, 21 октября 2026 г. в 00:00:05
https://habr.com/ru/articles/1096804/

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

Это самый неприятный вид поломки: сайт вроде бы работает, а что-то важное тихо сломано. С WordPress-сайтами таких историй три самые частые. Сайт лег ночью, и первым это замечает заказчик. Сертификат должен был продлиться сам, но автопродление сломалось, и браузер начинает пугать посетителей красной страницей. Ядро давно не обновлялось, потому что в админку никто не заходит.

Для этих трех случаев напрашивается простой Telegram-бот: добавляешь сайт, а бот следит за доступностью, сроком сертификата и версией WordPress и пишет, когда что-то не так. Готовые сервисы это умеют, но хочется без сервера и без подписки.

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

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

1. Воркер не видит сертификат сайта

Чтобы узнать, когда кончается сертификат, обычно открывают соединение с сайтом и читают дату прямо из него. В Workers так не получится: запрос к сайту отдает статус, заголовки и страницу, а сертификата в ответе нет.

Выход есть: логи Certificate Transparency. Каждый публичный сертификат при выпуске записывается в открытые журналы, иначе Chrome и Safari ему не доверяют. Сервис crt.sh по имени сайта отдает все его сертификаты списком. Оттуда и можно взять дату.

2. В логах десятки сертификатов, и нужен самый свежий

Сертификаты Let's Encrypt живут недолго и перевыпускаются заранее, так что в журналах их скапливается много. Часть уже истекла, часть еще действует.

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

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

3. Две мелочи в этих логах, на которых легко ошибиться

Звездочка покрывает ровно один уровень. Сертификат на *.site.ru подходит для www.site.ru, но не для самого site.ru и не для a.b.site.ru. Если сравнивать имена просто по окончанию строки, в выборку попадут сертификаты соседних поддоменов с чужой датой.

Время без часового пояса. crt.sh отдает даты без пометки, что это UTC. JavaScript такую строку читает как местное время. В Workers местное время и есть UTC, но код, который работает правильно только там, легко сломать при проверке на своем компьютере. Надежнее дописывать пояс явно.

4. Страницу сайта нельзя скачивать целиком

Второе ограничение тарифа: на один запуск дают всего 10 миллисекунд процессорного времени. Ожидание ответа от сайта в них не считается, а вот разбор ответа считается.

Главная страница сайта на конструкторе часто весит сотни килобайт. Скачивать и разбирать ее ради одной проверки значит быстро упереться в лимит.

Для проверки «жив ли сайт» хватает статуса ответа. Как только пришли заголовки, соединение можно закрыть, не скачивая страницу.

Версию WordPress удобнее всего искать в RSS-ленте /feed/: она маленькая, и WordPress по умолчанию указывает там свою версию в самом начале. Если ленты нет, можно смотреть страницу, но читать только начало, например первые 64 килобайта. Нужная метка стоит в шапке страницы, дальше читать незачем.

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

5. 50 запросов на запуск: это меньше, чем кажется

Третье ограничение: за один запуск воркер может сделать не больше 50 запросов наружу. Причем переадресация считается отдельным запросом, а у сайтов их хватает: с http на https, с www на без www.

Проверить за раз сто сайтов не выйдет. Решение: каждый запуск берет пачку, например 20 сайтов, которые дольше всех не проверялись. Сертификат и версию WordPress достаточно смотреть раз в сутки, их можно вынести в отдельную маленькую пачку. При запуске раз в пять минут запусков в сутках 288, так что на суточные проверки хватает с большим запасом.

И еще одна мелочь. Запуск по расписанию может начаться чуть позже назначенного времени. Если брать сайты строго «не проверялись пять минут», часть из них будет пропускать целый круг. Минута запаса это решает.

6. Одна неудачная проверка еще не падение

Если писать о падении после первой же неудачи, бот будет будить ночью из-за любой сетевой случайности и быстро отправится в мут. Разумнее считать сайт упавшим после двух неудач подряд.

Отдельно надо отличать «упал сайт» от «кончился свой лимит». Если воркер сам израсходовал 50 запросов, следующий запрос завершится ошибкой, и без проверки бот сообщит, что сайт лежит. Такие ошибки не стоит считать, сайт просто проверится в следующий раз.

7. Двадцать сайтов упали, а сообщение одно

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

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

8. Telegram не любит ждать

Когда пользователь добавляет сайт, его хочется сразу проверить: статус, сертификат, версия. Это несколько секунд. А Telegram ждет от бота быстрого ответа и при неудаче присылает то же сообщение повторно.

В Workers можно ответить сразу и продолжить работу после ответа. Значит, правильный порядок такой: сначала ответить Telegram, потом проверять сайт.

И не забыть про защиту. Адрес, на который Telegram присылает сообщения, открыт всему интернету. Telegram умеет подписывать каждое сообщение секретной строкой, и бот должен принимать только подписанные.

Короткий чек-лист

Если делать свой мониторинг на бесплатном тарифе, вот что проверить:

  • страница сайта не скачивается целиком, только статус;

  • сертификат берется самый свежий из действующих, звездочка покрывает один уровень, время в UTC;

  • сайты проверяются пачками, с запасом по расписанию;

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

  • уведомления склеиваются в одно сообщение, о каждой проблеме бот пишет не чаще, чем нужно;

  • Telegram получает ответ сразу, а входящие сообщения проверяются по секрету.

Чего такой бот не поймает

Сайт за жесткой защитой от ботов может отвечать воркеру отказом и выглядеть упавшим. Если версия WordPress спрятана, про обновления бот не скажет. Если crt.sh не отвечает, проверку сертификата придется отложить.

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

Код

Черновой код с этими решениями лежит на GitHub под MIT: github.com/sen4o/wp-watchdog. В бою он не обкатан, так что это скорее иллюстрация к статье, чем готовый продукт. Замечания и пулл-реквесты приветствуются.