Сообщество / Безопасность

Ночью WordPress отдаёт 502, а дежурный молчит

kate_ekb
Middle
Сообщения: 116
Репутация: 81
Дата регистрации:
12.08.2026
АВТОР ТЕМЫ09 окт. 2026 г., 19:28 (GMT+3)
Если сайт на WordPress три проверки подряд отвечает 502, мониторинг пишет админу в Telegram. Админ спит. Второй тоже есть, но ему ничего не пришло — значит, толку от него пока ноль)

Хочу простую схему для двух человек: основной по расписанию, второй страхует. Мониторинг ждёт от первого «беру», а если за пять минут ответа нет — будит второго. Чем у вас сделано это подтверждение и следующий шаг? Сообщением боту, кнопкой, звонком? Галочка доставки тут явно не считается.
1
S
serg_mail
Junior
Сообщения: 23
Репутация: 12
Дата регистрации:
17.09.2026
09 окт. 2026 г., 19:28 (GMT+3)
kate_ekb, я бы выбрал кнопку «принял», чтобы было записано, кто нажал и когда. Без нажатия через твои пять минут — звонок резервному, а не ещё одно сообщение в Telegram. Если оба спят с выключенным звуком у чата, пересылка не поможет.

После «принял» проверка сайта продолжается. Пока остаётся 502, авария не закрыта. И человеку нужен срок для следующего сообщения: например, через пятнадцать минут написать, что нашёл и нужна ли помощь. Взял задачу и исчез — тоже повод позвать второго.
0
kate_ekb
Middle
Сообщения: 116
Репутация: 81
Дата регистрации:
12.08.2026
12 окт. 2026 г., 09:00 (GMT+3)

serg_mail писал:
Взял задачу и исчез — тоже повод позвать второго.


Вот это важнее самой кнопки. «Принял» без дальнейших слов хуже молчания: второй расслабился, а первый уснул обратно с телефоном на груди. Было)

И звонок проверь заранее с выключенным звуком. Номер телефонии должен сидеть в исключениях «не беспокоить» у обоих, иначе ты красиво дозвонишься до беззвучного кирпича.
2
lexa92
Middle
Сообщения: 163
Репутация: 145
Дата регистрации:
09.08.2026
12 окт. 2026 г., 16:02 (GMT+3)
kate_ekb, в цепочке «бот → кнопка → звонок» не хватает нулевого шага — самого сервера. Ночная 502 у вордпресса почти всегда одно и то же: nginx не достучался до php-fpm. А падает fpm ночью по бытовым причинам: бэкап-плагин сожрал память, тяжёлый wp-cron, либо unattended-upgrades обновил php в четыре утра и после рестарта он не встал.

Поэтому сначала пусть чинит машина, потом люди:


# /etc/systemd/system/php8.2-fpm.service.d/override.conf
[Service]
Restart=always
RestartSec=5


И правило в мониторинге: 502 держится дольше двух минут после авто-рестарта — только тогда будим первого. У меня так половина ночных «аварий» закрывается без людей, а утром я по журналу разбираю причину, а не симптом.

Второе. В сам алерт клади хвост лога, а не голое «сайт лежит»:


journalctl -u php8.2-fpm --since '-15 min' --no-pager | tail -30
dmesg -T | grep -i oom


Разбуженный человек с телефона гадать не будет: прочитает, что умерло, пока идёт до ноута. Кнопка «принял» без лога рядом — это будильник, а не диагностика.
2
kate_ekb
Middle
Сообщения: 116
Репутация: 81
Дата регистрации:
12.08.2026
12 окт. 2026 г., 17:00 (GMT+3)

lexa92 писал:
У меня так половина ночных «аварий» закрывается без людей


И в этом ловушка: через месяц авто-рестарт закрывает уже все аварии, и никто не помнит, что fpm вообще-то падать не должен. Утренний журнал читается ровно до первого дедлайна)

Поэтому к Restart=always положи счётчик: третий рестарт за неделю — не ночная мелочь, а тикет. Иначе получается не мониторинг, а ковёр, под который метёшь.
1
lexa92
Middle
Сообщения: 163
Репутация: 145
Дата регистрации:
09.08.2026
13 окт. 2026 г., 14:01 (GMT+3)

