MHOSTMHOST

Чеклист базовой защиты VPS

Свежий VPS по умолчанию настроен на удобство, а не на защиту: root доступен по паролю, файрвол выключен, автообновлений нет. Этот чеклист закрывает восемь базовых дыр за один заход — после него сервер станет заметно устойчивее к автоматическому сканированию и перебору паролей, которые не прекращаются ни на одном публичном IP-адресе в интернете.

Что понадобится

  • VPS mHost на Ubuntu 22.04/24.04, Debian 11/12 или AlmaLinux/Rocky Linux 8/9.
  • Доступ по SSH под root — на новом сервере обычно только так.
  • Доступ к панели VMmanager 6 — как подстраховка на случай, если ошибётесь с firewall или SSH и потеряете удалённый доступ: в панели есть консоль сервера прямо из браузера, без SSH. Если ещё не заходили — начните со статьи «Как войти в VMmanager 6».
  • Час-полтора свободного времени: часть пунктов нужно проверять новым подключением, не закрывая старое.
Важно: проходите пункты в указанном порядке. При нарушении порядка шаги про SSH и firewall могут оборвать вам доступ к серверу — в каждом таком месте ниже есть отдельное предупреждение.

Чеклист целиком

Коротко — все восемь пунктов, каждый подробно разобран ниже:

  • Обновите систему — установите все доступные обновления пакетов.
  • Создайте пользователя с sudo — перестаньте работать под root постоянно.
  • Настройте SSH — вход по ключу вместо пароля, root по SSH отключён.
  • Включите firewall — ufw (Ubuntu/Debian) или firewalld (AlmaLinux/Rocky), запрет всего лишнего по умолчанию.
  • Поставьте fail2ban — автоматическая блокировка IP за перебор паролей.
  • Закройте неиспользуемые сервисы и порты — меньше слушающих портов — меньше поверхность атаки.
  • Включите автообновления безопасности — unattended-upgrades (Ubuntu/Debian) или dnf-automatic (AlmaLinux/Rocky).
  • Смените пароли по умолчанию — временный пароль root и пароли, оставшиеся от рецептов VMmanager.

Шаг 1. Обновите систему

Начинайте всегда с этого — часть уязвимостей закрывается именно обновлением пакетов, и остальные шаги чеклиста лучше выполнять уже на актуальной системе.

Ubuntu / Debian

bash
sudo apt update
sudo apt upgrade -y

Проверьте, не требуется ли перезагрузка (обычно после обновления ядра):

bash
[ -f /var/run/reboot-required ] && echo "Нужна перезагрузка" || echo "Перезагрузка не требуется"
Совет: файл /var/run/reboot-required создаёт пакет update-notifier-common — на Ubuntu он стоит по умолчанию, на Debian можно поставить отдельно (sudo apt install update-notifier-common). Если пакета нет — просто перезагрузите сервер после обновления, затронувшего ядро.

AlmaLinux / Rocky

bash
sudo dnf update -y

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

bash
sudo dnf install -y dnf-utils
needs-restarting -r
Совет: needs-restarting -r ничего не выводит и завершается без ошибки, если перезагрузка не нужна; если нужна — печатает Reboot is required.

Перезагрузите сервер, если это требуется:

bash
sudo reboot
Готово: обновление отработало без ошибок, ядро и пакеты — самой свежей доступной версии.

Шаг 2. Создайте пользователя с sudo вместо root

Работа под root день за днём — риск: любая ошибка в команде выполняется с полными правами, а компрометация единственной учётной записи сразу отдаёт весь сервер. Заведите отдельного пользователя с sudo и используйте его для повседневной работы.

Ubuntu / Debian

bash
sudo adduser admin
sudo usermod -aG sudo admin

AlmaLinux / Rocky

bash
sudo useradd -m -s /bin/bash admin
sudo passwd admin
sudo usermod -aG wheel admin

Замените admin на любое другое имя, если хотите, — дальше по статье используется именно оно.

Проверьте, что новый пользователь действительно получил права root:

bash
su - admin
sudo whoami

Команда sudo whoami спросит пароль пользователя admin (не root) и должна вывести root.

Готово: sudo whoami вернул root — пользователь admin полноценно работает через sudo.

Шаг 3. Настройте SSH: ключи и защита

Пароль можно подобрать перебором — SSH-ключ технически не подбирается. Дальше в шаге доступ под root по SSH отключается полностью, поэтому прежде чем продолжить, убедитесь, что вход по ключу под пользователем admin действительно работает.

Сгенерируйте пару ключей на своём компьютере (не на сервере):

bash
ssh-keygen -t ed25519 -C "you@example.com"

На вопрос о пути и passphrase можно просто нажать Enter — ключ сохранится в ~/.ssh/id_ed25519 (закрытый) и ~/.ssh/id_ed25519.pub (открытый).

Скопируйте открытый ключ на сервер пользователю admin:

bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub admin@203.0.113.10

