Безопасность VPS на Ubuntu и Debian: памятка по защите сервера (SSH, UFW, Fail2ban)

Безопасность VPS на Ubuntu и Debian — памятка по защите сервера Безопасность
Пошаговая памятка по защите VPS и VDS на Ubuntu 22.04–26.04 и Debian 12/13: вход по SSH-ключу, запрет пароля и root, UFW, Fail2ban, автообновления и восстановление доступа.

Реклама. ООО «ТАЙМВЭБ.КЛАУД», ИНН 7810945525.

Timeweb

Безопасность VPS начинается в первые 15 минут после создания сервера: сразу после покупки на него уже стучатся боты, которые перебирают пароли к SSH. В этой памятке — минимальный набор мер для VPS и VDS на Ubuntu и Debian: обновления, отдельный пользователь, вход по SSH-ключу, запрет пароля и root, файрвол UFW и Fail2ban. Всё расставлено в таком порядке, чтобы на каждом шаге не потерять доступ к серверу.

Команды проверены на Ubuntu 22.04, 24.04, 26.04 и Debian 12, 13. Там, где системы отличаются (SSH через ssh.socket в новых Ubuntu, журналы в Debian 12), это отмечено отдельно. Памятка обновлена в сентябре 2026 года.

Безопасность VPS: быстрый чек-лист

  1. Обновить систему и включить автоматические обновления безопасности.
  2. Создать пользователя с sudo вместо работы под root.
  3. Настроить вход по SSH-ключу ed25519.
  4. Проверить вход по ключу в новом окне — и только после этого отключить пароль и вход root.
  5. Включить файрвол UFW, заранее разрешив SSH.
  6. Поставить Fail2ban против подбора паролей.
  7. По желанию сменить порт SSH.
  8. Настроить резервные копии и время от времени проверять порты, логи и обновления.
Безопасность VPS: порядок настройки защиты на Ubuntu и Debian без потери доступа
Порядок настройки: сначала вход по ключу и его проверка, потом запреты и файрвол

Прежде чем начать: как не потерять доступ

  • Не закрывайте текущую SSH-сессию, пока не проверите вход в новом окне. Уже открытое соединение продолжает работать даже после перезапуска sshd и включения файрвола — это ваша страховка.
  • Найдите консоль в панели хостера (VNC, «Консоль», «Emergency console»). Она работает в обход SSH и файрвола, и через неё можно всё откатить.
  • Сделайте снапшот сервера в панели, если хостер это позволяет.
  • Команды ниже выполняются от root. Если вы уже работаете под обычным пользователем — добавляйте sudo.

Общие правила безопасности

Безопасность VPS зависит не только от настроек сервера. Чаще всего серверы взламывают через утёкшие пароли от панели хостера и почты, а не через хитрые уязвимости.

  • Не храните пароль от панели хостера в TXT-файле на рабочем столе или в заметках. Используйте менеджер паролей с открытым исходным кодом — KeePassXC или Bitwarden. Если храните пароли в браузере — обязательно включите мастер-пароль.
  • Используйте длинные уникальные пароли: для каждого сервиса свой.
  • Максимально защитите почту, к которой привязан аккаунт хостера: через неё восстанавливается доступ ко всему остальному.
  • Включите двухфакторную аутентификацию для почты и панели хостера. Лучше через приложение с кодами (TOTP), а не SMS: SIM-карту могут перевыпустить мошенники. Я пользуюсь Aegis.
  • Не сохраняйте пароли в FTP- и SFTP-клиентах: вредоносные программы часто вытаскивают их оттуда.
  • Никому не передавайте основную учётную запись. Если нужен доступ другому человеку — создайте отдельного пользователя с его собственным SSH-ключом и удалите его, когда доступ больше не нужен.
  • Выбирайте надёжного хостинг-провайдера. Для сервера я использую Timeweb CloudРеклама.

Обновление системы и автоматические обновления безопасности

Первым делом установите все обновления, а затем включите unattended-upgrades — он будет сам ставить исправления безопасности каждый день. В Ubuntu пакет обычно уже установлен, в Debian его нужно поставить.

apt update && apt full-upgrade -y
apt install -y unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades   # ответьте «Yes»

# нужна ли перезагрузка после обновления ядра
[ -f /var/run/reboot-required ] && echo "Нужна перезагрузка"

По умолчанию автоматически ставятся только обновления безопасности, сервер сам не перезагружается. Если после обновления ядра появился файл /var/run/reboot-required — перезагрузите сервер в удобное время. Подробнее: документация Ubuntu и Debian Wiki.

Отдельный пользователь с sudo

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