kate_ekb писал:
третий рестарт за неделю — не ночная мелочь, а тикет


Считать этот третий рестарт самому не нужно, systemd его уже считает:

systemctl show php8.2-fpm -p NRestarts --value

Раз в сутки сравниваешь со вчерашним числом: выросло больше чем на два — создаётся тикет, а не алерт. Алерт в три ночи проигнорируешь, а тикет висит в трекере и мозолит глаза. Память человека тут вообще не участвует, что и требовалось.
2
kate_ekb
Middle
Сообщения: 116
Репутация: 81
Дата регистрации:
12.08.2026
13 окт. 2026 г., 16:01 (GMT+3)

lexa92 писал:
Раз в сутки сравниваешь со вчерашним числом


Сравнивает кто? Крон. А крон — такая же ночная мелочь, как и рестарт. У меня этот diff умер при переезде с Uab на Heka: скрипт жил в /root, на новый сервер его никто не перенёс (никто — это я), и сравнение молча перестало существовать. Неделю думала, что тикетов нет, потому что всё хорошо)

Поэтому пусть systemd стучится сам, без моего участия. Лимит рестартов прямо в юните, при превышении юнит уходит в failed и дёргает OnFailure:


[Unit]
StartLimitIntervalSec=3600
StartLimitBurst=3

[Service]
Restart=always
RestartSec=5
OnFailure=fpm-ticket.service


fpm-ticket — десять строк: создать тикет и позвонить первому из твоей цепочки. Три рестарта за час — это уже не «починилось само», это цикл, и Restart=always его до утра не дотянет, systemd просто сдастся. Правильно, что сдаётся: пусть делает это громко.

NRestarts оставь для дашборда, он там красиво растёт. А логика «выросло на два» должна жить в трекере, а не в моей памяти о том, что где-то есть крон.
1
lexa92
Middle
Сообщения: 163
Репутация: 145
Дата регистрации:
09.08.2026
15 окт. 2026 г., 12:00 (GMT+3)
kate_ekb, ладно, переезд — аргумент, крон в /root действительно умирает молча. Твой вариант беру.

Один подводный камень у StartLimit: когда лимит сработает, юнит остаётся в failed, и обычный systemctl start его уже не поднимет. Сначала:


systemctl reset-failed php8.2-fpm


Дежурный ночью этого не вспомнит и полезет перезагружать весь сервер. Так что эту команду клади прямо в текст тикета, который создаёт fpm-ticket.service. Пусть звонок и инструкция приходят вместе, а не инструкция гуглится по сонным глазам.
2
kirill_nsk
Middle
Сообщения: 184
Репутация: 129
Дата регистрации:
26.08.2026
15 окт. 2026 г., 16:00 (GMT+3)
ребят я вообще мимо проходил, у меня вордпресса нет) но lexa92 вбил твою команду на своём сервере, systemctl show wg-quick@wg0 -p NRestarts --value, пишет 0. это вайргард правда ни разу не падал или для него этот счётчик просто не считает?

и куда OnFailure стучать, если трекера никакого нет? в телеграм можно, как у kate_ekb мониторинг пишет?
0
masha_spb
Middle
Сообщения: 129
Репутация: 98
Дата регистрации:
11.08.2026
16 окт. 2026 г., 00:00 (GMT+3)
kirill_nsk, ноль честный, просто меряет не то. wg-quick — oneshot: поднял интерфейс и завершился, рестартоваться там нечему, сам туннель в ядре живёт, без процесса. Живость вайргарда смотри через wg show — свежий handshake значит жив, а не счётчик рестартов.

OnFailure в телеграм — да, oneshot-сервис из пяти строк с curl в bot api, без трекера нормально живёт)
5
P
polina_smena
Junior
Сообщения: 31
Репутация: 19
Дата регистрации:
28.09.2026
16 окт. 2026 г., 01:01 (GMT+3)

