Новый VPS с публичным IP-адресом начинает получать попытки входа по SSH почти сразу после создания. Защита не требует сложных инструментов: достаточно обновлений, входа по ключам, файрвола и fail2ban. Порядок действий важен, потому что ошибка в настройках SSH может закрыть доступ к серверу. Поэтому сначала проверяется ключ, и только потом отключается пароль.

Порядок действий и как не потерять доступ

Главное правило: не закрывайте текущую SSH-сессию, пока не проверили вход в новой. Откройте второе окно терминала и подключитесь им. Только когда новая сессия работает, можно закрывать старую. Если доступ все же потерян, восстанавливать его придется через консоль или поддержку провайдера.

Ниже предполагается, что вы уже подключаетесь по SSH-ключу, как описано в статье Как подключиться к VPS по SSH.

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

Начните с обновления пакетов и установки автоматических обновлений безопасности. Команды рассчитаны на Ubuntu 24.04 и Debian 12:

sudo apt update && sudo apt upgrade -y
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

Пакет unattended-upgrades ставит обновления безопасности без вашего участия. После крупных обновлений ядра сервер все равно стоит перезагрузить и проверить, что сервисы поднялись.

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

Постоянная работа от root повышает риск: любая ошибка сразу затрагивает всю систему. Создайте обычного пользователя, дайте ему sudo и перенесите ключ. Пример с пользователем deploy. Команда копирования предполагает, что ваш ключ уже лежит в ~/.ssh/authorized_keys у root:

sudo adduser deploy
sudo usermod -aG sudo deploy
sudo mkdir -p /home/deploy/.ssh
sudo cp ~/.ssh/authorized_keys /home/deploy/.ssh/
sudo chown -R deploy:deploy /home/deploy/.ssh
sudo chmod 700 /home/deploy/.ssh
sudo chmod 600 /home/deploy/.ssh/authorized_keys

Откройте новое окно терминала и войдите под новым пользователем. Проверьте, что sudo работает:

ssh deploy@203.0.113.10
sudo -v

Шаг 3. Отключите вход по паролю и root

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

sudo tee /etc/ssh/sshd_config.d/00-hardening.conf > /dev/null <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
EOF

Проверьте синтаксис и итоговые значения до перезагрузки службы. Команда sshd -t молчит, если ошибок нет, а sshd -T показывает действующие значения:

sudo sshd -t
sudo sshd -T | grep -E 'passwordauthentication|kbdinteractiveauthentication|permitrootlogin'

Примените настройки командой reload, чтобы не разорвать уже открытые сессии:

sudo systemctl reload ssh

Шаг 4. Настройте файрвол ufw

ufw (Uncomplicated Firewall) - понятная обертка над правилами netfilter. Правило для SSH нужно добавить до включения файрвола, иначе активация закроет текущее соединение. Если sshd слушает нестандартный порт, разрешите его явно, например sudo ufw allow 22022/tcp.

sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status verbose

Порты 80 и 443 открывайте только если на сервере работает веб-сервер: sudo ufw allow 80/tcp и sudo ufw allow 443/tcp. Остальные порты оставляйте закрытыми, пока сервис действительно не нужен.

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

Правила ufw описывают то, что разрешено на входе, но не показывают, какие сервисы реально слушают порты. Проверяйте оба варианта: команда ss покажет все открытые TCP-порты и процессы, которые их держат:

sudo ss -tlnp

Если в списке есть порт, который вы не собирались открывать, найдите процесс в колонке users и остановите или удалите его. Закрытый в ufw порт, на котором слушает сервис, остается недоступен снаружи, но такой сервис все равно работает внутри сервера и может стать точкой входа при уязвимости.

Шаг 5. Установите fail2ban

fail2ban читает журналы и временно блокирует адреса, которые слишком часто ошибаются при входе. Это не замена ключам, но заметно снижает шум в логах и нагрузку от перебора.

sudo apt install -y fail2ban python3-systemd

Локальные настройки храните в jail.local. Файл jail.conf обновляется вместе с пакетом, и правки в нем при обновлении потеряются. Создайте файл с минимальными параметрами:

sudo tee /etc/fail2ban/jail.local > /dev/null <<'EOF'
[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1

[sshd]
enabled = true
port    = ssh
backend = systemd
EOF

Если у вас есть статический IP-адрес, добавьте его в ignoreip, чтобы не заблокировать себя после нескольких ошибок ввода. Если SSH работает на другом порту, укажите его в поле port. Строка backend = systemd нужна потому, что в Debian 12 нет файла /var/log/auth.log и без неё fail2ban не стартует; в Ubuntu 24.04 она тоже работает. Затем запустите службу и проверьте jail:

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

Чтобы снять блокировку с адреса, используйте unbanip. Адрес в примере условный:

sudo fail2ban-client set sshd unbanip 198.51.100.7

Шаг 6. Проверьте результат

Пройдите короткий чеклист:

  • вход по ключу работает под пользователем deploy;
  • sudo -v выполняется без ошибок;
  • sudo sshd -T показывает passwordauthentication no и permitrootlogin no;
  • sudo ufw status показывает разрешенный OpenSSH и другие нужные порты;
  • sudo fail2ban-client status sshd показывает активный jail.

Для просмотра последних попыток входа используйте журнал:

sudo journalctl -u ssh --since today | tail -n 50

Что еще стоит сделать

  • делать резервные копии данных и конфигураций и хранить их вне сервера;
  • устанавливать только те пакеты и сервисы, которые действительно используются;
  • давать sudo только тем пользователям, которым он нужен;
  • следить за свободным местом на диске и за статусом обновлений.

Если вы запускаете сайт, пройдите отдельную инструкцию по сайту на VPS с Nginx и SSL. Для вопросов по настройке можно написать в поддержку Pulsar.

Итог

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