apt install -y sudo          # в минимальном Debian sudo может не быть
adduser admin                # задайте надёжный пароль — он нужен для sudo и консоли
usermod -aG sudo admin

# если хостер уже добавил ваш ключ для root — скопируйте его новому пользователю
rsync --archive --chown=admin:admin ~/.ssh /home/admin

Пароль пользователя сохраните в менеджере паролей: после отключения входа по паролю в SSH он всё равно понадобится для sudo и для входа через консоль хостера.

Вход по SSH-ключу

SSH-ключ надёжнее любого пароля: его невозможно подобрать перебором, а секретная часть никогда не покидает ваш компьютер. Современный стандарт — ключ типа ed25519: он короче и быстрее RSA и поддерживается всеми актуальными клиентами и серверами.

Создание ключа на своём компьютере

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

# на своём компьютере: Linux, macOS или PowerShell в Windows 10/11
ssh-keygen -t ed25519 -C "admin@my-vps"

Согласитесь с путём по умолчанию и задайте кодовую фразу (passphrase) — она защитит ключ, если файл украдут. В каталоге ~/.ssh появятся два файла:

  • id_ed25519 — секретный ключ. Никому не передавайте и не загружайте на серверы, сделайте резервную копию в надёжном месте.
  • id_ed25519.pub — публичный ключ. Его и нужно добавить на сервер.

Если пользуетесь PuTTY, создайте ключ в PuTTYgen (тип EdDSA / Ed25519) и вставьте строку публичного ключа в файл ~/.ssh/authorized_keys на сервере. Многие хостеры также позволяют добавить публичный ключ прямо при создании VPS — тогда он окажется у root, и его можно скопировать пользователю командой rsync из прошлого шага.

Копирование ключа на сервер

# Linux и macOS
ssh-copy-id -i ~/.ssh/id_ed25519.pub admin@IP_СЕРВЕРА

# Windows (PowerShell): ssh-copy-id там нет, поэтому так
type $env:USERPROFILE.sshid_ed25519.pub | ssh admin@IP_СЕРВЕРА "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Команды сами создадут ~/.ssh/authorized_keys с правильными правами (700 для каталога, 600 для файла). Если права будут шире, sshd проигнорирует ключ.

Проверка входа по ключу

Откройте новое окно терминала и войдите под новым пользователем. Пароль от SSH спрашиваться не должен (только кодовая фраза ключа, если вы её задали):

ssh admin@IP_СЕРВЕРА
sudo -v   # спросит пароль пользователя admin — значит, sudo работает

Не переходите к следующему шагу, пока этот вход не заработает.

Настройка SSH: запрет пароля и входа root

Настройки лучше вынести в отдельный файл в /etc/ssh/sshd_config.d/, а не править основной sshd_config: так их не затрёт обновление пакета, и их легко откатить. Важная деталь: OpenSSH применяет первое найденное значение параметра, а файлы из sshd_config.d читаются по алфавиту и раньше основного конфига. Поэтому файл с префиксом 00- перекроет, например, 50-cloud-init.conf, в котором облачные образы Ubuntu часто включают PasswordAuthentication yes.

sudo nano /etc/ssh/sshd_config.d/00-hardening.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
AllowUsers admin
  • PermitRootLogin no — root не может войти по SSH. Если root по ключу нужен (например, для Ansible или скриптов бэкапа), используйте prohibit-password.
  • PasswordAuthentication no и KbdInteractiveAuthentication no — вход только по ключу, без паролей.
  • MaxAuthTries 3 и LoginGraceTime 30 — меньше попыток и времени на одно подключение.
  • AllowUsers admin — входить по SSH может только этот пользователь. Несколько имён пишутся через пробел.

Проверьте конфиг и перезапустите SSH:

# проверка синтаксиса: без вывода — значит, ошибок нет
sudo sshd -t

# итоговые значения, которые реально применит сервер
sudo sshd -T | grep -Ei '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|allowusers)'

sudo systemctl restart ssh

И сразу проверьте результат в новом окне:

# в НОВОМ окне терминала: вход по ключу должен работать
ssh admin@IP_СЕРВЕРА

# а вход по паролю — нет: ожидаем Permission denied (publickey)
ssh -o PubkeyAuthentication=no admin@IP_СЕРВЕРА

Если в старых инструкциях вы добавляли PubkeyAcceptedAlgorithms +ssh-rsa или RhostsRSAAuthentication — уберите их. Первый параметр возвращает устаревшую подпись RSA/SHA-1, а второй давно удалён из OpenSSH. С ключом ed25519 ничего из этого не нужно.