masha_spb писал:
oneshot-сервис из пяти строк с curl в bot api


Сижу на смене, у нас так же в телегу падает. Живёт, даже слишком — к четырём утра мечтаешь, чтоб не жило))
0
kate_ekb
Middle
Сообщения: 116
Репутация: 81
Дата регистрации:
12.08.2026
16 окт. 2026 г., 06:01 (GMT+3)

kirill_nsk писал:
как у kate_ekb мониторинг пишет?


Одна 502 за другой — и родился fpm-ticket.service: oneshot с curl в bot api. Токен в EnvironmentFile=/etc/fpm-ticket.env с chmod 600, не в самом юните: он читается всеми, токен открытым текстом — это не мониторинг, а подарок.

По вайргарду masha_spb права, смотри handshake. Я бы завернула в таймер: wg show wg0 latest-handshakes, старше пары минут — это и есть твоя «502».

«Мимо проходил», а уже OnFailure прикручивает)
2
pavel_63
Junior
Сообщения: 83
Репутация: 62
Дата регистрации:
13.08.2026
16 окт. 2026 г., 07:00 (GMT+3)

kate_ekb писал:
не мониторинг, а ковёр, под который метёшь


Ковёр этот и без systemd есть. У клиента агент 1С падал — винда его честно перезапускала, в журнал событий писала, журнал никто не открывал. Узнали, когда бухгалтер позвонила: «а почему база вчера весь день не открывалась». Вот и весь счётчик рестартов.
Так что тикет ваш правильный, только болезнь не линуксовая, а глазная :)
1
C
che32
Junior
Сообщения: 35
Репутация: 34
Дата регистрации:
05.09.2026
17 окт. 2026 г., 05:00 (GMT+3)

pavel_63 писал:
болезнь не линуксовая, а глазная


Павел, точно. У меня дома то же в миниатюре: на Keenetic неделю по ночам рвалась сессия, а я смотрел на аптайм и радовался. Узнал от сына за завтраком — «пап, а чего мультики вчера тупили». Вот и бухгалтер, только без звонка, с кашей)
0
kirill_nsk
Middle
Сообщения: 184
Репутация: 129
Дата регистрации:
26.08.2026
17 окт. 2026 г., 17:02 (GMT+3)
kate_ekb спасибо) вбил wg show wg0 latest-handshakes — выдало число типа 1792245612. это что, секунды от сотворения мира?)) туннель при этом живой, я с него и пишу
1
masha_spb
Middle
Сообщения: 129
Репутация: 98
Дата регистрации:
11.08.2026
18 окт. 2026 г., 00:00 (GMT+3)

kirill_nsk писал:
выдало число типа 1792245612. это что, секунды от сотворения мира?))


Почти угадал: это unix time, секунды с 1 января 1970 — у программистов сотворение мира датируется именно этим днём. В человеческий вид: date -d @1792245612.

А для таймера, про который kate_ekb пишет, переводить и не надо: сравнивай напрямую с $(date +%s). Разница больше трёх минут — handshake протух: туннель вроде поднят, а трафик не идёт.
2
void_3am
Middle
Сообщения: 164
Репутация: 112
Дата регистрации:
14.08.2026
18 окт. 2026 г., 05:01 (GMT+3)
маш, пять утра, человек пришёл с вопросом про сотворение мира — а ты ему спокойно date -d @1792245612. теология по расписанию)
0
kate_ekb
Middle
Сообщения: 116
Репутация: 81
Дата регистрации:
12.08.2026
19 окт. 2026 г., 16:02 (GMT+3)

masha_spb писал:
сравнивай напрямую с $(date +%s)


Так и сделаем, только с одной поправкой, иначе мониторинг превратится в будильник.

Handshake в WireGuard делается под трафик. Туннель поднят, но никто через него не ходит — handshake честно стареет, и проверка «старше трёх минут» начнёт орать каждую ночь ровно о том, что все спят. polina_smena к четырём утра уже мечтает, чтоб телеграм замолчал — не добавляй ей поводов)

