—Заметки

Оживляем алерты Zabbix — гайд с нуля

Пошаговая инструкция для тех, у кого пока нет вообще ничего из перечисленного: ни бота, ни nginx, ни сертификата. К концу гайда у вас будет свой домен, через который Zabbix (или любой другой сервис) сможет надёжно достучаться до Telegram Bot API, даже если api.telegram.org с вашего сервера мониторинга напрямую недоступен или обрывается по таймауту.

Зачем это нужно

Частая ситуация: Zabbix настроен, медиатип Telegram подключен, тестовое сообщение при настройке ушло — а через какое-то время алерты перестают доходить. Проверяешь бота напрямую — тоже тишина или долгий таймаут. Причина обычно в том, что api.telegram.org с сервера мониторинга просто недоступен стабильно. Итог — часть инцидентов вы узнаёте не из алерта, а от пользователей.

Решение: свой обратный прокси на nginx перед Telegram Bot API. Zabbix стучится в ваш собственный домен, а тот уже прозрачно пробрасывает запрос дальше в Telegram. Никакого стороннего сервиса, только proxy_pass.

Что должно быть готово перед началом

Бот в Telegram и сертификат мы получим по ходу гайда.


Шаг 1. Создать бота в Telegram

  1. Откройте в Telegram диалог с @BotFather
  2. Отправьте /newbot
  3. Задайте имя бота (отображается в чате) и username (должен заканчиваться на bot, например my_zabbix_alert_bot)
  4. BotFather пришлёт токен вида 123456789:ABC-DEF1234ghIkl-zyx57W2v1u123ew11 — сохраните его, он понадобится дальше и больше нигде не показывается повторно (при утере токен можно перевыпустить командой /revoke у того же BotFather)

Шаг 2. Направить домен на сервер

В панели управления DNS вашего домена создайте A-запись:

bot-api.example.com.   A   <IP вашего сервера>

Подождите 5–30 минут на распространение записи. Проверить, что запись уже видна, можно так:

dig +short bot-api.example.com

Команда должна вернуть IP вашего сервера.

Шаг 3. Установить nginx

sudo apt update
sudo apt install -y nginx

Проверить, что сервис запущен:

sudo systemctl status nginx

Если на сервере включён файрвол (ufw), откройте 80 и 443 порты:

sudo ufw allow 'Nginx Full'

Шаг 4. Установить certbot и выпустить сертификат

sudo apt install -y certbot python3-certbot-nginx

Перед выпуском сертификата нужен минимальный конфиг сайта на 80-м порту, чтобы certbot мог подтвердить владение доменом. Создайте файл:

sudo nano /etc/nginx/sites-available/bot-api.example.com

Содержимое (замените домен на свой):

server {
    listen 80;
    server_name bot-api.example.com;
}

Включите конфиг и перезапустите nginx:

sudo ln -s /etc/nginx/sites-available/bot-api.example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Выпустите сертификат:

sudo certbot --nginx -d bot-api.example.com

Certbot спросит e-mail для уведомлений об истечении сертификата и предложит автоматически донастроить редирект на HTTPS — соглашаться необязательно, следующий шаг переопределит конфиг полностью.

Шаг 5. Финальный конфиг nginx

Откройте тот же файл и замените содержимое целиком (домен — свой везде, где встречается):

sudo nano /etc/nginx/sites-available/bot-api.example.com
server {
    listen 80;
    server_name bot-api.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name bot-api.example.com;

    ssl_certificate     /etc/letsencrypt/live/bot-api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/bot-api.example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location /api/bot {
        # /api/bot123:ABC.../sendMessage  ->  /bot123:ABC.../sendMessage
        rewrite ^/api/(bot.*)$ /$1 break;

        proxy_pass https://api.telegram.org;
        proxy_ssl_server_name on;
        proxy_http_version 1.1;
        proxy_set_header Host api.telegram.org;
        proxy_set_header Connection "";

        client_max_body_size 50m;   # sendDocument / sendPhoto — Telegram принимает файлы до 50 МБ
        proxy_read_timeout 60s;
    }

    location / {
        return 404;
    }
}

