Когда нужно настроить постоянный и быстрый обмен файлами в локальной сети, мы поднимаем NFS или Samba. Но что делать, если сервер находится далеко в интернете, настраивать сложную шару некогда, а скачивать и закачивать файлы через scp или FileZilla уже надоело?
Тут на помощь приходит SSHFS (Secure Shell File System). Главная прелесть этой штуки в том, что на самом сервере вообще ничего не нужно настраивать. Если у вас есть SSH-доступ к серверу — значит, вы уже можете примонтировать его файловую систему к себе на ПК и работать с ней, как с обычной флешкой.
Делается это буквально в несколько команд.
Установка и подготовка На локальную машину (с которой будем подключаться) ставим пакет sshfs:
sudo apt install sshfs
Далее создаем директорию, которая будет служить точкой монтирования. Лучше всего делать это в своем домашнем каталоге, чтобы не возиться с правами root:
mkdir -p ~/mnt/remote_dir
(Ключ -p автоматически создаст все промежуточные каталоги, если их нет).
После монтирования можно проверить результат командой df -h. Теперь вы можете копировать, удалять, редактировать файлы в IDE или просматривать логи прямо в примонтированной папке. Все изменения моментально происходят на сервере.
Важные нюансы (чтобы не отваливалось) У SSHFS есть особенность: если интернет моргнет, примонтированная папка может намертво зависнуть. Чтобы этого избежать, рекомендую монтировать с параметрами поддержания сессии:
(Эта опция будет каждые 15 секунд отправлять ping-пакет на сервер, не давая соединению разорваться).
Как размонтировать? Когда работа закончена, директорию нужно отмонтировать. Так как мы монтировали без прав суперпользователя, обычный umount может выдать ошибку прав. Правильнее использовать эту команду:
fusermount -u ~/mnt/remote_dir
(Если получаете ошибку «устройство занято», убедитесь, что вы закрыли все файлы из этой папки и сами вышли из директории в терминале).
Используете ли вы SSHFS в повседневной работе или предпочитаете другие инструменты? Пишите в комменты.
Больше подобных шпаргалок, команд и коротких заметок по Linux и администрированию серверов я регулярно публикую в своем Telegram-канале [Linux для Админов и DevOps]. Буду рад видеть там коллег по цеху, заходите!
Многие сисадмины сейчас справедливо заметят: «Зачем изобретать велосипед, если можно просто сменить 22-й порт на нестандартный, повесить Fail2Ban, настроить вход только по ключам или вообще спрятать всё за VPN (WireGuard/OpenVPN)?»
Вы абсолютно правы. Это база. Но даже при входе по ключам постоянный фоновый шум от ботов-сканеров, стучащихся в логи, может раздражать. Сегодня хочу напомнить про старый, немного параноидальный, но очень изящный способ защиты — Port Knocking («стук в дверь»).
В чем суть? Ваш SSH-порт аппаратно закрыт фаерволом для всех без исключения. Он «откроется» (и то только для вашего IP-адреса), если вы предварительно «постучитесь» в правильной последовательности по другим закрытым портам. За всем этим следит неприметный демон knockd. Давайте посмотрим, как это настраивается за 5 минут.
Закрываем SSH в iptables Для начала запрещаем кому-либо инициировать новые подключения к нашему любимому 22 порту:
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j DROP
Всё. Теперь никто не может даже начать подключение. Сервер притворяется мертвым.
Устанавливаем и настраиваем knockd Ставим сам демон:
sudo apt install knockd
Обязательно делаем бекап дефолтного конфига:
sudo cp /etc/knockd.conf /etc/knockd.conf.bak
Теперь открываем /etc/knockd.conf.
Важный нюанс: вам нужно указать свой сетевой интерфейс (например, eth0 или enp0s3) и заменить команду добавления правила с -A INPUT (добавить в конец) на -I INPUT 1 (вставить первым правилом), иначе фаервол его проигнорирует из-за предыдущих запретов.
Включаем автозапуск Открываем файл /etc/default/knockd, находим строчку START_KNOCKD=0 и меняем её на 1. Запускаем:
sudo systemctl start knockd
Как теперь заходить на сервер? (Стучим с клиента) На свой рабочий компьютер (клиент) тоже ставим утилиту:
sudo apt install knock
Теперь, когда нам нужен доступ к серверу (допустим, его IP 192.168.1.6), мы сначала «стучим» правильную комбинацию:
knock 192.168.1.6 7000 8000 9000
Порт открылся для нашего IP. Спокойно заходим:
ssh admin@192.168.1.6.
После завершения работы закрываем за собой дверь обратной комбинацией:
knock 192.168.1.6 9000 8000 7000
Итог Метод не заменяет SSH-ключи, но работает как отличный дополнительный слой безопасности. SSH полностью скрыт от сканеров портов, логи чистые, а злоумышленники не могут даже начать перебор.
Надеюсь, кому-то эта шпаргалка сэкономит время. Я собираю подобные полезные сниппеты, команды и короткие мануалы по Linux и администрированию в свой Telegram-канал [Linux для Админов и DevOps]. Буду рад видеть там коллег по цеху, заходите!
Вы арендовали 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-окружения:
Важно: откройте вторую сессию и убедитесь, что вход под 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:
Python 3 уже предустановлен в Ubuntu 22.04. Для работы с виртуальными окружениями добавьте:
apt install -y python3-pip python3-venv
Docker как универсальный вариант
Если проект допускает контейнеризацию, Docker избавляет от ручного управления зависимостями: приложение с окружением упаковывается в образ и запускается одинаково на любом хосте. Для продакшен-среды предпочтительнее установка через официальный apt-репозиторий Docker: так проще контролировать источник пакетов и обновления. Официальный скрипт тоже добавляет репозиторий Docker Engine и ставит актуальную версию, но его лучше использовать для быстрого старта или тестового окружения:
Добавьте пользователя в группу 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:
Certbot изменит конфигурацию Nginx, добавит HTTPS-блок с путями к сертификату и предложит настроить редирект с HTTP на HTTPS. Обновление сертификата происходит через cron или systemd timer без вашего участия. Сертификат Let's Encrypt действует 90 дней. Проверьте, что продление пройдёт без ошибок:
certbot renew --dry-run
Автозапуск сервисов. Пакеты, установленные через apt, как правило, включаются в автозапуск автоматически. Для собственного приложения создайте unit-файл:
Каждая установка 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-сервера с нуля требует внимания прежде всего на этапе безопасности: шаги, пропущенные здесь, могут позже дать о себе знать. Не жалейте времени на проверку каждого пункта чек-листа до открытия сервиса пользователям.
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. Его необходимо добавить в белый список:
Проверьте, что на сервере есть пользователь с sudo. Работать от root не рекомендуется: ошибка в конфиге или случайная команда могут повлиять на весь сервер.
Чек-лист перед установкой
• SSH-доступ работает; запасная сессия открыта или есть KVM/VNC-консоль в панели провайдера
• Если используется 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, фильтр можно проверить так:
Самоблокировка при настройке. Две-три ошибки в пароле – и ваш 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 проверьте совпадения фильтра:
Если 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 сервера начинается с таких базовых вещей – ещё до деплоя приложения. Боты не ждут, пока вы закончите.
VPS куплен, SSH-сессия открыта. У многих здесь возникает пауза: непонятно, с чего начать и под какую задачу настраивать VPS-сервер. Разберём пять практических сценариев того, как использовать VPS: хостинг сайтов, запуск ботов, размещение API, мониторинг и автоматизация. У каждого – конкретный стек, ориентиры по ресурсам и нюансы, которые лучше знать до начала настройки, а не в процессе. Реальные требования зависят от сложности проекта, нагрузки, выбранного стека и числа одновременно работающих сервисов.
Что даёт VPS и почему его берут
VPS-сервер отличается от shared-хостинга тремя вещами. Первое – у вас есть заявленные параметры тарифа: CPU, RAM, диск и сетевой канал. На качество работы всё ещё может влиять общая инфраструктура хоста, но изоляция здесь выше, чем на shared-хостинге. Второе – root-доступ: можно установить любой софт, выбрать версию PHP, настроить nginx под конкретную задачу. Третье – VPS-сервер работает круглосуточно без вашего участия, независимо от состояния вашего компьютера или интернета. На shared-хостинге чужая нагрузка может повлиять на соседние сайты, если провайдер плохо ограничивает ресурсы аккаунтов.
От облачных функций (AWS Lambda, Yandex Cloud Functions) VPS отличается предсказуемостью: нет cold-start задержек, нет тарификации за каждый вызов функции, нет ограничений по времени выполнения. Для задач с постоянными процессами: баз данных, ботов, мониторинга – VPS часто проще и предсказуемее, чем serverless-архитектура с оплатой за вызов. При низкой или нерегулярной нагрузке serverless может оказаться дешевле.
Базовая подготовка: что сделать сразу после покупки
Настройка VPS начинается не сразу с рабочего проекта, а с базовой конфигурации. Базовая настройка снижает риск классических проблем: открытого SSH, устаревших пакетов, лишних портов и нехватки памяти при пиковых нагрузках. Пропуск таких шагов может увеличить риск потерять сервер из-за брутфорса или случайной команды от root.
• SSH-ключи. Сгенерируйте пару через ssh-keygen, передайте публичный ключ через ssh-copy-id, отключите аутентификацию по паролю в sshd_config.
• Пользователь без root. Создайте аккаунт с правами sudo. Работа от root в продакшене – плохая практика. Одна ошибка может стоить всей системы.
• Firewall. Откройте в UFW SSH-порт, 80 и 443, если они нужны вашему сценарию. Если используется стандартный SSH-порт, это 22. Fail2ban добавит защиту от брутфорса на SSH.
• Swap. Если RAM меньше 2 ГБ, добавьте swap-файл на 1–2 ГБ. Он снижает риск OOM при пиковой нагрузке, но при активном использовании может ухудшить производительность.
• Обновления. Запустите sudo apt update && apt upgrade сразу после входа на сервер, до начала любой работы.
Сценарий 1. Хостинг сайтов и веб-проектов
Хостинг на VPS оправдан, когда shared-хостинг перестал справляться: нет нужной версии PHP или Python, не хватает памяти, несколько доменов требуют разных настроек или нестандартного ПО. На VPS больше свободы в настройке: можно выбрать версии ПО, настроить веб-сервер, подключить нужные модули и управлять несколькими проектами независимо. Именно поэтому многие переезжают сюда с первого же конфликта с техподдержкой shared-хостинга.
Стек: Nginx как веб-сервер и reverse proxy, PHP-FPM для WordPress или других CMS, MySQL или PostgreSQL как база данных. Для статических сайтов (Hugo, Astro, Next.js SSG) Nginx работает без интерпретатора, нагрузка минимальная. SSL – Let’s Encrypt через Certbot, бесплатно и с автообновлением. Один Nginx обслуживает несколько доменов через server blocks.
Порты СУБД (3306, 5432) наружу не открывайте: приложение обращается к базе внутри сервера. Для сайта с умеренным трафиком часто хватает 1 vCPU и 1–2 ГБ RAM; для тяжёлых CMS с кешированием, большим числом плагинов или высокой посещаемостью лучше закладывать 2 vCPU и 2–4 ГБ. Добавьте Redis для кеша сессий: это может снизить нагрузку на базу данных и улучшить отклик WordPress при росте трафика.
Сценарий 2. Запуск Telegram- и Discord-ботов
Боту часто нужно работать круглосуточно и хранить состояние: настройки пользователей, историю диалогов, очереди задач. Локальная машина для этого не подходит, а облачные функции удобны в основном для коротких команд без постоянного процесса. VPS решает обе задачи: бот постоянно запущен, а база данных может работать рядом на том же сервере.
Стек для Telegram: Python + aiogram, управление процессом через systemd, хранение состояния в SQLite или PostgreSQL. SQLite подходит для небольших ботов с умеренной нагрузкой, но при высокой конкуренции запросов или запуске нескольких экземпляров приложения лучше сразу выбирать PostgreSQL. Для Discord – Node.js + discord.js, для управления процессом удобен PM2. Redis подойдёт для быстрого хранения временных данных и очередей.
Для большинства продакшен-сценариев с Telegram-ботами удобен webhook-режим: сервер сам получает обновления, не опрашивая API Telegram. Для webhook нужен домен с HTTPS. Polling тоже остаётся корректным вариантом для небольших проектов: он проще в запуске и не требует домена с HTTPS. Простой бот без базы данных умещается на 1 vCPU и 1 ГБ RAM. Бот со сложными очередями, вызовами внешних API и ML-моделями потребует минимум 2 ГБ RAM. Через systemd настраивается автозапуск: после перезагрузки сервера бот поднимется сам.
Сценарий 3. Размещение API и бэкендов
VPS-сервер даёт API постоянный адрес, свою базу данных и полный контроль над окружением, без vendor lock-in и без ограничений по времени выполнения запросов. Это важно для бэкендов с длительными операциями: обработкой файлов, парсингом, генерацией отчётов.
Стек: FastAPI (Python) или Express.js (Node.js) для REST, Docker для изоляции сервисов, Nginx или Traefik как reverse proxy. Приложение слушает на localhost, наружу открыты только 80 и 443. GraphQL – Strawberry (Python) или Apollo Server (Node.js). Для автодеплоя – GitHub Actions: пуш в main запускает пересборку и перезапуск контейнера.
Порты базы данных держите внутри Docker-сети, не открывайте наружу: бэкенд обращается к базе по имени сервиса внутри сети. Для API с базой данных начинайте с 2 vCPU и 2–4 ГБ RAM. При росте нагрузки Docker и reverse proxy позволяют масштабировать сервисы без переписывания архитектуры. Traefik автоматически получает и обновляет SSL-сертификаты через Let’s Encrypt при настроенном ACME, поэтому отдельная настройка Certbot не нужна.
Сценарий 4. Мониторинг и сбор метрик
Сервер мониторинга должен работать независимо от мониторируемой инфраструктуры. Если основной сервер упал, система мониторинга должна увидеть это первой и отправить алерт, а не упасть вместе с ним. Отдельный небольшой VPS для мониторинга решает эту задачу.
Uptime Kuma – удобный инструмент с веб-интерфейсом: отслеживает HTTP-статусы, время ответа, порты TCP, отправляет алерты в Telegram, Slack и другие каналы. Разворачивается через Docker за несколько минут и обычно помещается в небольшой VPS. Для лёгкого мониторинга часто достаточно 512 МБ RAM, но потребление зависит от числа проверок и их типа.
Prometheus + Grafana – полный стек для сбора метрик, построения дашбордов и настройки алертов. Prometheus собирает данные с exporters, Grafana строит графики. Оба сервиса вместе могут потреблять примерно 600–1000 МБ RAM в покое, но фактическое потребление зависит от retention, числа targets и объёма метрик. Под этот сценарий обычно стоит закладывать не меньше 2 ГБ RAM. Node Exporter собирает системные метрики хоста – CPU, RAM, диск, сеть; добавьте его на каждый наблюдаемый сервер. Алерты в Telegram настраиваются через Alertmanager за несколько минут.
Сценарий 5. Автоматизация и рабочие процессы
Сервер не выключается. Это главное преимущество VPS для автоматизации: cron-задачи запускаются по расписанию в любое время суток, скрипты работают столько, сколько нужно, без ограничений по времени выполнения и без зависимости от того, включён ли ваш компьютер.
n8n – self-hosted инструмент для визуальной автоматизации, аналог Zapier на вашем сервере. Разворачивается через Docker, а потребление памяти может начинаться примерно от 500 МБ RAM и расти с числом workflow, интеграций и выбранной БД. Данные о задачах хранятся в БД, поэтому volume для персистентности обязателен. Настроенный VPS с n8n заменяет подписку на облачные сервисы автоматизации и не передаёт данные третьим сторонам.
Для простых задач достаточно cron: бэкап файлов, отправка отчётов, очистка временных директорий, синхронизация данных между сервисами.
Как выбрать свой сценарий и не перегрузить сервер
Примерные ориентиры по ресурсам под основные задачи:
• Сайт или бот без тяжёлых фоновых задач: 1 vCPU, 1–2 ГБ RAM
Несколько сценариев на одном VPS совместить возможно, но требования зависят от сложности проекта, выбранного стека, объёма трафика и числа одновременно работающих сервисов. Для простого сайта, небольшого бота и лёгкого мониторинга 2 ГБ RAM могут быть достаточны, если нет тяжёлых фоновых задач. Docker упрощает совмещение: каждый сервис в своём контейнере, порты не конфликтуют, ресурсы лимитируются. Постоянная загрузка CPU или RAM выше 80% может стать сигналом для апгрейда. Начните с минимального тарифа и расширяйте по мере роста – большинство провайдеров позволяют сделать это без пересоздания сервера.
Чек-лист: что настроить на VPS под любой сценарий
1. SSH-ключи настроены, аутентификация по паролю отключена
2. Создан sudo-пользователь, работа от root прекращена
3. Система обновлена: sudo apt update && apt upgrade
4. UFW включён: открыты только нужные входящие порты, например SSH-порт, 80 и 443 для веб-сценариев
5. Swap настроен при RAM < 2 ГБ
6. Автоматические снапшоты или бэкапы настроены
7. Домен привязан, HTTPS работает через Let’s Encrypt
8. Базовый мониторинг: uptime и диск под контролем
VPS это не готовый продукт, а платформа для разных задач: сайта, бота, API, мониторинга или автоматизации. Начните с одного сценария, не пытайтесь запускать всё сразу. Сначала закройте базовую настройку из чек-листа: SSH-ключи, firewall, обновления, бэкапы и мониторинг. После этого разверните минимальную рабочую версию сервиса и расширяйте конфигурацию по мере роста нагрузки.
Облачный инстанс создан, SSH-доступ работает, и первое, что хочется сделать, это запустить приложение. Но новый сервер в этот момент уязвим: root-доступ может быть разрешён, часть пакетов требовать обновления, firewall ещё не настроен, мониторинга нет. Автоматические сканеры находят новые IP-адреса за минуты и начинают перебор паролей ещё до того, как вы откроете второй терминал.
Настройка облачных серверов перед нагрузкой – это четыре конкретных блока: сеть, пользователи и доступ, firewall, мониторинг. Каждый занимает от десяти минут до получаса. Пропустить любой – значит получить дыру в безопасности и эксплуатации.
Разберём все четыре блока по порядку на примере Ubuntu 22.04 LTS. Все команды воспроизводимы и проверены. Порядок шагов важен: каждый следующий опирается на предыдущий. Не запускайте приложение до настройки firewall: незащищённый VPS с открытым SSH быстро попадает под автоматический перебор паролей.
С чего начинается настройка облачного сервера?
Терминал Ubuntu 22.04 с обновлением пакетов, проверкой синхронизации времени, запущенных служб и свободного места на диске.
Прежде чем двигаться дальше, нужно привести систему в актуальное состояние. Образы облачных провайдеров зачастую собираются заранее и поставляются с пакетами недельной или месячной давности. Первое же обновление нередко закрывает десятки CVE, включая критические в OpenSSH и ядре. Выполните:
apt update && apt upgrade -y
Если обновление затронуло ядро – перезагрузите сервер. После перезагрузки убедитесь, что соединение восстановилось, и продолжайте.
Следующий шаг – проверить синхронизацию времени. Расхождение системных часов ломает TLS-рукопожатие, сбивает JWT-токены и делает логи бесполезными при сравнении событий с разных хостов. На Ubuntu 22.04 за это отвечает systemd-timesyncd. Проверьте его статус:
timedatectl status
В строке NTP service должно стоять active. Если нет – включите вручную:
systemctl enable --now systemd-timesyncd
Также сразу посмотрите, что уже запущено на сервере, и сколько свободно дискового пространства. На минимальном образе Ubuntu 22.04 запущено около 25–30 системных сервисов. Если их заметно больше, образ уже преднастроен провайдером:
Если корневой раздел занят более чем на 80%, разберитесь с этим до любых дальнейших шагов: нехватка места ломает обновления пакетов, ротацию логов и запись временных файлов.
Настройка сети на облачном сервере
Терминал Ubuntu 22.04 с проверкой сети, настройкой статического IP через Netplan и изменением имени облачного сервера.
Начните с просмотра текущего состояния сетевых интерфейсов. Две команды дают полную картину: какие интерфейсы подняты, какие IP назначены и куда идёт маршрут по умолчанию.
ip a
ip route show
В выводе ip a найдите интерфейс с публичным IP-адресом – обычно это ens3, ens4 или eth0, в зависимости от провайдера. Запомните его имя: оно понадобится в конфигурации netplan.
На Ubuntu 22.04 сетевые настройки управляются через netplan: конфигурационные файлы лежат в /etc/netplan/. Если провайдер использует cloud-init для автоматической конфигурации сети, в /etc/netplan/ уже может быть файл 50-cloud-init.yaml. Его можно редактировать, но изменения могут быть перезаписаны cloud-init при следующей перезагрузке или пересоздании конфигурации. Безопаснее создать отдельный файл с более высоким приоритетом, например 99-custom.yaml: числа в именах файлов определяют порядок применения, большее число применяется последним и переопределяет предыдущее.
Пример конфигурации со статическим IP (замените значения на реальные):
Терминал Ubuntu 22.04 с применением Netplan и проверкой IP-адреса, маршрута, DNS и внешнего соединения.
Директива addresses задаёт статический IP с маской. routes описывает маршрут по умолчанию – шлюз, через который идёт весь трафик. nameservers – DNS-серверы; при необходимости укажите серверы провайдера или вашего корпоративного резолвера.
Перед применением проверьте конфигурацию через netplan try: он применит настройки и автоматически откатит их через 120 секунд, если вы не подтвердите. Это страховка от потери соединения. Если всё в порядке – зафиксируйте:
netplan apply
Последний штрих – задать осмысленное имя хоста. Понятное имя упрощает навигацию в логах и мониторинге, особенно когда серверов несколько:
hostnamectl set-hostname web-prod-01
echo "127.0.1.1 web-prod-01" >> /etc/hosts
Диагностика сетевых проблем
Терминал Ubuntu 22.04 с успешной проверкой подключения, DNS-серверов и открытого SSH-порта.
Если после применения netplan что-то пошло не так, три команды помогут локализовать проблему:
Если ping проходит, а dig не разрешает имена – проблема в DNS. На Ubuntu 22.04 DNS управляется через systemd-resolved. Его состояние:
resolvectl status
Если dig не установлен, установите пакет:
apt install bind9-dnsutils -y
В выводе resolvectl смотрите секцию DNS Servers для каждого интерфейса. Если серверы не отображаются или стоит 127.0.0.53, убедитесь, что в файле netplan прописан раздел nameservers, и заново примените конфигурацию.
Команда ss -tulpn полезна не только при диагностике сети: её стоит запускать после каждого шага настройки, чтобы убедиться – ничего лишнего не появилось на открытых портах.
Управление пользователями и доступом (users)
Постоянно работать от root – плохая практика. Опечатка в пути к файлу под root может уничтожить данные без возможности отмены. Любая уязвимость в запущенном от root приложении даёт атакующему полный контроль над системой. При командной работе аудит затруднён: в логах нет разграничения между разными администраторами.
Создайте пользователя для повседневной работы. В Ubuntu удобнее использовать adduser: команда создаёт домашнюю директорию, настраивает оболочку и интерактивно запрашивает пароль.
adduser <name>
usermod -aG sudo <name>
Команда usermod -aG sudo <name> добавляет пользователя в группу sudo. На Ubuntu эта группа по умолчанию имеет право выполнять любые команды через sudo без изменения файла /etc/sudoers. Проверьте, что всё работает не закрывая текущую сессию root:
su - <name>
sudo whoami # должно вывести: root
Для входа по SSH без пароля сгенерируйте ключ на локальной машине и скопируйте публичную часть на сервер. Тип ed25519 предпочтительнее rsa:
# На локальной машине
ssh-keygen -t ed25519 -C "user@pc_name"
ssh-copy-id <name>@<IP_сервера>
Два терминала: создание пользователя deploy и проверка sudo на Ubuntu-сервере, генерация и копирование SSH-ключа с локального компьютера.
Два терминала: создание пользователя deploy и проверка sudo на Ubuntu-сервере, генерация и копирование SSH-ключа с локального компьютера.
Если нужно добавить публичный ключ вручную – создайте структуру директорий самостоятельно. Разрешения важны: 700 на директорию, 600 на файл:
После настройки ключа войдите в новый сеанс под пользователем через SSH. Убедитесь, что аутентификация по ключу работает, и только после этого переходите к следующему шагу.
Безопасные настройки SSH
Настройка SSH на сервере сводится к нескольким директивам в /etc/ssh/sshd_config. Ключевой принцип: ограничить поверхность атаки. Откройте файл:
nano /etc/ssh/sshd_config
Перед отключением парольного входа не закрывайте текущую root-сессию и убедитесь, что вход по SSH-ключу работает в новом терминале. Если в конфиге или ключах есть ошибка, SSH-доступ можно потерять, и восстанавливать его придётся через консоль провайдера, VNC/KVM или rescue mode.
Внесите следующие изменения:
# Запретить прямой вход под root
PermitRootLogin no
# Только ключи; пароли не принимать
PasswordAuthentication no
PubkeyAuthentication yes
# Разрешить вход только указанному пользователю
AllowUsers deploy
# Сократить время и попытки аутентификации
MaxAuthTries 3
LoginGraceTime 30
PermitRootLogin no закрывает наиболее атакуемый вектор: большинство автоматических сканеров перебирают именно root. PasswordAuthentication no убирает парольный вход полностью после этого единственным способом войти остаются SSH-ключи. AllowUsers deploy добавляет дополнительный слой: даже если на сервере появятся другие пользователи, по SSH они войти не смогут.
Директива AllowUsers особенно полезна при командной работе: она задаёт явный белый список тех, кто может войти по SSH. Новый пользователь, не включённый в список, не получит доступ даже с корректным ключом.
Перед перезапуском проверьте синтаксис конфига, ошибка в директиве заблокирует вас при работающем соединении:
sshd -t # пустой вывод означает: конфиг корректен
systemctl restart ssh
Откройте новый терминал и убедитесь, что вход по ключу работает, прежде чем закрывать текущую сессию. Это самая частая ошибка при настройке SSH: отключают парольный вход до того, как проверяют, что ключ принимается.
Дополнительно: смена стандартного порта 22 на нестандартный снижает количество автоматических сканирований и шум в логах. Если решите сменить, сначала откройте новый порт в UFW, затем измените Port в конфиге и перезапустите sshd, не наоборот.
Настройка firewall: UFW и iptables
UFW – стандартный инструмент управления firewall на Ubuntu. Он даёт простой интерфейс для настройки правил, а конкретный backend зависит от версии Ubuntu и конфигурации системы: это может быть iptables-совместимый слой или nftables. На новом сервере UFW установлен, но часто не активирован.
Настройка облачных серверов без активного firewall оставляет все порты открытыми. Порядок имеет значение: сначала разрешить SSH, потом включать UFW, иначе заблокируете собственное соединение:
ufw default deny incoming # всё входящее – запрещено по умолчанию
Если SSH настроен на нестандартный порт, замените 22 на него. Правило ufw status verbose покажет активные разрешения и политику по умолчанию – полезно сверить сразу после включения.
Для отладки сначала используйте вывод UFW:
ufw status verbose
Если нужно посмотреть низкоуровневые правила, используйте инструмент, который соответствует backend системы:
iptables -L -n --line-numbers
или:
nft list ruleset
На Ubuntu 22.04 UFW может работать через iptables-совместимый backend или nftables. Поэтому не стоит ориентироваться только на одну цепочку INPUT: фактическое расположение правил зависит от backend и конфигурации системы.
Для автоматической блокировки IP-адресов после нескольких неудачных попыток входа установите fail2ban:
apt install fail2ban -y
systemctl enable --now fail2ban
Создайте файл пользовательских настроек /etc/fail2ban/jail.local. Редактировать jail.conf напрямую не стоит – он перезаписывается при обновлении пакета:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
[sshd]
enabled = true
При таких настройках IP блокируется на час после пяти неудачных попыток входа за десять минут. Перезапустите сервис и проверьте статус jail:
systemctl restart fail2ban
fail2ban-client status sshd
В выводе Currently banned покажет количество активных блокировок. Разбанить конкретный IP можно командой fail2ban-client set sshd unbanip <IP>. Кроме SSH, fail2ban поддерживает джейлы для nginx, apache2 и postfix. Они конфигурируются аналогично, добавлением отдельных секций в jail.local.
Мониторинг облачного сервера
Мониторинг сервера Linux без агентов начинается со встроенных инструментов. Для быстрой диагностики их вполне хватает:
Для постоянного мониторинга с метриками и алертами нужен агент. Выбор зависит от контекста: если в инфраструктуре уже есть Prometheus, оптимален node_exporter – он экспортирует более 800 метрик ОС с минимальным потреблением ресурсов (около 20–50 MB RAM):
apt install prometheus-node-exporter -y
systemctl enable --now prometheus-node-exporter
Агент слушает на порту 9100 и отдаёт метрики в формате Prometheus по адресу http://<IP>:9100/metrics. Добавьте этот адрес как scrape target в конфигурацию Prometheus, и метрики появятся в Grafana. Не открывайте порт 9100 наружу: ограничьте доступ через security group, UFW или приватную сеть Prometheus.
Если Prometheus ещё нет – Netdata даёт готовый интерактивный дашборд из коробки, без дополнительной инфраструктуры:
apt install netdata -y
systemctl enable --now netdata
Netdata слушает на порту 19999. Настройте SSH-туннель для разового просмотра или nginx с basic auth для постоянного доступа. Netdata потребляет от 100 MB RAM, на VPS с 1 GB это существенная разница по сравнению с node_exporter.
Алерты настраиваются поверх метрик. Для node_exporter используйте Prometheus Alertmanager: правила на PromQL, уведомления в Slack, email или PagerDuty. Для Netdata встроена собственная система уведомлений – настройте её в /etc/netdata/health_alarm_notify.conf. На практике для старта хватает трёх порогов: CPU load выше числа vCPU, диск выше 85%, список упавших сервисов непуст.
Что мониторить в первую очередь
На только что настроенном сервере важны шесть базовых показателей:
CPU load average – если значение устойчиво превышает количество vCPU в течение 5–10 минут, сервер перегружен. htop или uptime показывают три скользящих средних: за 1, 5 и 15 минут.
Память – при использовании свыше 85% система начинает активно использовать swap, что резко увеличивает latency. Для веб-серверов и баз данных это ощутимо. Контролируется через free -h.
Диск – заполненность свыше 80% блокирует запись логов, временных файлов и данных приложений. Дополнительно следите за iostat (из пакета sysstat) – высокий await при умеренной нагрузке указывает на проблемы с хранилищем.
Failed services – systemctl --failed выводит список упавших юнитов. Перед выводом в продакшен этот список должен быть пустым.
Auth log – journalctl -u ssh --since "1 hour ago" покажет активность после настройки fail2ban. Строки Failed password могут продолжать появляться до бана или с других IP-адресов. Важнее проверить, что fail2ban видит попытки входа и добавляет нарушителей в jail; строки Accepted publickey должны соответствовать вашим успешным входам.
Открытые порты – ss -tulpn один раз после каждого изменения конфигурации. Всё, что слушает наружу, должно быть в явном белом списке UFW.
Чек-лист финальной проверки
Пройдитесь по списку перед открытием сервера под рабочий трафик:
• Непривилегированный пользователь создан, добавлен в sudo
• Перед отключением парольного входа проверен вход по SSH-ключу в новом терминале
• PasswordAuthentication no и PermitRootLogin no прописаны в sshd_config
• UFW включён: ufw status verbose показывает только нужные порты
• fail2ban запущен: fail2ban-client status sshd показывает активный jail
• Пакеты обновлены: apt upgrade -y выполнен, при обновлении ядра – перезагрузка
• NTP активен: timedatectl показывает NTP service: active
• Мониторинг-агент запущен и метрики доступны
• Бэкапы настроены через панель провайдера или отдельный инструмент
• systemctl --failed возвращает пустой список
• Имя хоста и /etc/hosts настроены корректно
Четыре блока: сеть, пользователи, firewall, мониторинг – это минимальная конфигурация, без которой облачный сервер не готов к продакшену. Пропуск любого из этих шагов рано или поздно даёт о себе знать: либо взломом, либо аварией без видимой причины, либо часами поиска проблемы в логах.
Сохраните этот гайд и пройдитесь по нему при следующем деплое нового инстанса. В блоге Aeza регулярно выходят материалы по администрированию и безопасности серверов – подпишитесь, чтобы не пропускать NETTOWN5 обновления.
Каждый, кто хоть раз подключался к новому серверу по SSH, знаком с этим интерактивным ритуалом:
The authenticity of host example. com can't be established. ED25519 key fingerprint is SHA256:... Are you sure you want to continue connecting (yes/no)?
И почти все бездумно вводят одинаковый ответ:
yes
Эта модель называется TOFU или Trust On First Use — доверие при первом использовании.
Через несколько месяцев или даже лет по тому же адресу может прилететь уже совсем другое сообщение:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
И тут сценарий в большинстве случаев тоже простой и бестолковый:
ssh-keygen -R example. com ssh example. com yes
Вот и все, можно снова не беспокоиться, проблема решена.
Или нет?
До недавнего времени я относился к файлу known_hosts примерно так же. Ну какой-то там служебный кэш SSH. Если что-то пошло не так - удалил запись, подключился заново, живем дальше.
Но однажды я поймал себя на простой как два рубля мысли.
known_hosts - это вообще не кэш.
Это база доверенных идентичностей серверов.
Когда SSH спрашивает:
Вы уверены, что хотите доверять этому серверу?
он сохраняет ваш ответ именно в known_hosts. И потом годами использует этот файл как единственный источник истины, чтобы понимать, разговариваете вы с тем же сервером или с кем-то совершенно другим.
Получается интересная ситуация.
Один из важнейших механизмов безопасности SSH хранится в обычном текстовом файле.
При этом вокруг него почти нет инструментов.
Где заканчивается OpenSSH
Давайте посмотрим, что OpenSSH умеет делать со своей собственной базой доверия.
автоматически добавить новую запись при первом подключении
удалить запись (ssh-keygen -R)
найти запись (ssh-keygen -F)
захэшировать файл (ssh-keygen -H)
И, по большому счёту, на этом его полномочия всё.
Если вы работаете с десятками или сотнями серверов, через несколько лет в known_hosts накапливаются сотни записей.
И неожиданно оказывается, что OpenSSH почти не помогает ответить на самые обычные вопросы.
Какие серверы уже давно не существуют?
Какие ключи изменились?
Есть ли дубликаты?
Какие записи используют устаревшие алгоритмы?
Кому я доверяю прямо сейчас?
И начинается дурдом с grep, awk, sed.
А мой коллега американец достает припасенную пачкау shell-скриптов и с умным видом делает вид, что (его цитата) shoveling shit)
Меня это искренне удивило.
SSH существует уже больше тридцати лет. Это один из самых распространённых сетевых протоколов в мире.
Но его модель доверия практически заканчивается сразу после первого yes.
Создать доверие - пожалуйста. Поддерживать его - уже без меня.
А как вообще SSH получает host key?
Стало интересно, как именно клиент получает публичный ключ сервера.
Мне всегда казалось, что для этого нужно установить полноценную SSH-сессию, договориться о шифровании, пройти аутентификацию и только потом получить нужную информацию.
Оказалось, все гораздо прозаичнее.
Во время подключения происходит примерно такая последовательность:
Сначала стороны просто обмениваются строками версии вроде
SSH-2.0-OpenSSH_10.0
Затем договариваются о поддерживаемых алгоритмах.
И наконец клиент отправляет `SSH_MSG_KEX_ECDH_INIT`.
Самое интересное происходит в ответном сообщении.
`SSH_MSG_KEX_ECDH_REPLY` содержит:
host key сервера
временный публичный ключ сервера
криптографическую подпись
Именно здесь клиент вычисляет фингерпринт, сравнивает его с known_hosts и принимает решение - продолжать соединение или нет.
Что меня удивило больше всего - все это происходит ещё до аутентификации пользователя.
Никаких паролей. Никаких приватных ключей. Никакого shell. Никакой открытой SSH-сессии.
И это абсолютно логично.
Host key существует именно для того, чтобы клиент убедился, с кем он разговаривает, прежде чем отправлять хоть какие-либо секреты.
Получается, что если цель - просто проверить идентичность сервера, то после получения `SSH_MSG_KEX_ECDH_REPLY` соединение можно сразу закрывать.
Все необходимое уже получено.
От исследования к инструменту
Когда я это понял, стало очевидно еще кое-что.
Чтобы проверить host key сервера, как я уже упомянул выше, не нужен полноценный SSH-клиент. Ни шелл, ни аут. Не нужна большая часть SSH вообще.
Нужен лишь небольшой кусок протокола.
Именно из этого наблюдения постепенно вырос небольшой CLI проект, который я назвал khm (known hosts manager).
Изначально он вообще писался для себя.
Мне хотелось иметь возможность быстро ответить на вопросы, на которые OpenSSH почему-то не отвечает.
изменились ли ключи у уже известных серверов
есть ли мусор и дубликаты в known_hosts
чем отличаются два файла после миграции инфраструктуры или ротации ключей
что вообще я имею на сегодняшний день
Постепенно стало понятно, что проблема гораздо шире, чем казалось сначала.
На удивление много людей воспринимают known_hosts как временный файл, который можно удалить при первой ошибке.
Хотя на самом деле именно он определяет, каким серверам ваш компьютер доверяет прямо сейчас.
Например, именно такого вывода мне всегда не хватало в OpenSSH:
$ khm verify --all
OK github. com
OK gitlab. com
CHANGED old. example. com
UNREACHABLE backup. example. com
4 hosts • 2 OK • 1 changed • 1 unreachable
Не список ключей. Не тупой, подверженный человеческому фактору, вывод grep, а простой ответ на простой вопрос:
Все ли ещё соответствует тому, чему я доверял раньше?
Вместо заключения
Пока я работал над этим проектом, самым неожиданным открытием оказался вовсе не SSH-протокол.
Меня удивило отношение к known_hosts. Мое в том числе.
Мы привыкли считать его временным кэшем, который можно без сожаления удалить при первом предупреждении SSH.
Но если посмотреть внимательнее, это единственная локальная база доверенных идентичностей серверов, которой пользуется OpenSSH.
И как только начинаешь воспринимать ее именно так, становится удивительно, насколько мало вокруг нее существует инструментов.
Именно поэтому появился khm.
Не как ещё один SSH-клиент. И не как замена OpenSSH.
А как попытка сделать чуть удобнее одну маленькую, но, как мне кажется, незаслуженно забытую часть его модели доверия.
Исходный код проекта, бинарные сборки и документация доступны в репо: