VPN·HUB·CRACK
Мониторинг ресурсов: увидеть, что нода умирает, до падения · VPN HUB CRACK
Мониторинг ресурсов: увидеть, что нода умирает, до падения
Мониторинг ресурсов: увидеть, что нода умирает, до падения
В Мониторинге и бэкапе мы подняли Uptime Kuma. Она отвечает ровно на один вопрос: отвечает порт или нет. Вопрос важный, но у него есть неприятное свойство: ответ меняется на «нет» одновременно с тем, как клиенты начинают писать в поддержку.
Практически всё, что убивает ноду, убивает её медленно: диск заполняется неделю, память утекает сутки, сосед по гипервизору душит процессор каждый вечер. Всё это время монитор аптайма светится зелёным, потому что порт-то отвечает.
Дальше разберём второй слой: мониторинг ресурсов. Он не заменяет Kuma, он показывает то, чего она не видит в принципе.
📖 Незнакомые слова? Все термины простыми словами есть в Словаре терминов.
Что тихо убивает VPN-ноду
| Что происходит | Что видит клиент | Метрика, которая предупредила бы заранее |
|---|---|---|
| Диск забит логами Xray | Соединения рвутся, no space left on device |
Диск, %: растёт линейно днями |
| Утечка памяти на панели (Postgres + Remnawave) | Панель отваливается, OOM-killer убивает контейнер | RAM + swap: ползут часами |
| Оверселл гипервизора (сосед ест CPU) | «Вечером тормозит, ночью норм» | Load average и steal: пик по расписанию |
| Выжран месячный трафик | Хостер режет канал до 10 Мбит или выставляет счёт | Пропускная способность: видно на второй неделе |
| Кончились inode | Место вроде есть, а записать нельзя | Диск / inode |
| Перегрев дедика | Троттлинг, скорость просела вдвое | Температура |
Общее у всех строк: сигнал был за дни до аварии. Его просто некому было увидеть.
Kuma и Beszel решают разные задачи
Соблазн заменить одно другим, и это ошибка. Они смотрят с разных сторон:
- Uptime Kuma смотрит снаружи. Проверяет то, что видит клиент: маршрут, доступность, сертификат. Только она заметит, что нода жива и здорова, но ТСПУ прикрыл ваш 443, сервер при этом идеален по всем метрикам.
- Beszel смотрит изнутри. Показывает запас прочности: сколько осталось диска, памяти, процессора. Только он заметит, что до аварии три дня.
Нужны оба. Kuma отвечает «работает ли сервис», Beszel отвечает «надолго ли его хватит».
Почему Beszel
Инструментов много, но большинство несоразмерны задаче «десять нод и панель»:
| Чем неудобно для нашей задачи | |
|---|---|
| Zabbix | Мощно и правильно, но это отдельный проект на неделю и сервер под него |
| Prometheus + node_exporter + Grafana | Три компонента, свои конфиги и язык запросов ради шести графиков |
| Netdata | Отлично на одном хосте; сведение десяти хостов и история тянут за собой облако |
Beszel это минимум, который закрывает 90% потребности: хаб (веб-панель) + лёгкий агент на каждом сервере. История, статистика по Docker-контейнерам отдельно от хоста, алерты в Telegram из коробки. Лицензия MIT, актуальная версия на момент написания: v0.18.7. Образы крошечные: хаб ~12 МБ, агент ~9 МБ в сжатом виде.
Отдельно ценно для нас: он разделяет хост и контейнеры. Видно не просто «память кончается», а «память ест конкретно remnawave-db».
Шаг 1. Хаб
⚠️ Хаб не ставим на ноду. Если он живёт на сервере, за которым следит, то в момент реальной аварии некому будет прислать алерт. Панельный сервер или отдельный дешёвый VPS.
mkdir -p /opt/beszel && cd /opt/beszel
cat > docker-compose.yml <<'EOF'
services:
beszel:
image: henrygd/beszel
container_name: beszel
restart: unless-stopped
ports:
- "127.0.0.1:8090:8090" # только локально, наружу — через nginx
volumes:
- ./beszel_data:/beszel_data
EOF
docker compose up -d
Официальный пример публикует порт как
8090:8090, то есть на все интерфейсы. Мы намеренно вешаем на127.0.0.1: панель мониторинга со списком всех ваших серверов не должна торчать в интернет голой.
Наружу пускаем через reverse-proxy с сертификатом:
server {
listen 443 ssl;
server_name beszel.example.com;
location / {
proxy_pass http://127.0.0.1:8090;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # обязательно: агенты ходят по WebSocket
proxy_set_header Connection "upgrade";
}
}
certbot --nginx -d beszel.example.com, и открываем адрес, создаём аккаунт администратора. Первый, кто откроет свежий хаб, станет админом: не оставляйте его без сертификата и без пароля даже на час.
Шаг 2. Агенты и ни одного открытого порта
Здесь ключевой для нас момент. У агента два режима связи, и выбор между ними это вопрос не удобства, а маскировки ноды.
- SSH-режим (входящий). Хаб сам стучится к агенту на порт
45876. Значит, на ноде появляется ещё один открытый порт с опознаваемым баннером, на сервере, который мы старательно прячем за self-steal и CDN. - WebSocket-режим (исходящий). Агент сам открывает соединение к хабу (
HUB_URL+TOKEN). Входящий порт не нужен вообще.
Для VPN-нод берём только второй.
В хабе Settings → Tokens даёт универсальный токен, либо Add System открывает диалог с готовой командой с вашим ключом и токеном. Проще всего скопировать её оттуда; ниже: что означают флаги.
Бинарём (рекомендую для нод):
curl -sL https://get.beszel.dev -o /tmp/install-agent.sh && chmod +x /tmp/install-agent.sh
/tmp/install-agent.sh -t <ТОКЕН> -url https://beszel.example.com --auto-update
Флаги: -t = токен, -url = адрес хаба, -k = публичный ключ (если ставите не по универсальному токену), -p = порт прослушивания, --auto-update = ежедневное автообновление, --china-mirrors = зеркала, если GitHub недоступен с сервера.
Скрипт заведёт пользователя beszel и сервис beszel-agent.service.
Закрываем порт прослушивания. Даже в WebSocket-режиме агент поднимает локальный слушатель на 45876. На скрытой ноде он не нужен снаружи:
ufw deny 45876/tcp # либо nft/iptables — как у вас заведено
ss -tlnp | grep 45876 # убедиться, что не виден с внешнего интерфейса
Заодно ограничим агенту аппетит, правим /etc/systemd/system/beszel-agent.service, секция [Service]:
MemoryMax=128M
systemctl daemon-reload && systemctl restart beszel-agent.
Docker-вариант (удобно там, где уже всё в контейнерах, например, на панельном сервере):
services:
beszel-agent:
image: henrygd/beszel-agent
container_name: beszel-agent
restart: unless-stopped
network_mode: host
volumes:
- ./beszel_agent_data:/var/lib/beszel-agent
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
LISTEN: 127.0.0.1:45876
HUB_URL: "https://beszel.example.com"
TOKEN: "<токен>"
KEY: "<публичный ключ>"
🔒 Проброс
docker.sockэто то, что даёт статистику по каждому контейнеру отдельно. Он смонтирован:ro, но помните: доступ к сокету Docker равносилен root на хосте. Ставьте агента только из официального образа и только на свои серверы.
Шаг 3. Пороги именно под VPN-ноду
Дефолтные пороги «CPU > 80%» бесполезны: у ноды под нагрузкой это норма. Что реально стоит сторожить:
| Метрика | Порог | Почему так | Что делать по алерту |
|---|---|---|---|
| Диск | > 75% | Главный убийца нод. Растёт медленно: 75% даёт дни на реакцию | Разобрать логи (ниже) |
| Память | > 90%, держится 10 мин | На панели: Postgres; на ноде: утечка Xray | Проверить, кто ест; перезапуск как временная мера |
| Load average | > числа ядер, держится 15 мин | Отличает реальную нагрузку от всплеска | Если растёт без роста клиентов: подозрение на оверселл |
| Пропускная способность | ~70% месячного лимита хостера | Чтобы узнать до счёта, а не после | См. Лимиты трафика |
| Температура | > 75 °C | Только для дедиков | Троттлинг → жалобы на скорость |
| Статус | агент пропал | Дублирует Kuma другим маршрутом | Проверить, жив ли сервер вообще |
Ставьте пороги с выдержкой по времени, иначе телефон будет звенеть на каждом всплеске, вы отключите уведомления, и весь мониторинг превратится в тыкву.
Диск: почти всегда это логи
Девять из десяти переполнений на ноде это логи Xray внутри Docker. Найти:
du -sh /var/lib/docker/containers/*/*.log | sort -h | tail
du -sh /var/lib/docker/volumes/* | sort -h | tail
Лечится не удалением, а ограничением на будущее. В docker-compose.yml ноды каждому сервису:
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
docker compose up -d, и файл лога физически не сможет вырасти больше 30 МБ. Плюс убавьте многословность самого Xray: в конфиге ноды уровень логирования выше warning на проде не нужен, а access-лог на живой ноде это ещё и лишние данные о клиентах, которые вам незачем хранить.
Шаг 4. Алерты в Telegram
Settings → Notifications, добавить URL в формате shoutrrr:
telegram://<BOT_TOKEN>@telegram?chats=<CHAT_ID>
BOT_TOKEN: от@BotFather, без префиксаbot.CHAT_ID: ваш id или id группы (у групп он с минусом). Для группы бота нужно сначала в неё добавить.
Дальше алерты включаются по каждой системе в таблице на главной. Доступные типы: CPU, память, диск, пропускная способность, температура, load average и статус.
Заведите под это отдельную группу, а не личку. Когда нод десяток, алерты в личке смешиваются с рабочей перепиской и теряются, проверено многими.
Чего Beszel не покажет
Честно про границы, чтобы не было ложного спокойствия:
- Блокировку. Нода идеальна по всем метрикам, а из России не открывается. Это ловит Kuma снаружи и живая проверка с РФ-адреса.
- Качество маршрута до клиента. Потери и джиттер по пути не про ресурсы сервера.
- Что творится у хостера. Steal time намекнёт на оверселл, но подтверждать диагноз придётся отдельно.
- Прикладные ошибки. Xray может отдавать ошибки при нулевой нагрузке, смотрите логи и Диагностику «не работает».
Чек-лист
- Хаб не на ноде, порт на
127.0.0.1, наружу через nginx с сертификатом. - Админ-аккаунт создан сразу, пароль сильный.
- Агенты в WebSocket-режиме, порт
45876закрыт фаерволом. MemoryMaxагенту прописан.- Пороги: диск 75%, память 90% с выдержкой, LA по числу ядер, трафик 70% лимита.
- Логи Docker ограничены
max-sizeна всех нодах, не только на проблемной. - Алерты в отдельную группу Telegram, проверены тестовым срабатыванием.
- Uptime Kuma оставлена работать: она про другое.
Полчаса на настройку. Окупается первым же алертом «диск 75%» в среду днём вместо «всё легло» в субботу ночью.