Файрвол UFW

UFW — простая надстройка над iptables и nftables. Политика простая: закрыть все входящие соединения и открыть только то, что действительно нужно. Разрешите SSH до команды ufw enable — иначе файрвол отрежет вас от сервера.

sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw limit 22/tcp comment 'SSH'
# только если на сервере есть сайт или панель:
sudo ufw allow 80,443/tcp comment 'Web'
sudo ufw enable
sudo ufw status verbose

ufw limit работает как allow, но блокирует адрес, который открывает больше 6 соединений за 30 секунд, — это дополнительная защита от перебора. Если у вас статический IP, SSH можно разрешить только с него:

# SSH только с вашего статического IP (вместо limit 22/tcp)
sudo ufw allow from 203.0.113.10 to any port 22 proto tcp comment 'SSH from office'

Docker обходит правила UFW

Порты, опубликованные через Docker (-p 8080:80 или ports: в compose), открываются собственными правилами iptables в обход UFW, и ufw status их не покажет. Публикуйте служебные порты только на localhost (127.0.0.1:8080:80) и выпускайте наружу через обратный прокси, либо используйте ufw-docker. Пример сервера на Docker — установка Matrix Synapse через Ansible и Docker.

Fail2ban: защита от подбора паролей

Fail2ban читает журналы и временно блокирует адреса, с которых идут неудачные попытки входа. При входе только по ключу подобрать доступ уже невозможно, но Fail2ban убирает шум из логов и снижает нагрузку от ботов. Настройки пишутся в отдельный файл в jail.d — стандартные jail.conf и defaults-debian.conf не редактируйте, их перезапишет обновление.

sudo apt install -y fail2ban
sudo nano /etc/fail2ban/jail.d/sshd.local
[DEFAULT]
bantime = 1h
bantime.increment = true
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1

[sshd]
enabled = true
port = ssh
# Debian 12: раскомментируйте, если fail2ban пишет
# «Have not found any log file for sshd jail»
# backend = systemd
  • bantime = 1h — на сколько блокировать адрес; bantime.increment увеличивает срок для тех, кто попадается снова.
  • findtime = 10m и maxretry = 5 — бан после 5 неудачных попыток за 10 минут.
  • ignoreip — адреса, которые никогда не блокируются. Допишите через пробел свой статический IP, чтобы не забанить себя.
  • port — если меняли порт SSH, укажите его здесь (например, port = 2222).

В Debian 12 по умолчанию нет файла /var/log/auth.log (журнал ведёт systemd), и Fail2ban может не запуститься — для этого в конфиге оставлена закомментированная строка backend = systemd. В Debian 13 такой бэкенд уже включён по умолчанию, в Ubuntu всё работает без изменений.

sudo systemctl enable fail2ban
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

# разблокировать адрес, если забанили себя
sudo fail2ban-client set sshd unbanip 203.0.113.10

Смена порта SSH (по желанию)

Нестандартный порт не защищает от целенаправленной атаки, но убирает из логов почти весь автоматический перебор. Если вход уже только по ключу, а UFW и Fail2ban настроены, это необязательно. Главное — соблюдать порядок: сначала открыть новый порт, проверить вход и только потом закрыть 22.

# 1. Сначала откройте новый порт в файрволе
sudo ufw limit 2222/tcp comment 'SSH'

# 2. Укажите порт для sshd
echo 'Port 2222' | sudo tee /etc/ssh/sshd_config.d/10-port.conf
sudo sshd -t

# 3. Узнайте, как запущен SSH: active — через ssh.socket
systemctl is-active ssh.socket

В Ubuntu 24.04 и 26.04 SSH запускается через ssh.socket, и порт слушает systemd, а не sshd. Поэтому одного Port в конфиге мало — нужно переопределить и сокет. Пустая строка ListenStream= обязательна: она сбрасывает стандартный 22-й порт.

# Ubuntu 24.04 / 26.04 (ssh.socket активен)
sudo mkdir -p /etc/systemd/system/ssh.socket.d
printf '[Socket]nListenStream=nListenStream=2222n' | sudo tee /etc/systemd/system/ssh.socket.d/port.conf
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket

# Ubuntu 22.04, Debian 12/13 (ssh.socket не используется)
sudo systemctl restart ssh
sudo ss -tlnp | grep -E ':(22|2222) '
# в новом окне
ssh -p 2222 admin@IP_СЕРВЕРА

# когда вход на 2222 проверен — закройте 22
sudo ufw delete limit 22/tcp

Не забудьте указать новый порт в Fail2ban (port = 2222) и перезапустить его.