Поэтому порядок такой: сначала пинг через туннель (он заодно сам новый handshake инициирует), а упал — тогда смотрим timestamp и шлём тикет.

/usr/local/sbin/wg-watchdog.sh:

#!/bin/bash
PEER_IP=10.13.13.1

if ping -c 2 -W 3 -I wg0 "$PEER_IP" >/dev/null 2>&1; then
exit 0
fi

LAST=$(wg show wg0 latest-handshakes | awk 'NR==1{print $2}')
curl -s -X POST "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \
-d chat_id="${TG_CHAT}" \
--data-urlencode "text=wg0 молчит: пинг до ${PEER_IP} не прошёл, последний handshake $(date -d @"${LAST:-0}" '+%H:%M %d.%m')" >/dev/null


wg-watchdog.service:

[Unit]
Description=WireGuard watchdog

[Service]
Type=oneshot
EnvironmentFile=/etc/wg-watchdog.env
ExecStart=/usr/local/sbin/wg-watchdog.sh


и сам будильник, wg-watchdog.timer:

[Unit]
Description=WireGuard watchdog timer

[Timer]
OnBootSec=2min
OnUnitActiveSec=2min
Unit=wg-watchdog.service

[Install]
WantedBy=timers.target


Дальше: systemctl enable --now wg-watchdog.timer, и systemctl list-timers покажет, когда следующий запуск. Токен с chat id — в /etc/wg-watchdog.env с chmod 600, почему не в самом юните — выше уже писала.

Две оговорки. Если в тикете увидишь 1970 год — это не баг формата, это handshake не было ни разу, туннель мёртв прямо с сотворения мира. И awk 'NR==1' берёт первого пира из вывода: если их на wg0 несколько, нужен цикл, но у kirill_nsk, судя по «с него и пишу», пир один.

Ленивый вариант без пинга: PersistentKeepalive=25 в [Peer] — handshake будет всегда свежим, и можно проверять голый timestamp. Цена — пакет каждые 25 секунд круглосуточно. За NAT это оправдано, просто так — трата на ровном месте.

void_3am, вот и вся теология: сначала date -d, потом systemctl. Человек спросил про сотворение мира — получил и дату, и будильник)
0
masha_spb
Middle
Сообщения: 129
Репутация: 98
Дата регистрации:
11.08.2026
22 окт. 2026 г., 01:00 (GMT+3)

kate_ekb писал:
сначала пинг через туннель (он заодно сам новый handshake инициирует), а упал — тогда смотрим timestamp


Так честнее, согласна. Добавлю две мелочи, на которые сама наступала.

Первая: awk 'NR==1' берёт первого пира из вывода. Если в wg0 у тебя и ноут, и телефон — проверяться будет только один, причём не факт что тот, который как раз молчит. Либо фильтруй по публичному ключу нужного пира, либо крути цикл по всем и алерть по худшему.

Вторая: ping из двух пакетов — штука нервная. Один пакет потерялся ночью на кривом аплинке — и polina_smena получает тикет в четыре утра ни за что, хотя она уже мечтает, чтоб телега замолчала. Я делаю вторую попытку через десять секунд и только после неё шлю.

И да, если LAST пустой и подставится 0 — алерт честно напишет «последний handshake 01.01.1970». Это не баг, это диагноз: пир вообще ни разу не подключался)
2
kate_ekb
Middle
Сообщения: 116
Репутация: 81
Дата регистрации:
12.08.2026
22 окт. 2026 г., 10:01 (GMT+3)

masha_spb писал:
либо крути цикл по всем и алерть по худшему


Цикл — да, «по худшему» — нет: один уснувший телефон сядет на алерт, и про честно упавший ноут узнаешь утром от людей. По каждому молчащему пиру, иначе это не мониторинг, а усреднение.

А NR==1 лечится и без цикла, одной строкой:
wg show wg0 latest-handshakes | awk -v p="$PEER_PUB" '$1==p{print $2}'

Ключ пира — в тот же env-файл рядом с токеном, chmod 600 там уже есть.

По второй попытке согласна: sleep 10 и ещё один пинг дешевле тикета в четыре утра ни за что.
3