Если ssh-copy-id недоступен (например, в Windows PowerShell без утилит OpenSSH), сделайте то же самое вручную:

bash
cat ~/.ssh/id_ed25519.pub | ssh admin@203.0.113.10 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Проверьте: ssh admin@203.0.113.10 теперь должен пускать без запроса пароля.

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

Отключите вход по паролю и вход под root — на сервере отредактируйте /etc/ssh/sshd_config:

bash
PasswordAuthentication no
PermitRootLogin no
Совет: если хотите оставить root доступным по SSH, но только по ключу, без пароля, — укажите PermitRootLogin prohibit-password вместо no.

Проверьте синтаксис конфигурации перед перезапуском — это дешевле, чем чинить сервер вслепую после ошибки:

bash
sudo sshd -t

Перезапустите SSH:

bash
# Ubuntu/Debian
sudo systemctl restart ssh

# AlmaLinux/Rocky
sudo systemctl restart sshd

Не закрывая текущую сессию, откройте новое окно терминала и проверьте вход под admin по ключу — закрывайте старую сессию, только убедившись, что всё работает.

Важно: если что-то пошло не так и SSH недоступен — восстановить доступ поможет консоль сервера в VMmanager 6, она открывается прямо в браузере и не зависит от SSH (см. «Как войти в VMmanager 6»).
Готово: вход по паролю и вход под root по SSH отключены, admin заходит по ключу.

Более глубокая защита SSH — нестандартный порт, AllowUsers, ограничение числа попыток — в статье «Усиление SSH».

Шаг 4. Включите firewall: ufw или firewalld

Firewall с политикой «запретить всё лишнее» — базовая защита от любых сервисов, которые вы не собирались открывать наружу.

Ubuntu / Debian (ufw)

bash
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw enable
sudo ufw status verbose
Важно: разрешите SSH (ufw allow 22/tcp) обязательно до ufw enable — иначе первое же новое подключение будет заблокировано, а с ним и вы сами. Если сменили порт SSH на нестандартный (см. «Усиление SSH») — открывайте именно его, а не 22.

AlmaLinux / Rocky (firewalld)

bash
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
Совет: на большинстве образов AlmaLinux/Rocky служба ssh уже разрешена в зоне по умолчанию — повторное добавление ничего не ломает, а лишь убеждает вас в этом наверняка.

Полный разбор команд ufw — открытие произвольных портов, просмотр и удаление правил — в статье «Файрвол ufw: порты».

Готово: ufw status verbose / firewall-cmd --list-all показывают, что входящие запрещены по умолчанию и разрешён только SSH.

Шаг 5. Поставьте fail2ban

ufw и firewalld решают, какие порты видны снаружи, но не мешают перебирать пароль на уже открытом порту SSH. fail2ban следит за логами и сам добавляет временный бан для IP, который слишком часто ошибается с паролем.

Ubuntu / Debian

bash
sudo apt install -y fail2ban

AlmaLinux / Rocky

fail2ban не входит в стандартные репозитории — сначала подключите EPEL:

bash
sudo dnf install -y epel-release
sudo dnf install -y fail2ban fail2ban-systemd fail2ban-firewalld
Совет: пакеты fail2ban-systemd и fail2ban-firewalld здесь не опциональны. На AlmaLinux/Rocky jail sshd по умолчанию читает журнал systemd, а не файл лога, — для этого нужны Python-биндинги из fail2ban-systemd. А банить IP fail2ban должен именно через firewalld — штатный файрвол этих дистрибутивов, — иначе бан будет числиться в статусе, но реально трафик не остановит; это настраивает fail2ban-firewalld.

Включите и запустите службу:

bash
sudo systemctl enable --now fail2ban

Настройки лучше не трогать в jail.conf — файл может быть перезаписан при обновлении пакета. Создайте jail.local:

bash
sudo nano /etc/fail2ban/jail.local
ini
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1

[sshd]
enabled  = true
bantime  = 1h
findtime = 10m
maxretry = 5
  • enabled — jail sshd в jail.conf выключен по умолчанию (кроме Debian/Ubuntu, где пакет сразу включает его через свой defaults-debian.conf); строка выше включает его явно и одинаково на всех дистрибутивах.
  • bantime / findtime / maxretry — на сколько банить, за какой промежуток считать попытки и сколько попыток допустимо, прежде чем забанить; значения выше строже настроек по умолчанию (bantime по умолчанию — 10m, здесь — час).
  • ignoreip — адреса, которые никогда не банятся; добавьте сюда через пробел свой статический IP, если он есть, — иначе рискуете забанить сами себя.

Примените конфигурацию:

bash
sudo systemctl restart fail2ban

Проверьте, что jail sshd активен:

bash
sudo fail2ban-client status
sudo fail2ban-client status sshd

Если нужно снять бан с IP-адреса раньше времени:

bash
sudo fail2ban-client set sshd unbanip 198.51.100.23
Готово: fail2ban-client status sshd показывает jail включённым, а разбанить нужный IP можно в любой момент одной командой.