Резервные копии

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

Регулярные проверки

Раз в неделю-месяц полезно заглянуть на сервер и проверить, не появилось ли лишнего:

# какие службы слушают порты
sudo ss -tulpn

# правила файрвола и забаненные адреса
sudo ufw status numbered
sudo fail2ban-client status sshd

# кто и откуда входил по SSH
sudo journalctl -u ssh -S today | grep -E 'Accepted|Failed'
last -a | head

# что ждёт обновления
apt list --upgradable

Незнакомые службы на внешних адресах (не 127.0.0.1), входы с чужих IP или отключённые автообновления — повод разобраться сразу. Для сайтов удобно использовать панель — например, Virtualmin, где файрвол, обновления и бэкапы собраны в одном интерфейсе.

Если потеряли доступ к серверу

Откройте консоль (VNC) в панели хостера и войдите под admin или root по паролю — ограничения SSH и файрвол на консоль не действуют. Затем откатите изменения и разберитесь, что пошло не так:

# в консоли (VNC) хостера под пользователем admin или root
sudo ufw disable
sudo rm -f /etc/ssh/sshd_config.d/00-hardening.conf /etc/ssh/sshd_config.d/10-port.conf
sudo rm -f /etc/systemd/system/ssh.socket.d/port.conf && sudo systemctl daemon-reload
sudo systemctl restart ssh.socket 2>/dev/null; sudo systemctl restart ssh
sudo fail2ban-client unban --all

Если пароль root не задан или забыт, загрузите сервер в режиме восстановления (rescue) из панели хостера, смонтируйте диск и поправьте файлы в /etc/ssh/.

Обсуждение и предложения

Памятка пополняется: свои советы и вопросы пишите в комментариях.

Частые вопросы

С чего начать безопасность VPS?

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

Нужно ли менять стандартный порт SSH?

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

Почему после смены Port в sshd_config SSH всё ещё слушает 22 порт в Ubuntu 24.04?

В Ubuntu 24.04 и 26.04 SSH запускается через ssh.socket, и порт задаёт systemd. Создайте переопределение /etc/systemd/system/ssh.socket.d/port.conf с пустой строкой u003ccodeu003eListenStream=u003c/codeu003e и новым портом, затем выполните u003ccodeu003esystemctl daemon-reloadu003c/codeu003e и u003ccodeu003esystemctl restart ssh.socketu003c/codeu003e.

Почему PasswordAuthentication no не отключает вход по паролю?

OpenSSH применяет первое найденное значение. В облачных образах Ubuntu файл /etc/ssh/sshd_config.d/50-cloud-init.conf включает пароль раньше основного конфига. Вынесите настройки в файл 00-hardening.conf в том же каталоге и проверьте итог командой u003ccodeu003esshd -T | grep passwordauthenticationu003c/codeu003e.

Fail2ban не запускается в Debian 12: Have not found any log file for sshd jail

В Debian 12 нет /var/log/auth.log — журнал ведёт systemd. Добавьте u003ccodeu003ebackend = systemdu003c/codeu003e в секцию [sshd] файла /etc/fail2ban/jail.d/sshd.local и перезапустите Fail2ban. В Debian 13 это уже настроено по умолчанию.

Какой SSH-ключ выбрать: RSA или ed25519?

Ed25519: он короче, быстрее и поддерживается всеми актуальными версиями OpenSSH. RSA нужен только для очень старых систем; в этом случае берите не меньше 3072 бит.

Нужен ли Fail2ban, если вход только по SSH-ключу?

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

Docker открывает порты мимо UFW — что делать?

Docker добавляет свои правила iptables в обход UFW. Публикуйте порты только на 127.0.0.1 и отдавайте наружу через обратный прокси, либо используйте ufw-docker.

Что делать, если я заблокировал себе доступ по SSH?

Войдите через консоль (VNC) в панели хостера — на неё не действуют ни настройки SSH, ни файрвол. Отключите UFW, удалите свои файлы из /etc/ssh/sshd_config.d/ и перезапустите SSH. Если пароль не помните — используйте режим восстановления (rescue).

Реклама. ООО «ТАЙМВЭБ.КЛАУД», ИНН 7810945525, erid: CQH36pWzJqVKyCLcHfYJjN7tMMG5q1zq1zwGxHoZ8G95ZA.

Рубрика: Безопасность
Подписаться на новые статьи (RSS)

Без почты и трекеров — только лента обновлений.

Также есть английская лента

Оцените статью
Добавить комментарий

  1. Аватар StudyDocx
    StudyDocx

    Спасибо за статью, пригодилось!

    Ответить