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

Команды проверены на Ubuntu 24.04 и 26.04. Мы подключаемся как root — так сервер обычно выдают. Адрес 203.0.113.10 замените на свой.

1. Обновить систему

apt update && apt full-upgrade -y

Если после обновления появился файл /var/run/reboot-required, обновилось ядро или важные библиотеки — перезагрузите сервер:

[ -f /var/run/reboot-required ] && reboot

2. Создать пользователя для работы

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

adduser admin            # задайте пароль — он понадобится для sudo
usermod -aG sudo admin

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

install -d -m 700 -o admin -g admin /home/admin/.ssh
install -m 600 -o admin -g admin /root/.ssh/authorized_keys /home/admin/.ssh/authorized_keys

Проверка. Не закрывая текущее подключение, в новом окне терминала:

ssh admin@203.0.113.10
sudo whoami               # спросит пароль admin и ответит root

Если входа по ключу ещё нет совсем, сначала настройте его по статье «Как входить на сервер по SSH-ключу».

3. Закрыть вход по паролю и вход для root

Когда вход admin по ключу и sudo работают, запретим вход по паролю и прямой вход для root:

sudo tee /etc/ssh/sshd_config.d/00-hardening.conf > /dev/null <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
EOF
sudo sshd -t && sudo systemctl reload ssh

Префикс 00 нужен, чтобы этот файл прочитался раньше облачного 50-cloud-init.conf: SSH берёт первое найденное значение настройки. Подробности и что делать, если не пускает, — в статье про SSH-ключи.

Проверка — в новом окне: ssh admin@203.0.113.10 пускает, а ssh root@203.0.113.10 отвечает Permission denied.

4. Включить файрвол UFW

UFW — простая обёртка над файрволом Linux, в Ubuntu он уже установлен. Главное правило: сначала разрешить SSH, потом включать — иначе текущее подключение оборвётся.

sudo ufw allow OpenSSH          # порт 22; если сменили порт SSH — sudo ufw allow <порт>/tcp
sudo ufw allow 80/tcp           # только если на сервере будет сайт
sudo ufw allow 443/tcp
sudo ufw enable                 # на вопрос ответить y
sudo ufw status verbose

В выводе должно быть Status: active, Default: deny (incoming), allow (outgoing) и ваши правила.

Если на сервере будет Docker: порты, которые контейнер публикует через -p 8080:80, Docker открывает в обход UFW. Сервисы, которые не должны быть видны снаружи, публикуйте только на localhost: -p 127.0.0.1:8080:80. Подробнее — в статье о Docker Compose в продакшене.

5. Включить автоматические обновления безопасности

Пакет unattended-upgrades ставит обновления безопасности сам, раз в сутки. Обычно он уже установлен; включим и убедимся:

sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades     # выбрать «Yes»
cat /etc/apt/apt.conf.d/20auto-upgrades

Должно быть две строки со значением "1":

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

Проверить, что именно он поставил бы сейчас, можно без установки: sudo unattended-upgrade --dry-run --debug.

6. Поставить fail2ban

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

sudo apt install -y fail2ban
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

В Ubuntu 24.04 и 26.04 защита SSH включена сразу после установки: настройки лежат в /etc/fail2ban/jail.d/defaults-debian.conf, журнал читается через systemd. Свои значения пишите в отдельный файл, а не в системные:

sudo tee /etc/fail2ban/jail.local > /dev/null <<'EOF'
[sshd]
maxretry = 5
bantime  = 1h
# если SSH на нестандартном порту:
# port = 22746
EOF
sudo systemctl restart fail2ban

Не проверяйте блокировку подключениями с самого сервера: свои адреса fail2ban по умолчанию не блокирует (ignoreself = true).

7. Время и часовой пояс

timedatectl

Строка System clock synchronized: yes значит, что время синхронизируется автоматически. Часовой пояс на серверах часто оставляют UTC — так проще сравнивать журналы разных машин. Если удобнее местное время:

sudo timedatectl set-timezone Europe/Moscow

8. Файл подкачки на сервере с малым объёмом памяти

На сервере с 1–2 ГБ памяти файл подкачки страхует от внезапного завершения процессов при пиковой нагрузке — например, во время сборки проекта. Он медленнее памяти и не заменяет её.

sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
swapon --show

Последняя команда должна показать /swapfile размером 1G. Строка в /etc/fstab включает подкачку после перезагрузки. Как понять, что памяти не хватает и подкачка не спасает, — в статье про OOM killer.

Итог

Что сделали Чем проверить
Обновили систему apt list --upgradable — список пакетов пуст
Пользователь admin с sudo ssh admin@…, затем sudo whoami → root
Вход только по ключу, root закрыт sudo sshd -T — строки passwordauthentication no и permitrootlogin no
Файрвол sudo ufw status verbose
Автообновления безопасности cat /etc/apt/apt.conf.d/20auto-upgrades
fail2ban sudo fail2ban-client status sshd
Время timedatectl
Подкачка swapon --show

Дальше — то, ради чего брали сервер:

  • установка Docker и Docker Compose в продакшене на одном VPS;
  • Nginx как обратный прокси и HTTPS от Let's Encrypt;
  • PostgreSQL на Ubuntu;
  • деплой Next.js на VPS и автоматический деплой из GitHub Actions;
  • Telegram-бот на сервере через systemd.

Сколько памяти понадобится под эти задачи — в статье «Сколько оперативной памяти нужно VPS».