Подробный разбор фильтров, действий и джейла recidive для злостных нарушителей — в статье «Fail2ban: защита от брутфорса».

Шаг 6. Закройте неиспользуемые сервисы и порты

Firewall закрывает порты снаружи, но лишний слушающий сервис на сервере — риск сам по себе: ошибка в правиле firewall, второй сетевой интерфейс или туннель — и то, что якобы было закрыто, окажется доступно. Меньше работающих сервисов — меньше того, что можно взломать.

Посмотрите, что вообще слушает порты:

bash
sudo ss -tulpn
  • -t / -u — TCP и UDP;
  • -l — только слушающие сокеты;
  • -p — какой процесс держит порт (нужен sudo, иначе имя процесса скрыто);
  • -n — показывать порты и адреса числом, не резолвить в имена.

Посмотрите, какие службы включены и запущены:

bash
systemctl list-units --type=service --state=running
systemctl list-unit-files --type=service --state=enabled

Частые кандидаты на отключение на голом VPS без десктопного окружения — если вы ими не пользуетесь: avahi-daemon, cups, rpcbind. Если у вас Debian/Ubuntu без собственного почтового сервера — локальный MTA (exim4 или postfix) обычно слушает только 127.0.0.1 и наружу не торчит, но проверить через ss не помешает.

Остановите и отключите автозапуск ненужной службы:

bash
sudo systemctl disable --now <служба>

Если сервис вообще не нужен — удалите пакет целиком:

bash
# Ubuntu/Debian
sudo apt purge <пакет>

# AlmaLinux/Rocky
sudo dnf remove <пакет>
Важно: отключайте только то, в чём точно уверены. Не трогайте ssh/sshd — без него вы потеряете доступ к серверу, — и любой сервис, который реально используете (веб-сервер, база данных и т. п.).

Проверьте результат повторным ss -tulpn — список слушающих портов должен стать короче и понятнее.

Готово: ss -tulpn показывает только те порты, которые вы осознанно используете.

Шаг 7. Включите автоматические обновления безопасности

Шаг 1 обновил систему один раз, здесь же обновления безопасности будут ставиться сами, без вашего участия, и дальше.

Ubuntu / Debian

bash
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

dpkg-reconfigure создаёт /etc/apt/apt.conf.d/20auto-upgrades с содержимым:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

Основная логика — в /etc/apt/apt.conf.d/50unattended-upgrades: по умолчанию оттуда ставятся только security-обновления, а не обновления версий пакетов.

Проверьте, что всё настроено, не дожидаясь реального запуска по расписанию:

bash
sudo unattended-upgrade -v --dry-run
Совет: если хотите, чтобы сервер сам перезагружался после обновлений, требующих перезагрузки, раскомментируйте в /etc/apt/apt.conf.d/50unattended-upgrades строки Unattended-Upgrade::Automatic-Reboot "true"; и Unattended-Upgrade::Automatic-Reboot-Time "02:00";. Без этого сервер сам не перезагрузится — не забывайте проверять шаг 1 вручную.

AlmaLinux / Rocky

bash
sudo dnf install -y dnf-automatic
sudo nano /etc/dnf/automatic.conf

В секции [commands]:

ini
[commands]
upgrade_type = security
apply_updates = yes

Включите таймер:

bash
sudo systemctl enable --now dnf-automatic.timer
Готово: systemctl status dnf-automatic.timer (AlmaLinux/Rocky) или apt-config dump APT::Periodic::Unattended-Upgrade (Ubuntu/Debian) показывают, что автообновления включены.

Шаг 8. Смените пароли по умолчанию

Временный пароль root, который mHost прислал в письме при активации сервера, — первое, что стоит сменить, если вы ещё не сделали этого при первом подключении:

bash
passwd

Как пользователь admin с sudo, вы можете сменить пароль и другому пользователю, включая root:

bash
sudo passwd root
Совет: раз root по SSH уже отключён (шаг 3), пароль root по-прежнему стоит держать длинным и уникальным — он ещё нужен для входа через локальную консоль VNC в VMmanager 6.

Если вы разворачивали ПО через готовый рецепт VMmanager 6 — некоторые из них оставляют собственный пароль по умолчанию (например, Zabbix: Admin/zabbix, Redmine: admin/admin) — смените и его сразу после первого входа в веб-интерфейс приложения. Полный список рецептов и их особенностей — в статье «Готовые рецепты VMmanager 6».

Готово: пароль root заменён на новый и уникальный, пароли по умолчанию у установленных приложений — тоже.

Что дальше

Восемь пунктов чеклиста выполнены — сервер прошёл базовую защиту. Дальше стоит разобрать каждую тему подробнее: «Файрвол ufw: порты» — полный разбор команд ufw; «Усиление SSH» — нестандартный порт, ограничение пользователей и попыток входа; «Fail2ban: защита от брутфорса» — фильтры и действия под другие сервисы, не только SSH.