Ваш мониторинг съедает VPS: сколько ресурсов на самом деле нужны Prometheus и Grafana
Система мониторинга конкурирует за те же ресурсы, состояние которых должна отслеживать. Prometheus держит активные ряды в памяти, пишет WAL и регулярно уплотняет блоки TSDB. Grafana создаёт всплески запросов при обновлении дашбордов, а неудачные правила превращают Alertmanager в источник повторяющихся уведомлений. Если сервер выбран только по числу целей, нехватка RAM или дисковых операций обнаруживается уже после запуска. Надёжнее заранее оценить число временных рядов, скорость приёма образцов, срок хранения и профиль запросов. Эти параметры дают основу для выбора CPU, памяти и NVMe, а затем уточняются нагрузочным тестом и наблюдением за самим стеком.
Почему VPS – рабочий вариант под Prometheus и Grafana
Отдельный VPS-сервер подходит небольшим и средним командам, которым нужен контроль над retention, сетевым доступом и версиями компонентов без обслуживания физического узла. По сравнению с managed-сервисом команда сама отвечает за обновления, резервные копии и доступность. Managed-сервис удобнее, если команда не готова обновлять стек и реагировать на сбои самого мониторинга. Выделенный физический сервер становится оправданным при миллионах активных рядов, тяжёлых запросах или требованиях к предсказуемым IOPS, которые конкретный тариф VPS не подтверждает.
Стек лучше отделить от приложений: перегруженный сервис не должен вытеснять Prometheus из памяти вместе с данными о сбое. Но VPS в том же дата-центре или аккаунте не увидит отказ всей площадки. Добавьте независимую проверку из другой сети и внешний контроль получения периодического heartbeat-сигнала. Shared vCPU и общий дисковый контур тоже могут искажать картину, поэтому отслеживайте CPU steal, задержку диска и время выполнения правил.
Resource overhead: сколько реально потребляет стек
Число целей само по себе мало что говорит о нагрузке. Для ориентиров ниже предполагается по 500 активных рядов на цель, scrape каждые 15 секунд, обычные системные дашборды и отсутствие рендеринга изображений. Это около 1,7 тыс., 6,7 тыс. и 33 тыс. образцов в секунду. Диапазоны нужны для первого запуска, после которого ресурсы сверяют с prometheus_tsdb_head_series, скоростью приёма образцов, RSS процессов и длительностью запросов.
Prometheus
50 целей / 25 тыс. рядов: 1–2 vCPU, 2–4 ГБ RAM
200 целей / 100 тыс. рядов: 2–4 vCPU, 4–8 ГБ RAM
1000 целей / 500 тыс. рядов: 4–8 vCPU, 12–24 ГБ RAM
Grafana
50 целей / 25 тыс. рядов: 2 vCPU, 2–4 ГБ RAM
200 целей / 100 тыс. рядов: 2 vCPU, 2–4 ГБ RAM
1000 целей / 500 тыс. рядов: 2–4 vCPU, 4–8 ГБ RAM
Alertmanager
50 целей / 25 тыс. рядов: 0,1–0,3 ГБ RAM, доля vCPU
200 целей / 100 тыс. рядов: 0,2–0,5 ГБ RAM, до 1 vCPU
1000 целей / 500 тыс. рядов: 0,5–1 ГБ RAM, 1–2 vCPU
node_exporter
50 целей / 25 тыс. рядов: обычно десятки МБ на каждой цели; нагрузка зависит от включённых коллекторов
200 целей / 100 тыс. рядов: обычно десятки МБ на каждой цели; расход не относится к центральному VPS
1000 целей / 500 тыс. рядов: обычно десятки МБ на каждой цели; необходимо контролировать длительность scrape
Основную нагрузку от роста числа целей принимает Prometheus. Grafana рассчитывают по числу пользователей, панелей и правил, Alertmanager – по числу активных алертов, групп и получателей.
Prometheus: TSDB, retention и IOPS
По оценке разработчиков Prometheus, постоянные блоки TSDB занимают в среднем 1–2 байта на образец. При 33 тыс. образцов в секунду это около 2,9–5,8 ГБ в сутки, или 86–174 ГБ за 30 дней. WAL, chunks_head и временное место для compaction требуют дополнительной ёмкости. Практический план должен оставлять не менее 20–30% свободного пространства и ограничивать хранение одновременно по времени и размеру.
Уменьшение scrape_interval с 15 до 5 секунд утраивает скорость приёма при прежнем наборе рядов. Ещё опаснее рост кардинальности меток, то есть числа уникальных значений: user_id, UUID и необработанный URL порождают отдельный ряд на каждое из них. Сначала исключайте ненужные метрики и метки, затем увеличивайте интервал там, где минутная детализация достаточна.
remote_write отправляет образцы во внешнее долговременное хранилище, но увеличивает расход RAM, CPU и сети. В документации Prometheus отмечено, что пользователи сообщают примерно о 25% дополнительной памяти, хотя результат зависит от частоты появления и исчезновения рядов, а также очередей. Следите за отставанием и числом ожидающих образцов. Федерация решает другую задачу: верхний Prometheus забирает выбранные, обычно агрегированные ряды с нижестоящих серверов. Она не заменяет резервирование и долговременное хранилище.
Grafana и Alertmanager: лёгкие, но со своими нюансами
Для запуска Grafana достаточно 512 МБ RAM и одного ядра. Для небольшого развёртывания руководство рекомендует 2 ядра и 2–4 ГБ RAM. Расход зависит от числа пользователей, панелей, правил и частоты обновления. Широкие диапазоны, короткий auto-refresh и панели с тяжёлым PromQL нагружают прежде всего источник данных. Recording rules сокращают повторные вычисления. Сервис рендеринга изображений лучше выносить отдельно, поскольку браузерные процессы потребляют значительно больше памяти, чем обычный интерфейс.
Alertmanager хранит активные алерты, silences и журнал отправок. Расход обычно невелик, пока не растут число событий, маршрутов и получателей. Каталог данных должен быть постоянным, иначе после перезапуска пропадут silences и состояние дедупликации. node_exporter работает на наблюдаемой машине, а не на центральном узле. Его порт открывайте только для адресов сборщика.
Подбор конфигурации VPS под задачи мониторинга
В таблице сохранён тот же профиль: 500 рядов на цель, интервал 15 секунд, 30 дней локального хранения. NVMe указан с запасом для WAL, compaction и рабочих запросов. Если Grafana одновременно используют десятки пользователей или в Prometheus выполняются длинные ad hoc запросы, выбирайте верхнюю границу RAM и CPU.
До 50 целей
vCPU: 2
RAM: 4–8 ГБ
NVMe: 80–120 ГБ
Профиль: 15–30 дней хранения, простые дашборды
Около 200 целей
vCPU: 4
RAM: 8–16 ГБ
NVMe: 160–250 ГБ
Профиль: 30 дней хранения, recording rules, умеренный remote_write
Около 1000 целей
vCPU: 8
RAM: 24–32 ГБ
NVMe: 400–600 ГБ
Профиль: 30 дней хранения, разделение scrape-групп, план горизонтального роста
Высокая доступность
vCPU: от 4 на каждый узел
RAM: от 8 ГБ на каждый узел
NVMe: рассчитывается отдельно для каждого узла
Две реплики Prometheus с одинаковыми целями и дедупликация во внешнем хранилище или слое запросов
Проверяйте не только маркировку NVMe, но и лимиты IOPS, задержку записи и поведение диска во время compaction. RAM нужна активным рядам и запросам, поэтому увеличение retention влияет на диск сильнее, чем на память. Для сети посчитайте входящий поток scrape и исходящий remote_write, затем проверьте квоту трафика и доступность приватной сети.
Держите 30–40% запаса на рост кардинальности, обновление компонентов и временные очереди. Если Prometheus устойчиво приближается к лимиту RAM или во время compaction растёт задержка дисковых операций, простого увеличения диска недостаточно. Разделите сбор по площадкам, вынесите долговременное хранение или добавьте второй сервер до того, как одиночный узел станет точкой отказа.
Установка и базовая настройка стека
Разворачивая мониторинг на VPS через Docker Compose, закрепляйте проверенные версии образов и храните конфигурацию в Git. Ниже показан минимальный compose-файл с закреплёнными версиями образов. Перед развёртыванием сверьте их с текущими стабильными релизами. Административные интерфейсы привязаны к localhost: публикуйте Grafana через reverse proxy с TLS или открывайте её только из доверенной сети.
services:
prometheus:
image: prom/prometheus:v3.13.2
restart: unless-stopped
volumes:
- ./prometheus:/etc/prometheus:ro
- prometheus_data:/prometheus
ports: ["127.0.0.1:9090:9090"]
grafana:
image: grafana/grafana:13.1.1
restart: unless-stopped
volumes: ["grafana_data:/var/lib/grafana"]
ports: ["127.0.0.1:3000:3000"]
alertmanager:
image: prom/alertmanager:v0.33.1
restart: unless-stopped
volumes:
- ./alertmanager:/etc/alertmanager:ro
- alertmanager_data:/alertmanager
ports: ["127.0.0.1:9093:9093"]
volumes:
prometheus_data:
grafana_data:
alertmanager_data:
Выдайте контейнерам доступ только к нужным каталогам. На VPS оставьте доступными SSH и порты обратного прокси. К node_exporter разрешите подключение только с адреса Prometheus. Сохраняйте резервные копии конфигурации, provisioning Grafana и её БД. Копирование работающего каталога TSDB не гарантирует согласованный снимок.
В этом примере Grafana использует встроенную SQLite. Она подходит для тестового или небольшого внутреннего стенда. Для продакшена и нескольких реплик подключите внешнюю PostgreSQL или MySQL.
prometheus.yml и scrape-конфиги
В Prometheus 3.13 retention можно задать в prometheus.yml. Значение 60GB в примере рассчитано на небольшой профиль и том объёмом не менее 80 ГБ. Для другой скорости приёма лимит пересчитывают отдельно. Если одновременно заданы время и размер, Prometheus применит ограничение, которое сработает раньше. WAL и head-блокам всё равно нужно свободное место. metric_relabel_configs выполняется после получения метрик и помогает отбрасывать ненужные ряды до записи в TSDB.
global:
scrape_interval: 15s
evaluation_interval: 30s
external_labels:
environment: production
storage:
tsdb:
retention:
time: 30d
size: 60GB
rule_files: ["/etc/prometheus/rules/*.yml"]
alerting:
alertmanagers:
- static_configs:
- targets: ["alertmanager:9093"]
scrape_configs:
- job_name: node
static_configs:
- targets: ["10.0.0.11:9100", "10.0.0.12:9100"]
labels:
cluster: core
metric_relabel_configs:
# Не сохраняем метрики временных точек монтирования
- source_labels: [mountpoint]
regex: "/run/.*"
action: drop
Не меняйте интервалы сразу для всех job. Короткий интервал нужен там, где изменения требуется обнаруживать за несколько секунд. Ёмкость диска или срок сертификата можно проверять реже.
Alerting без шума: правила и маршрутизация
Порог без выдержки времени реагирует на каждый короткий провал. Поле for оставляет алерт в состоянии pending, пока условие не выполняется непрерывно. Метки severity, team и service нужны маршрутизации, но не добавляйте в них динамические значения.
groups:
- name: availability
interval: 30s
rules:
- alert: TargetDown
expr: up == 0
for: 5m
labels:
severity: critical
team: platform
annotations:
summary: "Цель {{ $labels.instance }} недоступна более пяти минут"
В Alertmanager настройка маршрутизации начинается с группировки связанных событий. group_wait собирает первые алерты, group_interval задаёт интервал отправки изменений в группе, а repeat_interval ограничивает повтор уже известного уведомления. Inhibition подавляет предупреждение, когда для той же цели сработал критический сигнал.
route:
receiver: default
group_by: [cluster, alertname]
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- receiver: oncall
matchers: ['severity="critical"']
inhibit_rules:
- source_matchers: ['severity="critical"']
target_matchers: ['severity="warning"']
equal: [alertname, instance]
receivers:
- name: default
webhook_configs:
- url: http://notification-gateway:8080/warnings
send_resolved: true
- name: oncall
webhook_configs:
- url: http://notification-gateway:8080/critical
send_resolved: true
Перед запуском проверьте Compose, конфигурацию Prometheus, правила и конфигурацию Alertmanager:
docker compose config
docker compose run --rm --entrypoint /bin/promtool prometheus check config /etc/prometheus/prometheus.yml
docker compose run --rm --entrypoint /bin/promtool prometheus check rules /etc/prometheus/rules/availability.yml
docker compose run --rm --entrypoint /bin/amtool alertmanager check-config /etc/alertmanager/alertmanager.yml
Не храните токены в открытом репозитории. После изменения отправьте тестовый алерт и проверьте уведомления о срабатывании и восстановлении, а также отсутствие дублей. Для каждого сигнала укажите действие или ранбук. Без понятной реакции он создаёт шум независимо от порога.
Оптимизация и типовые ошибки
Чаще всего стек перегружают лишние ряды и запросы. Сократите кардинальность и ненужные collectors, увеличьте интервалы для медленных показателей, вынесите повторяющийся PromQL в recording rules. Ограничьте auto-refresh и диапазон ad hoc запросов. Длительную историю храните снаружи, федерацию используйте для выбранных агрегатов.
Проверяйте здоровье стека по короткому списку:
· retention ограничен по времени и размеру, свободно не менее 20–30% диска.
· рост активных рядов и скорости приёма объясним.
· длительность scrape и evaluation укладывается в соответствующий интервал.
· remote_write не копит очередь, отказ приёмника проверен.
· для чувствительных к кратким провалам алертов задано for.
· проверены группировка, inhibition и инструкции по реакции.
· дашборды и правила версионируются, правила проверяются через promtool, изменения проходят ревью.
· собственные метрики Grafana, Alertmanager и Prometheus используются в алертах.
· независимая проверка обнаруживает недоступность VPS, а внешний контроль heartbeat-сигнала – отказ канала уведомлений.
Проверьте настроенный сервер под реальной нагрузкой и по метрикам, а восстановление резервных копий – отдельным тестом.
Как поднять свой VPS: путь от чистой ОС до рабочей среды
Вы арендовали VPS, получили IP и пароль от root. Между этим моментом и рабочим сервисом в продакшене лежит десяток шагов, которые важно пройти в правильном порядке. Пропустить один из них означает оставить сервер уязвимым или потратить часы на отладку в самый неподходящий момент. И здесь встаёт вопрос: как подготовить свой VPS к реальной работе?
Этот материал проведёт вас от первого SSH-подключения до полноценного окружения с безопасным доступом, настроенным firewall и рабочим стеком приложений. Руководство написано для Ubuntu 22.04 LTS: проверенного LTS-релиза, который часто используют для серверов и небольших проектов. В конце вас ждёт чек-лист, который удобно держать под рукой при каждой новой установке.
Что понадобится до начала установки VPS
Перед тем как приступить к установке VPS и первичной настройке, убедитесь, что у вас есть всё необходимое.
Во-первых, данные для подключения: IP-адрес сервера, имя пользователя (обычно root) и пароль или SSH-ключ. Всё это провайдер высылает на email сразу после создания машины. Если провайдер вместо пароля сразу добавил публичный ключ, убедитесь, что соответствующий приватный ключ есть у вас локально.
Во-вторых, терминал на локальной машине. На macOS и Linux SSH встроен по умолчанию. На Windows удобно использовать PowerShell со встроенным OpenSSH-клиентом.
Заранее найдите в панели провайдера KVM/VNC-консоль, она понадобится в случае потери SSH-доступа после изменений в конфигурации сети или firewall.
Первое подключение к серверу по SSH
Подключитесь к серверу из терминала. Замените YOUR_IP на IP-адрес сервера:
ssh root@YOUR_IP
При первом подключении терминал покажет предупреждение с отпечатком (fingerprint) сервера (уникальным идентификатором хоста) и предложит добавить его в список доверенных. Перед подтверждением сверьте fingerprint с данными в панели провайдера или документации к инстансу. Если он совпадает, введите yes. SSH сохранит ключ хоста в ~/.ssh/known_hosts. Если отпечаток изменится при повторном подключении, это может указывать на атаку посредника или на переустановку сервера.
Если провайдер настроил аутентификацию по SSH-ключу, а не по паролю, укажите путь к приватному ключу:
ssh -i ~/.ssh/id_rsa root@YOUR_IP
Возможные ошибки при первом подключении:
• Connection refused: SSH-сервис не запущен или порт закрыт. Проверьте состояние сервера через панель провайдера, иногда образ ещё инициализируется.
• Permission denied (publickey): ключ не добавлен на сервер или указан неверный путь к файлу ключа.
• Connection timed out: IP указан неверно или сервер ещё загружается. Подождите минуту и повторите.
Для удобства при частых подключениях настройте алиас в файле ~/.ssh/config на локальной машине:
Host myserver
HostName YOUR_IP
User root
IdentityFile ~/.ssh/id_rsa
После этого достаточно набрать ssh myserver. При необходимости подключаться под другим пользователем добавьте второй блок Host с другим значением User.
Обновление системы и базовые пакеты
Сразу после входа обновите список пакетов и сами пакеты.
apt update && apt upgrade -y
После обновления установите базовый набор инструментов:
apt install -y curl wget htop ufw fail2ban
Назначение каждого пакета:
• curl и wget: загрузка файлов и скриптов из сети;
• htop: интерактивный мониторинг процессов и потребления ресурсов;
• ufw: управление правилами firewall поверх iptables;
• fail2ban: автоматическая блокировка IP при многократных неудачных попытках входа.
Если после обновления терминал выводит System restart required, было обновлено ядро. Выполните reboot, дождитесь восстановления SSH-соединения (обычно 30–60 секунд) и продолжайте.
Создание пользователя и настройка безопасного доступа
Безопасная работа на своём VPS начинается с отказа от постоянной работы под root. Любая ошибка в команде или скомпрометированный пакет, запущенный с правами root, получает неограниченный доступ к системе. Создайте отдельного пользователя с правами sudo.
Если у вас ещё нет SSH-ключа, сгенерируйте его на локальной машине. Алгоритм ed25519 предпочтительнее RSA:
ssh-keygen -t ed25519 -C "myserver"
Публичный ключ находится в ~/.ssh/id_ed25519.pub. Его нужно добавить на сервере в файл ~/.ssh/authorized_keys того пользователя, под которым вы будете подключаться по SSH.
Создание пользователя и добавление в группу sudo:
adduser admin
usermod -aG sudo admin
Проверьте, что пользователь добавлен корректно:
id admin
В выводе должна присутствовать группа sudo. Зайдите под новым пользователем и проверьте работу sudo: выполните sudo whoami, вывод root подтверждает корректную конфигурацию. Скопируйте SSH-ключи из root-окружения:
mkdir -p /home/admin/.ssh
cp /root/.ssh/authorized_keys /home/admin/.ssh/authorized_keys
chown -R admin:admin /home/admin/.ssh
chmod 700 /home/admin/.ssh
chmod 600 /home/admin/.ssh/authorized_keys
Важно: откройте вторую сессию и убедитесь, что вход под admin работает, прежде чем вносить следующие изменения. Потеря доступа на этом этапе потребует входа через KVM/VNC-консоль провайдера.
Откройте конфигурацию SSH:
nano /etc/ssh/sshd_config
Найдите и задайте параметры:
PermitRootLogin no
PasswordAuthentication no
Перезагрузите конфигурацию через reload, а не restart: активные сессии при этом не прервутся.
systemctl reload ssh
Опционально: смена стандартного порта SSH с 22 на нестандартный снижает объём шума от автоматических сканеров в логах. Если решите изменить порт, сначала разрешите новый порт в UFW, затем внесите изменения в sshd_config и только после этого перезагрузите SSH.
Настройка брандмауэра и базовой защиты
Свежий сервер без firewall попадает под сканирование портов в первые минуты после выдачи публичного IP. UFW (Uncomplicated Firewall) снижает этот риск без необходимости работать с iptables напрямую. По умолчанию UFW блокирует весь входящий трафик и разрешает исходящий трафик.
Важный порядок действий: сначала создайте разрешающие правила, и только потом включайте firewall. Иначе вы заблокируете SSH и потеряете доступ к серверу.
Разрешите нужные порты:
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
Если используете нестандартный порт SSH, добавьте его вместо или дополнительно к 22 на период перехода. Включите firewall и проверьте статус:
ufw enable
ufw status
Вывод Status: active и список разрешённых портов подтверждают корректную работу. Все остальные входящие соединения будут отклоняться.
Настройка fail2ban. На Ubuntu 22.04 SSH-события пишутся в systemd journal, поэтому создайте файл /etc/fail2ban/jail.local с указанием backend:
[sshd]
enabled = true
backend = systemd
maxretry = 5
bantime = 1h
Перезапустите сервис и проверьте статус:
systemctl restart fail2ban
fail2ban-client status sshd
В выводе строки Currently banned и Currently failed покажут число заблокированных адресов и количество неудачных попыток за текущий период. Снять блокировку вручную можно командой fail2ban-client set sshd unbanip IP. Если fail2ban не видит попыток входа при реальных ошибках, проверьте значение backend = systemd в конфиге.
Установка рабочей среды: веб-сервер, БД, язык
Состав стека целиком зависит от задач проекта. Для большинства веб-приложений достаточно трёх компонентов: веб-сервер, база данных и runtime языка. Устанавливайте только то, что действительно нужно: каждый лишний запущенный сервис потребляет ресурсы сервера.
Nginx в роли веб-сервера и reverse proxy – стандартный выбор для большинства проектов:
apt install -y nginx
systemctl enable nginx
PostgreSQL для реляционных данных:
apt install -y postgresql
MySQL как альтернатива:
apt install -y mysql-server
Node.js. Версия в стандартном репозитории Ubuntu 22.04 может быть старее актуальной LTS-версии. Для установки свежей LTS-версии можно использовать NodeSource, предварительно сверив номер версии на nodejs.org:
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
apt install -y nodejs
Python 3 уже предустановлен в Ubuntu 22.04. Для работы с виртуальными окружениями добавьте:
apt install -y python3-pip python3-venv
Docker как универсальный вариант
Если проект допускает контейнеризацию, Docker избавляет от ручного управления зависимостями: приложение с окружением упаковывается в образ и запускается одинаково на любом хосте. Для продакшен-среды предпочтительнее установка через официальный apt-репозиторий Docker: так проще контролировать источник пакетов и обновления. Официальный скрипт тоже добавляет репозиторий Docker Engine и ставит актуальную версию, но его лучше использовать для быстрого старта или тестового окружения:
curl -fsSL https://get.docker.com | sh
Добавьте пользователя в группу docker, чтобы команды выполнялись без sudo:
usermod -aG docker admin
Изменения применятся при следующем входе в сессию. Docker Compose v2 устанавливается как плагин и вызывается без дефиса:
apt install -y docker-compose-plugin
docker compose up -d
Пример минимального docker-compose.yml для сервиса с автоперезапуском:
services:
app:
image: myapp:latest
ports:
- "8080:8080"
restart: unless-stopped
Проверьте, что Docker установлен корректно и может запустить тестовый контейнер:
docker run hello-world
Домен, SSL и автозапуск сервисов
Привязка домена. В DNS-настройках у регистратора добавьте A-запись, указав IP сервера:
@ → YOUR_IP
www → YOUR_IP
Обновление DNS-записей занимает от нескольких минут до 24 часов. Проверить это можно командой dig yourdomain.com или через онлайн-сервисы вроде dnschecker.org. Не запускайте certbot до того, как запись распространится: это приведёт к ошибке валидации.
HTTPS через Let's Encrypt. Установите Certbot с плагином для Nginx:
apt install -y certbot python3-certbot-nginx
Получите сертификат:
certbot --nginx -d yourdomain.com -d www.yourdomain.com
Certbot изменит конфигурацию Nginx, добавит HTTPS-блок с путями к сертификату и предложит настроить редирект с HTTP на HTTPS. Обновление сертификата происходит через cron или systemd timer без вашего участия. Сертификат Let's Encrypt действует 90 дней. Проверьте, что продление пройдёт без ошибок:
certbot renew --dry-run
Автозапуск сервисов. Пакеты, установленные через apt, как правило, включаются в автозапуск автоматически. Для собственного приложения создайте unit-файл:
nano /etc/systemd/system/myapp.service
Минимальное содержимое:
[Unit]
Description=My Application
After=network.target
[Service]
ExecStart=/usr/bin/node /home/admin/app/index.js
User=admin
Restart=on-failure
[Install]
WantedBy=multi-user.target
Подключите и запустите:
systemctl daemon-reload
systemctl enable myapp
systemctl start myapp
Чек-лист: что проверить перед запуском в прод
Каждая установка VPS проходит по схожему маршруту. Сохраните этот список и проходитесь по пунктам при каждой новой настройке.
1. Система обновлена: apt update && apt upgrade выполнены
2. Создан непривилегированный пользователь с правами sudo
3. Root-вход отключён: PermitRootLogin no в /etc/ssh/sshd_config
4. Аутентификация только по SSH-ключу: PasswordAuthentication no
5. UFW активен: ufw status показывает Status: active с нужными правилами
6. fail2ban работает: fail2ban-client status sshd показывает активный jail
7. HTTPS настроен: certbot renew --dry-run выполняется без ошибок
8. Сервисы добавлены в автозапуск: проверьте systemctl is-enabled nginx и другие
9. Настроены бэкапы или снапшоты через панель провайдера
10. Запланированы регулярные обновления безопасности: настройте unattended-upgrades для security-обновлений или другой контролируемый процесс обновления.
От первого ssh root до продакшен-среды вполне можно дойти за один рабочий день. Настройка VPS-сервера с нуля требует внимания прежде всего на этапе безопасности: шаги, пропущенные здесь, могут позже дать о себе знать. Не жалейте времени на проверку каждого пункта чек-листа до открытия сервиса пользователям.
Fail2Ban на VPS: защита от bruteforce без лишней магии
VPS с открытым SSH-портом быстро замечается ботами. На сервере счётчик неудачных входов набирает сотни попыток в сутки, а на давно засвеченных адресах – тысячи. Боты работают автоматически и не делают перерывов. Настройка VPS без базовой защиты от перебора – прямое приглашение для таких сканеров.
Оценить масштаб можно без внешних сервисов: откройте журналы за сутки и посмотрите, сколько раз повторяются одни и те же адреса или подсети. У нового сервера первые попытки нередко появляются через несколько минут после выдачи публичного IP. Поэтому Fail2Ban лучше ставить сразу после настройки доступа, а не когда перебор уже попал в мониторинг.
Fail2Ban не заменяет SSH-ключи, отключение входа по паролю и аккуратный firewall, но хорошо снимает самый частый шум от bruteforce: видит повторяющиеся ошибки входа и отправляет подозрительные IP в бан. Ниже – рабочая настройка для Ubuntu 22.04/24.04, Debian 11/12, AlmaLinux 9 и CentOS Stream 9: установка, jail.local, защита SSH и проверка результата.
Что такое Fail2Ban и как он работает?
Fail2Ban работает довольно просто. Этот инструмент на Python читает лог-файлы или systemd journal и ищет строки, похожие на неудачную аутентификацию. Совпало регулярное выражение – счётчик для IP увеличился. Набралось maxretry ошибок за findtime – адрес уходит в firewall на время bantime. Когда срок заканчивается, блокировка снимается автоматически.
Отдельный сервис поднимать не нужно, Fail2Ban использует системный firewall: iptables, nftables или firewalld. Вся защита от bruteforce держится на понятной связке: лог, фильтр, порог срабатывания и действие блокировки.
В конфигурации чаще всего встречаются два термина:
Jail – правило для конкретного сервиса: какие события читать, какие строки считать нарушением и что делать после превышения лимита.
Filter – набор failregex, то есть регулярных выражений для поиска нужных строк в логе. Для SSH, nginx, postfix и других популярных сервисов такие фильтры уже лежат в пакете.
Подготовка VPS перед установкой
Правильная настройка VPS сервера начинается с доступа. Перед установкой нужно оставить себе путь назад: несколько действий занимают пару минут, зато помогают не попасть в классический сценарий, когда защита сработала, но заблокировала самого администратора.
Обновите систему:
# Ubuntu/Debian
sudo apt update && sudo apt upgrade -y
# AlmaLinux 9 / CentOS Stream 9
sudo dnf update -y
Узнайте свой текущий внешний IP. Его необходимо добавить в белый список:
curl -4 https://api.ipify.org
Проверьте, что на сервере есть пользователь с sudo. Работать от root не рекомендуется: ошибка в конфиге или случайная команда могут повлиять на весь сервер.
Чек-лист перед установкой
• SSH-доступ работает; запасная сессия открыта или есть KVM/VNC-консоль в панели провайдера
• Внешний IP известен: curl -4 https://api.ipify.org
• На сервере есть пользователь с sudo
• Если используется UFW на Ubuntu/Debian, проверен его статус: sudo ufw status
• На AlmaLinux 9 / CentOS Stream 9 проверен firewalld: sudo systemctl status firewalld
Установка Fail2Ban на Ubuntu/Debian и AlmaLinux/CentOS
На Ubuntu и Debian пакет есть в стандартном репозитории:
sudo apt install fail2ban -y
/var/log/auth.log может отсутствовать при использовании systemd-journald вместо rsyslog. Если auth.log отсутствует или jail [sshd] не считает попытки входа, задайте backend = systemd. При использовании backend = systemd может потребоваться пакет python3-systemd. На минимальных образах он не всегда установлен:
sudo apt install python3-systemd -y
Проблема с backend может выглядеть так: сервис запущен, jail [sshd] активен, но Currently failed остаётся 0 даже после заведомо ошибочных SSH-входов. В таком случае явно укажите backend = systemd и перезапустите инструмент.
В AlmaLinux 9 и CentOS Stream 9 Fail2Ban обычно ставят через EPEL. Для связки с firewalld понадобится дополнительный пакет fail2ban-firewalld:
sudo dnf install epel-release -y
sudo dnf install fail2ban fail2ban-firewalld -y
На современных системах Fail2Ban также может работать через nftables без fail2ban-firewalld, в зависимости от выбранного banaction.
Запуск и добавление в автозагрузку:
sudo systemctl enable --now fail2ban
Проверка статуса:
sudo systemctl status fail2ban
В статусе нужен Active: active (running). Если сервис упал, первым делом посмотрите последние сообщения unit:
journalctl -u fail2ban -n 50
Базовая конфигурация: jail.local без магии
/etc/fail2ban/jail.conf приходит вместе с пакетом и может измениться после обновления. Свои правила лучше держать в /etc/fail2ban/jail.local: он читается поверх jail.conf и обычно не перезаписывается при обновлениях.
Создаём файл:
sudo nano /etc/fail2ban/jail.local
Секция [DEFAULT] задаёт глобальные параметры для всех jail:
[DEFAULT]
# Адреса из этого списка никогда не блокируются
ignoreip = 127.0.0.1/8 ::1 Ваш_IP
# Время блокировки (s – секунды, m – минуты, h – часы, d – дни)
bantime = 1h
# Временное окно для подсчёта неудачных попыток
findtime = 10m
# Количество неудач до блокировки
maxretry = 5
# Бэкенд чтения логов: auto подходит для большинства систем
backend = auto
ignoreip заполните сразу, до тестов. Добавьте свой IP, а при статическом офисном адресе – ещё и офисную подсеть. Иначе одна серия ошибочных входов может закончиться блокировкой администратора.
bantime определяет срок бана. Десять минут часто слишком мало: бот успевает вернуться с тем же или соседним адресом. Для рабочей SSH-защиты обычно начинают с 1h, а затем повышают до 24h, если ложных срабатываний нет.
findtime и maxretry всегда смотрят вместе. При findtime = 10m и maxretry = 5 адрес блокируется после пяти ошибок за десять минут. Для SSH это нормальный старт: пользователь с опечаткой не страдает, а простой перебор быстро отсекается.
backend = auto автоматически выбирает способ чтения логов в зависимости от окружения. В большинстве случаев этого достаточно, но если SSH-события не обнаруживаются, необходимо указать backend = systemd в нужном jail.
Защита SSH: минимально рабочая конфигурация
Добавьте в jail.local секцию [sshd] для защиты входа по SSH. Обычная настройка fail2ban ssh выглядит так:
[sshd]
# Включаем jail
enabled = true
# Порт SSH (измените, если используете нестандартный)
port = ssh
# Фильтр из /etc/fail2ban/filter.d/sshd.conf
filter = sshd
# Переопределяем глобальные значения для SSH
maxretry = 5
bantime = 24h
Если SSH-события в Ubuntu 24.04 читаются через journal, добавьте в [sshd]:
backend = systemd
Для AlmaLinux 9 и CentOS Stream 9 задайте действие блокировки через firewalld в [DEFAULT] или [sshd]:
# На AlmaLinux / CentOS Stream 9 обычно используется firewalld
banaction = firewallcmd-rich-rules
После правок перезапустите сервис:
sudo systemctl restart fail2ban
Дополнительные jail: nginx, postfix, панели управления
Фильтры для nginx, postfix, dovecot и других сервисов лежат в /etc/fail2ban/filter.d/. Например, для basic auth в nginx можно завести отдельный jail:
[nginx-http-auth]
enabled = true
port = http,https
maxretry = 10
Для ISPmanager, cPanel, Plesk и других панелей универсального фильтра обычно нет. Правила лучше брать из документации панели или репозитория Fail2Ban, а затем прогонять у себя.
Проверка работы и мониторинг
Общий статус всех активных jail:
sudo fail2ban-client status
Статус jail [sshd] показывает, сколько раз правило сработало и какие IP сейчас в бане:
sudo fail2ban-client status sshd
Если sshd не появился в списке jail, чаще всего проблема в jail.local. Проверить конфиг можно без перезапуска:
sudo fail2ban-client -t
Разбанить конкретный IP:
sudo fail2ban-client set sshd unbanip 192.168.1.100
Основной лог – /var/log/fail2ban.log. По строкам Ban и Unban видно, кого заблокировали и когда блокировка закончилась:
sudo tail -50 /var/log/fail2ban.log
Если при реальных атаках строк Ban нет, а Currently failed держится на 0, Fail2Ban смотрит не туда. На системах, где SSH пишет в /var/log/auth.log, фильтр можно проверить так:
# Тест фильтра против реального лог-файла
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
Типичные ошибки и как их избежать
Самоблокировка при настройке. Две-три ошибки в пароле – и ваш IP уже в бане. Перед тестами держите открытой запасную сессию. Если доступ пропал, зайдите через KVM/VNC в панели провайдера и снимите блокировку:
sudo fail2ban-client set sshd unbanip Ваш_IP
Неверный backend при использовании systemd journal. Если auth.log отсутствует, а backend оставлен auto, jail может не видеть SSH-события. Итог: Currently failed остаётся 0 при реальных неудачных входах. Обычно помогает backend = systemd в [sshd]; на минимальных образах проверьте python3-systemd.
Конфликт с firewalld на AlmaLinux и CentOS. Без fail2ban-firewalld и banaction блокировки через firewalld баны могут появляться в fail2ban.log, но не попадать в реальные правила firewall. Проверьте rich rules:
sudo firewall-cmd --list-rich-rules
Конфликт с UFW на Ubuntu. Если Fail2Ban использует способ блокировки, который не совпадает с активным firewall, правила могут применяться некорректно. Проверьте выбранный banaction и используйте вариант, соответствующий вашему окружению: UFW, iptables, nftables или firewalld.
Слишком низкий maxretry. Значение 1–2 ловит не только ботов, но и людей с одной опечаткой при вводе пароля. Для SSH начинайте с 3–5 попыток; для веб-сервисов с живыми пользователями ставьте порог выше.
Ложные срабатывания. Если под бан попал легитимный пользователь или сервис, чаще всего виноваты слишком строгий maxretry или неподходящий failregex. На системах с /var/log/auth.log проверьте совпадения фильтра:
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
Если auth.log нет, смотрите SSH-события через journalctl и используйте backend = systemd. Адреса с постоянным административным доступом добавляйте в ignoreip.
Нет ignoreip для офисных адресов. При смене сети или работе из нескольких локаций риск заблокировать себя выше. Если у офиса статический IP, внесите в ignoreip всю офисную подсеть.
Итоговый чек-лист внедрения
1. Сервис стартует вместе с системой, а systemctl status fail2ban показывает active (running)
2. Пользовательские правила лежат в /etc/fail2ban/jail.local, минимум с секциями [DEFAULT] и [sshd]
3. В ignoreip внесены личный IP и административные подсети
4. bantime задан минимум на 1 час
5. Для систем с SSH-логами в systemd journal в [sshd] указан backend = systemd, а python3-systemd установлен или уже пришёл зависимостью
6. Для AlmaLinux 9 / CentOS Stream 9 установлен fail2ban-firewalld, а banaction работает через firewallcmd-rich-rules
7. fail2ban-client status sshd показывает активный jail и реальные счётчики при неудачных входах
Базовая настройка Fail2Ban обычно занимает 15–20 минут. После этого достаточно изредка проверять логи и whitelist, особенно при смене firewall, офиса или сети. Правильная настройка VPS сервера начинается с таких базовых вещей – ещё до деплоя приложения. Боты не ждут, пока вы закончите.
С днем системного администратора
С днем системного администратора!
Коллеги Сисадмин - это...
Согласны?
#ДеньСисадмина #SysAdminDay #IT #АдминВсемуГолова #Zabbix #DevOps
#ADM #ADM00103 #101 #АДМ #АДМ00103
VDS для баз данных: предсказуемый I/O важнее теоретической пиковой скорости
Для СУБД важна не максимальная скорость в коротком тесте, а стабильный отклик диска под рабочей нагрузкой. Требования к I/O зависят от профиля: OLTP, аналитика и смешанные нагрузки по-разному используют чтение, запись, WAL, временные файлы и кэш. VDS для баз данных оценивают по стабильному IOPS, p99-задержке и поведению под длительной нагрузкой, а не по лучшей цифре из прайса.
Почему БД чувствительны к стабильности I/O
PostgreSQL пишет WAL, MySQL – redo log и, если включён, binlog. При скачках задержки fsync с 2 до 80 мс транзакции могут ждать диск, а очередь запросов расти даже при нормальной средней скорости. io_wait сам по себе не всегда означает проблему: его нужно смотреть вместе с latency диска, p95/p99 и временем ответа запросов.
Пиковая скорость vs устойчивый IOPS
На VDS с burst-профилем короткий тест может показать высокий результат, но через несколько минут упереться в лимит хоста или нагрузку соседних VM. Для OLTP важнее, чтобы 5 000 IOPS держались ровно 10–15 минут, чем разовый пик в 50 000 IOPS на старте теста.
Метрики, на которые смотреть
Смотрите не только среднюю задержку, а p95/p99, джиттер и самые медленные операции записи. Оценивать график лучше относительно SLO конкретной СУБД и приложения: p99-задержка, время ответа запросов и io_wait не должны регулярно выходить за допустимые для проекта значения при одинаковой нагрузке.
Как проверить VDS перед миграцией БД
Перед переносом запустите fio со случайным чтением и записью блоками 4K минимум на 10 минут и отдельно проверьте СУБД через pgbench или другой нагрузочный тест. fio помогает оценить диск, но не полностью повторяет поведение PostgreSQL или MySQL: важны WAL, fsync, cache hit ratio и размер рабочего набора данных. Размер тестового файла должен быть больше объёма памяти, который может использоваться под page cache, иначе результат может попасть в кэш и показать нереалистично высокую скорость. Тестируйте VDS-сервер в то же время суток, когда у проекта обычно пиковая нагрузка.
Что замерить до переноса продакшена
• Стабильный IOPS на длительном fio-тесте
• p99-задержка чтения и записи
• p99-задержка fsync при типичной нагрузке вашей СУБД
• io_wait во время pgbench или тестовой нагрузки
• Наличие резервирования дисков, RAID-схему и поведение платформы при сбое накопителя
• Доступный объём RAM, использование page cache и активность swap под нагрузкой
• Поведение диска после 10–15 минут непрерывной нагрузки
До миграции продакшена проверьте диск под реальный профиль БД, а после переноса повторите тесты уже на рабочей нагрузке. Если тест показывает стабильную p99-задержку без резких всплесков, миграция будет менее рискованной: вы выбираете сервер по поведению под нагрузкой, а не по пиковой скорости.
VDS и выделенные ресурсы: когда предсказуемость важнее цены
Сервер на дешёвом тарифе может пройти тест на нагрузку и всё равно провалиться в продакшене. Причина не всегда в коде: на переподписанной ноде VM конкурируют за CPU, диск и сеть. Для сервисов важна не средняя скорость, а стабильность под пиками
Две модели VDS: shared vs dedicated
В shared-модели провайдер может использовать оверкоммит: виртуальных ресурсов на узле выделено больше, чем доступно физически. Сам по себе оверкоммит не всегда означает проблему: многое зависит от политики провайдера, мониторинга нод и лимитов для соседних VM. Но при высокой конкуренции за CPU может расти steal time, а при задержках операций ввода-вывода – iowait; в обоих случаях страдают p99 и хвостовые задержки.
VDS с выделенными ресурсами строится иначе: провайдер может снижать конкуренцию за CPU, резервировать RAM и задавать гарантии по диску, но конкретная реализация зависит от тарифа и инфраструктуры. Переплата здесь покупает не цифры в тарифе, а более предсказуемое поведение под нагрузкой.
Когда предсказуемость важнее цены
Выделенные ресурсы оправданы для БД под нагрузкой, платёжных сервисов, realtime-API, CI/CD-раннеров и геймдев-бэкендов. В этих сценариях рост p99 или jitter быстро превращается в проблему. Экономия на тарифе теряет смысл, если её съедают простои, миграции и разбор деградаций.
Метрики, которые всё решают
Следите за steal time, iowait, p99 latency и jitter. iowait показывает ожидание операций ввода-вывода, поэтому его стоит смотреть вместе с await, очередью диска, latency и метриками приложения. Для steal time 3–5% – повод проверить ноду. Для p99 и jitter пороги берите из SLO сервиса, а не из средней загрузки CPU.
Чек-лист выбора конфигурации
• SLA и компенсации прописаны в условиях
• CPU, RAM и диск имеют понятные гарантии
• Понятно, как ограничивается производительность диска
• Сеть выдерживает пики и не даёт лишний jitter
• Заложен запас ресурсов под рост нагрузки
Перед тем как арендовать VDS, сверьте текущую конфигурацию с этим списком. Если риски уже видны по метрикам, переход на выделенные ресурсы может обойтись дешевле возможного инцидента.
CPU Steal на VPS: скрытый сигнал, который большинство пользователей игнорирует
В логах пусто, CPU в норме, но приложение тормозит. Часто виновата метрика, которую игнорируют: cpu steal time, или %st. Она показывает, сколько времени VPS провёл в ожидании физического процессора.
Что такое CPU Steal и откуда он берётся?
На гипервизоре несколько VM делят физические ядра. Когда vCPU готов работать, но планировщик отдал ядро соседней машине, ожидание засчитывается в steal. Так устроен Cloud VPS с общими ресурсами: несколько виртуальных машин конкурируют за физические ядра одного хоста. Steal может расти из-за высокой загрузки гипервизора, оверселлинга, особенностей планировщика виртуализации или кратковременной конкуренции за CPU.
Как измерить steal time
Быстрее всего – строка CPU в выводе top:
%Cpu(s): 8.0 us, 2.0 sy, 0.0 ni, 85.0 id, 3.0 wa, 0.0 hi, 0.0 si, 2.0 st
Для наблюдения в динамике – vmstat 1: колонка st показывает steal за каждую секунду. Разбивку по ядрам даёт mpstat -P ALL 1. Для минутного замера с усреднением – sar -u 1 60.
Какие значения считать нормой
На стабильной ноде steal обычно близок к нулю, но универсальной нормы нет: многое зависит от типа нагрузки и платформы виртуализации. Практические ориентиры:
• 0–1% – обычно не вызывает проблем
• 3–5% – повод проверить динамику и сопоставить её с задержками приложения
• >10% – часто заметно влияет на производительность, особенно у чувствительных к задержкам сервисов
Смотрите на устойчивое значение за 10–15 минут, а не на пиковый выброс.
Что делать, если steal стабильно высокий
Сначала подтвердите устойчивость: sar -u 1 600 даст картину за 10 минут. Если steal держится выше 5%, стоит обратиться в поддержку провайдера: причина может быть в конкретной ноде, тарифе или особенностях инфраструктуры. Иногда помогает миграция на другой хост, но сначала лучше подтвердить проблему вместе с поддержкой. Если ситуация повторяется, рассмотрите тарифы с выделенными CPU-ядрами или смену провайдера.
Быстрый мониторинг VPS: чек-лист
• Запустите top, найдите строку %Cpu и проверьте %st
• Понаблюдайте за vmstat 1 в течение 30–60 секунд
• Сравните пики steal с замедлениями приложения
• Если steal стабильно выше 5%, зафиксируйте замеры и передайте их в поддержку
• Рассмотрите тариф с выделенными ядрами, если проблема системная
Запустите диагностику прямо сейчас хватит одной команды. Если steal стабильно высокий и совпадает с замедлениями приложения, сначала проверьте инфраструктуру, а уже потом ищите проблему в коде.

