Что делает каждая директива

Директива Зачем
location /api/bot Ловит только запросы к боту; если позже на этом домене появится сайт, конфликта не будет
rewrite ^/api/(bot.*)$ /$1 break Убирает /api спереди, оставляя путь /bot<token>/<method>, который ждёт Telegram
proxy_set_header Host api.telegram.org Обязательно: без этого nginx отправит апстриму Host: bot-api.example.com, и Telegram не поймёт запрос
proxy_ssl_server_name on Корректный SNI при TLS-соединении к api.telegram.org
client_max_body_size 50m Иначе загрузка файлов через бота будет обрываться на лимите по умолчанию (1 МБ)
тело, метод, заголовки Прокидываются как есть — proxy_pass копирует запрос без изменений, JSON и multipart работают одинаково

Проверьте синтаксис и примените:

sudo nginx -t && sudo systemctl reload nginx

Шаг 6. Проверка: getMe

curl "https://bot-api.example.com/api/bot<TOKEN>/getMe"

где <TOKEN> — токен из Шага 1. Должен вернуться JSON вида {"ok":true,"result":{"id":...,"is_bot":true,...}}.

Шаг 7. Полный тест — отправить себе сообщение

getMe проверяет только GET-запрос. Чтобы убедиться, что через прокси проходит и POST с телом (реальный сценарий отправки алертов), отправьте тестовое сообщение самому себе.

7.1. Узнайте свой Telegram ID

Напишите @userinfobot — он пришлёт ваш числовой Id. Он нужен как chat_id.

7.2. Напишите /start своему боту

Telegram не разрешает боту первым писать пользователю — сначала пользователь должен сам начать диалог. Найдите вашего бота по username из Шага 1 и отправьте ему /start.

7.3. Отправьте тестовое сообщение через ваш домен

curl -X POST "https://bot-api.example.com/api/bot<TOKEN>/sendMessage" \
     -d "chat_id=<ВАШ_ID>" \
     -d "text=Тест: алерты снова доходят"

Если всё настроено верно — curl вернёт "ok": true, а в чате с ботом тут же появится сообщение.

Если пришла ошибка 403: bots can't initiate conversation with a user — пропущен шаг 7.2. Если 404 — проверьте, что конфиг применился (nginx -t + reload) и что токен указан без опечаток.

Шаг 8. Подключить Zabbix

Встроенный медиатип «Telegram» в Zabbix — это webhook-медиатип со скриптом на JavaScript, который ходит в Telegram Bot API.

  1. Administration → Media types → Telegram
  2. Если такого медиатипа ещё нет — импортируйте стандартный шаблон Telegram из списка встроенных медиатипов Zabbix
  3. В параметрах медиатипа найдите поле вроде telegram_api_url / «Telegram API URL» (в актуальных версиях Zabbix оно есть отдельно от токена)
  4. Замените значение с https://api.telegram.org на https://bot-api.example.com/api
  5. Сохраните и нажмите «Test» прямо в форме медиатипа, указав chat_id из Шага 7.1

Если такого поля в параметрах нет (более старая версия Zabbix) — откройте вкладку Script того же медиатипа, найдите в коде строку, где формируется URL запроса (обычно содержит api.telegram.org), и замените её на bot-api.example.com/api, не трогая остальную логику скрипта.

Дальше — обычная настройка Zabbix: привяжите медиатип к пользователю (Users → его учётная запись → Media, Send to = ваш chat_id), включите в Actions уведомление по нужным триггерам. Запустите тестовый триггер или вручную сгенерируйте проблему — алерт должен прийти тем же путём, что вы проверяли в Шаге 7.


Важно понимать перед использованием

VPS и скидки

Всё описанное в гайде разворачивается на обычном VPS. Пользуюсь AdminVPS.ru — при заказе можно применить промокоды:

Промокод Скидка
60START 60% на первый месяц
30START 30% на первый месяц
20X3M +20% + 3% при оплате сразу за 3 месяца
15X6M +15% + 5% при оплате сразу за 6 месяцев
← ко всем записям