bolt Valebyte VPS от $4/мес — NVMe, запуск за 60 секунд.

Получить VPS arrow_forward
eco Начальный Туториал

Hardening Ubuntu 24.04 за 30 минут: чек-лист для нового VPS

calendar_month Sep 24, 2026 schedule 18 мин. чтения visibility 20 просмотров
Hardening Ubuntu 24.04 за 30 минут: чек-лист для нового VPS
info

Нужен сервер для этого гайда? Мы предлагаем выделенные серверы и VPS в 50+ странах с мгновенной настройкой.

Нужен сервер для этого гайда?

Разверните VPS или выделенный сервер за минуты.

Hardening Ubuntu 24.04 за 30 минут: чек-лист для нового VPS

TL;DR

Hardening Ubuntu 24.04 для нового VPS — это набор быстрых мер, которые уменьшают поверхность атаки: обновления, отдельный sudo-пользователь, SSH-ключи, запрет root-входа, UFW, Fail2ban, автоматические security-обновления и резервные копии. Базовую защиту можно внедрить за 30 минут, не блокируя себе доступ к серверу.

  • Сначала создайте отдельного пользователя с SSH-ключом и проверьте вход во втором терминале.
  • Только после проверки запретите SSH-вход под root и отключите аутентификацию по паролю.
  • Откройте в UFW только необходимые порты: обычно 22, 80 и 443.
  • Установите Fail2ban, автоматические security-обновления и базовые инструменты диагностики.
  • Не публикуйте Docker-порты, базы данных, панели администрирования и Redis в интернет без необходимости.
  • Настройте внешний зашифрованный бэкап: hardening без возможности восстановления неполон.

Что мы настраиваем и зачем

Схема: Что мы настраиваем и зачем
Схема: Что мы настраиваем и зачем

Новый VPS с Ubuntu 24.04 обычно доступен по публичному IPv4-адресу сразу после провижининга. Интернет-сканеры находят такой адрес за минуты: они проверяют SSH, веб-порты, базы данных, Docker API, панели управления и известные уязвимые сервисы. Даже сервер без сайта и приложений начинает получать попытки перебора паролей почти сразу.

Цель этого руководства — создать безопасный базовый слой для Ubuntu 24.04 LTS. Это не заменяет аудит конкретного приложения, защиту кода, настройку IAM или DDoS-защиту, но закрывает типовые ошибки нового VPS: root-доступ по паролю, открытые лишние порты, отсутствие обновлений, неограниченные попытки входа и отсутствие резервных копий.

После выполнения чек-листа сервер будет иметь отдельного администратора, вход по SSH-ключам, ограниченный firewall, Fail2ban, включённые автоматические обновления безопасности, аудит открытых портов и основу для зашифрованных бэкапов. Этот набор подходит для VPS с сайтом, API, VPN, Git-сервисом, Minecraft-сервером, ботом, Docker Compose и внутренними инструментами.

Что не входит в базовый hardening

Hardening ОС не делает небезопасное приложение безопасным. Если вы публикуете WordPress, GitLab, Nextcloud, Grafana, Mattermost или собственный API, нужно отдельно обновлять само приложение, использовать сильные пароли и MFA, выключать тестовые endpoints, ограничивать административные URL и регулярно проверять логи.

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

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

Cloud-managed и self-hosted: что выбрать

Подход Что делает провайдер Что остаётся вашей задачей
Managed-платформа Часть обновлений, балансировка, резервирование отдельных сервисов Доступы, конфигурация приложения, данные, биллинг, vendor lock-in
Self-hosted на VPS Сеть, виртуализация, физическая инфраструктура ОС, SSH, firewall, обновления, бэкапы, мониторинг, приложение
Dedicated Физический сервер и канал связи Всё, включая ОС и часто аппаратный мониторинг

Self-hosted VPS выбирают ради контроля: можно запускать нужные версии ПО, держать данные в выбранной юрисдикции, не платить за каждый managed-компонент и не зависеть от ограничений платформы. Цена контроля — необходимость выполнять регулярную эксплуатацию. Этот чек-лист сокращает начальный риск, но его нужно повторять после изменений инфраструктуры.

Какой VPS-конфиг нужен под эту задачу

Схема: Какой VPS-конфиг нужен под эту задачу
Схема: Какой VPS-конфиг нужен под эту задачу

Сам hardening почти не требует ресурсов. Ubuntu 24.04, OpenSSH, UFW, Fail2ban и unattended-upgrades нормально работают на небольшом сервере. Ресурсы определяет не защита, а ваше будущее приложение: база данных, Docker-контейнеры, игровой сервер, VPN, CI, файловое хранилище или веб-приложение.

Сценарий vCPU RAM Диск Сеть
Только VPN, бот, статический сайт, bastion 1 1 ГБ 20–25 ГБ SSD 100 Мбит/с
Docker Compose, небольшой API, Caddy, PostgreSQL 2 2–4 ГБ 40–80 ГБ NVMe 100–1000 Мбит/с
Nextcloud, Mattermost, Minecraft, Git-сервис 4 8 ГБ 100 ГБ NVMe 1 Гбит/с

Для универсального нового сервера под небольшой проект разумный старт — 2 vCPU, 4 ГБ RAM, 60–80 ГБ NVMe и публичный IPv4. Такой запас позволяет использовать Docker, reverse proxy, логи, swap и небольшую базу данных без постоянного давления на память. Как один из нейтральных вариантов можно взять VPS с указанными характеристиками, но перед заказом сопоставьте объём диска с размером бэкапов и ростом данных.

Когда VPS достаточно

VPS подходит почти для всех одиночных сервисов и небольших команд. Изоляция виртуальной машины, регулярные snapshots и возможность быстро увеличить тариф удобны для старта. Для WireGuard, веб-приложения, мониторинга, пары контейнеров и нескольких десятков пользователей VPS обычно более чем достаточно.

Когда нужен dedicated

Выбирайте dedicated, если нужен гарантированный CPU без конкуренции с соседями, очень интенсивный I/O, много памяти, большие локальные массивы данных, высокая пропускная способность или предсказуемая производительность под постоянной нагрузкой. Типичные примеры: крупный игровой сервер, индексатор блокчейна, CI-раннеры, несколько тяжёлых виртуальных машин, медиа-транскодирование и база данных с сотнями гигабайт.

Как влияет локация

Локация влияет на задержку, законодательство о данных и скорость до вашей аудитории. Для VPN выбирайте регион рядом с пользователями. Для базы с персональными данными учитывайте требования вашей юрисдикции и договоров. Для администрирования важна не только география, но и стабильность маршрута: проверьте задержку командой ping и фактическую скорость после запуска.

Подготовка сервера

Схема: Подготовка сервера
Схема: Подготовка сервера

Ниже предполагается, что провайдер выдал IPv4-адрес и временный root-пароль либо добавил ваш публичный ключ. Работайте из обычного локального терминала. На Windows подойдут PowerShell, Windows Terminal или WSL. Все команды выполняются на сервере, если не указано иное.

Проверьте систему и обновите пакеты

Ubuntu 24.04 LTS использует ветку Linux 6.8 с HWE-обновлениями в зависимости от образа. Не ориентируйтесь только на номер версии: патчи безопасности часто бэкпортируются, поэтому пакет может иметь старый upstream-номер и при этом быть исправленным.

# Подключитесь к серверу по адресу, выданному после провижининга.
ssh root@SERVER_IP

# Проверьте релиз Ubuntu, ядро и текущего пользователя.
cat /etc/os-release
uname -r
whoami

# Обновите индекс пакетов и установленные пакеты.
apt update && apt full-upgrade -y

# Перезагрузите сервер, если обновилось ядро или systemd.
reboot

После перезагрузки подключитесь заново. Если SSH временно не отвечает, подождите одну-две минуты и проверьте web-консоль у провайдера. Не продолжайте настройку, пока не убедитесь, что система загрузилась.

Создайте отдельного администратора

Не используйте root как ежедневную учётную запись. Отдельный пользователь даёт понятный аудит действий, снижает риск случайной команды с полными правами и позволяет безопасно отключить root-login по SSH.

# Создайте пользователя admin и добавьте его в группу sudo.
adduser admin
usermod -aG sudo admin

# Создайте каталог для SSH-ключей с корректными правами.
install -d -m 700 -o admin -g admin /home/admin/.ssh

# Скопируйте уже работающий root authorized_keys новому пользователю.
cp /root/.ssh/authorized_keys /home/admin/.ssh/authorized_keys
chown admin:admin /home/admin/.ssh/authorized_keys
chmod 600 /home/admin/.ssh/authorized_keys

Если у root нет файла authorized_keys, создайте ключ на своём компьютере. Для 2026 года практичный выбор — Ed25519. Не передавайте приватный ключ на сервер и не отправляйте его в мессенджеры.

# Выполните на локальном компьютере: создайте ключ Ed25519.
ssh-keygen -t ed25519 -a 100 -C "admin@my-vps"

# Скопируйте публичный ключ на сервер; команда спросит текущий пароль root.
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@SERVER_IP

# На сервере повторите копирование ключа в учётную запись admin.
install -d -m 700 -o admin -g admin /home/admin/.ssh
cp /root/.ssh/authorized_keys /home/admin/.ssh/authorized_keys
chown admin:admin /home/admin/.ssh/authorized_keys
chmod 600 /home/admin/.ssh/authorized_keys

Откройте второй терминал и проверьте новый доступ. Старую root-сессию не закрывайте.

# Выполните локально: вход должен пройти по ключу без пароля пользователя.
ssh -i ~/.ssh/id_ed25519 admin@SERVER_IP

# Проверьте, что sudo работает в новой сессии.
sudo whoami

Ожидаемый результат последней команды — root. Только после этого переходите к настройке SSH. Если ключ не работает, сначала исправьте права на /home/admin/.ssh и authorized_keys.

Установка ПО — пошагово

Схема: Установка ПО — пошагово
Схема: Установка ПО — пошагово

В Ubuntu 24.04 используются пакеты OpenSSH 9.6p1 с патчами Ubuntu, UFW 0.36.x, Fail2ban 1.0.x и unattended-upgrades 2.9.x. Точную установленную версию всегда проверяйте через apt-cache policy: безопасность определяется доступными обновлениями конкретного репозитория, а не только номером upstream-версии.

# Подключитесь под новым пользователем и установите базовые инструменты.
ssh admin@SERVER_IP
sudo apt update
sudo apt install -y ufw fail2ban unattended-upgrades apt-listchanges \
  curl ca-certificates gnupg jq vim-tiny lsof needrestart chrony

Пакет needrestart сообщает, какие службы требуют перезапуска после обновления библиотек. chrony поддерживает точное время, что важно для TLS, токенов, журналов и расследования инцидентов.

# Проверьте версии и статус основных служб после установки.
apt-cache policy openssh-server ufw fail2ban unattended-upgrades
systemctl status ssh --no-pager
systemctl status chrony --no-pager
timedatectl status

Настройте UFW до отключения слабых методов SSH

UFW управляет правилами Netfilter. Безопасная последовательность: разрешить SSH, включить firewall, проверить статус, затем открыть только необходимые сервисы. Если вы используете нестандартный SSH-порт, разрешите именно его до применения конфигурации.

# Задайте политику: входящие запрещены, исходящие разрешены.
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Разрешите SSH и включите firewall.
sudo ufw allow 22/tcp comment 'OpenSSH'
sudo ufw enable

# Проверьте активные правила и номера правил.
sudo ufw status numbered

Если сервер будет обслуживать обычный HTTPS-сайт, откройте HTTP и HTTPS. Порт 80 нужен Caddy или Certbot для выпуска сертификата по HTTP-01. После получения сертификата его обычно оставляют открытым для автоматического продления и редиректа на HTTPS.

# Откройте веб-порты только если на сервере действительно будет HTTP/HTTPS-сервис.
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'

# Убедитесь, что доступен только ожидаемый набор портов.
sudo ufw status verbose
sudo ss -tulpn

Установите и включите автоматические security-обновления

Автоматическое применение обновлений безопасности не отменяет ручные обновления. Оно закрывает критичный промежуток между выходом патча и вашим плановым окном обслуживания. Для production-сервисов, чувствительных к рестартам, заранее тестируйте обновления на staging-сервере.

# Запустите интерактивную настройку автоматических обновлений Ubuntu.
sudo dpkg-reconfigure --priority=low unattended-upgrades

# Включите таймеры загрузки списков пакетов и установки обновлений.
sudo systemctl enable --now apt-daily.timer apt-daily-upgrade.timer

# Проверьте расписание системных таймеров.
systemctl list-timers --all | grep -E 'apt-daily|unattended'

Включите Fail2ban

Fail2ban читает журналы и временно блокирует IP-адреса после серии неудачных попыток. Это полезно против массового перебора, но не является заменой SSH-ключей. На Ubuntu 24.04 журнал SSH обычно доступен через systemd journal; ниже используется backend systemd.

# Создайте локальный конфигурационный каталог Fail2ban.
sudo install -d -m 755 /etc/fail2ban/jail.d

# Создайте отдельную локальную конфигурацию для SSH.
sudo tee /etc/fail2ban/jail.d/sshd.local > /dev/null <<'EOF'
[sshd]
enabled = true
backend = systemd
port = ssh
maxretry = 5
findtime = 10m
bantime = 1h
banaction = ufw
EOF

# Проверьте конфигурацию и запустите службу.
sudo fail2ban-client -d > /dev/null
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

Не редактируйте файлы /etc/fail2ban/jail.conf и /etc/ssh/sshd_config, поставляемые пакетом, без необходимости: обновления могут изменить их. Для локальных настроек используйте jail.d/.local и sshd_config.d/.conf.

Конфигурация

Схема: Конфигурация
Схема: Конфигурация

Ужесточите SSH без потери доступа

Ubuntu 24.04 поддерживает каталог /etc/ssh/sshd_config.d/. Создадим файл с приоритетным локальным набором параметров. Перед перезапуском всегда запускайте проверку синтаксиса: одна ошибка в SSH-конфиге может оставить сервер без удалённого доступа.

# Создайте локальный файл с безопасными настройками OpenSSH.
sudo tee /etc/ssh/sshd_config.d/99-hardening.conf > /dev/null <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
UsePAM yes
X11Forwarding no
AllowUsers admin
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
LogLevel VERBOSE
EOF

# Проверьте синтаксис и примените изменения без полного рестарта.
sudo sshd -t
sudo systemctl reload ssh

# Проверьте эффективные параметры, учитывая все include-файлы.
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|kbdinteractiveauthentication|allowusers|maxauthtries'

Теперь откройте ещё одно новое SSH-подключение как admin. Если подключение проходит, root-доступ по SSH отключён корректно. Если вы используете несколько администраторов, перечислите их в AllowUsers через пробел или удалите эту строку и управляйте доступом другими способами.

# Выполните локально: проверьте вход администратора после hardening SSH.
ssh -o PreferredAuthentications=publickey admin@SERVER_IP

# Выполните локально: root-вход должен быть отклонён.
ssh root@SERVER_IP

Добавьте параметры ядра через sysctl

Следующие параметры отключают неиспользуемую маршрутизацию IPv4 и уменьшают риск ряда сетевых подмен. Не применяйте их вслепую на VPS, который работает как маршрутизатор, WireGuard-шлюз, Kubernetes-нода или NAT-шлюз: там потребуется отдельная сетевая конфигурация.

# Создайте безопасные sysctl-настройки для обычного публичного сервера.
sudo tee /etc/sysctl.d/99-hardening.conf > /dev/null <<'EOF'
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_syncookies = 1
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
EOF

# Примените sysctl-файлы и проверьте один из параметров.
sudo sysctl --system
sysctl net.ipv4.tcp_syncookies

Секреты храните вне кода и репозитория

Пароли базы данных, токены API, ключи S3 и SMTP-учётные данные не должны попадать в Git, Dockerfile, shell history или публичные конфиги Nginx/Caddy. Для небольшого сервиса храните переменные в файле .env с правами 600. Для systemd используйте EnvironmentFile. В более крупной инфраструктуре применяйте Vault, SOPS, cloud secret manager или аналогичный секрет-хранилище.

# Создайте защищённый каталог и файл переменных окружения для приложения.
sudo install -d -m 750 -o root -g root /etc/myapp
sudo tee /etc/myapp/app.env > /dev/null <<'EOF'
APP_ENV=production
DATABASE_URL=postgresql://app:[email protected]:5432/app
JWT_SECRET=CHANGE_ME_TO_A_LONG_RANDOM_VALUE
EOF
sudo chmod 600 /etc/myapp/app.env

# Сгенерируйте криптографически случайный секрет и замените placeholder вручную.
openssl rand -base64 48

TLS/HTTPS через Caddy

Если на VPS есть веб-сервис, публикуйте его через reverse proxy. Caddy автоматически получает и продлевает TLS-сертификаты, если DNS-запись домена указывает на IP сервера, а порты 80 и 443 доступны извне. Не устанавливайте Caddy только ради hardening: если веб-сервиса нет, держите 80 и 443 закрытыми.

# Добавьте официальный репозиторий Caddy для актуальной стабильной ветки 2.x.
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | \
  sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \
  sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install -y caddy

# Проверьте установленную версию Caddy.
caddy version

Предположим, приложение слушает только локальный адрес 127.0.0.1:3000. Это важное ограничение: сервис не должен дополнительно открывать порт 3000 в интернет. Замените домен и порт на свои значения.

example.com {
    encode zstd gzip

    reverse_proxy 127.0.0.1:3000

    header {
        -Server
        X-Content-Type-Options "nosniff"
        X-Frame-Options "DENY"
        Referrer-Policy "strict-origin-when-cross-origin"
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
    }

    log {
        output file /var/log/caddy/example.com.access.log
        format json
    }
}
# Сохраните Caddyfile, проверьте его и перезагрузите Caddy.
sudo cp /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak
sudo vim /etc/caddy/Caddyfile
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl enable --now caddy
sudo systemctl reload caddy

# Проверьте HTTP-редирект, HTTPS и локальный health endpoint приложения.
curl -I http://example.com
curl -I https://example.com
curl -fsS http://127.0.0.1:3000/health || echo "Проверьте endpoint приложения"

Финальная проверка поверхности атаки

Проверяйте не только то, что вы настроили, но и то, что реально слушает сеть. Команда ss показывает локальные сокеты. Порты, привязанные к 127.0.0.1, не доступны напрямую из интернета; адреса 0.0.0.0 и [::] доступны на всех интерфейсах при разрешающем firewall.

# Покажите все слушающие TCP/UDP-порты и процессы-владельцы.
sudo ss -tulpn

# Проверьте firewall, Fail2ban, обновления и необходимость перезагрузки.
sudo ufw status numbered
sudo fail2ban-client status sshd
sudo unattended-upgrade --dry-run --debug
sudo needrestart -r l

# Проверьте доступность сервера и TLS с локального компьютера.
ping -c 4 SERVER_IP
curl -fsSI https://example.com

Для внешней проверки используйте второй сервер или мобильный интернет: убедитесь, что открыты только 22, 80 и 443, если это ваш план. Не открывайте PostgreSQL на 5432, MySQL на 3306, Redis на 6379, Docker API на 2375 и панели администрирования «на время»: такие временные решения часто остаются навсегда.

Бэкапы и обслуживание

Схема: Бэкапы и обслуживание
Схема: Бэкапы и обслуживание

Снимок VPS полезен, но не должен быть единственной резервной копией. Он может находиться в той же учётной записи, той же локации и даже на той же инфраструктуре, что и исходный сервер. Рабочая схема — правило 3-2-1: минимум три копии данных, на двух типах хранилища, одна копия вне основного сервера.

Что нужно бэкапить

  • Конфигурацию: /etc, Caddyfile, systemd units, Docker Compose-файлы, настройки firewall и скрипты.
  • Данные приложений: каталоги uploads, volumes Docker, файлы пользователей, медиа, ключи и сертификаты при необходимости.
  • Базы данных: логический dump PostgreSQL или MySQL плюс проверка восстановления.
  • Секреты: зашифрованные env-файлы, ключи доступа, recovery codes. Не складывайте секреты в обычный незашифрованный архив.
  • Документацию: список доменов, пользователей, портов, порядок восстановления и дату последней проверки restore.

Для небольшого сервера удобен Restic 0.17.x или новее: он шифрует данные на стороне VPS, поддерживает S3-совместимые хранилища, дедупликацию и политики хранения. Репозиторий Restic не заменяет пароль: потеря пароля репозитория без отдельного безопасного хранения означает потерю доступа к копиям.

# Установите Restic и создайте каталог для защищённых переменных бэкапа.
sudo apt install -y restic
sudo install -d -m 700 /root/.config/restic

# Создайте файл окружения; замените все значения на реальные.
sudo tee /root/.config/restic/backup.env > /dev/null <<'EOF'
export RESTIC_REPOSITORY="s3:https://s3.example.net/my-vps-backup"
export RESTIC_PASSWORD="CHANGE_ME_TO_A_LONG_UNIQUE_PASSWORD"
export AWS_ACCESS_KEY_ID="CHANGE_ME"
export AWS_SECRET_ACCESS_KEY="CHANGE_ME"
EOF
sudo chmod 600 /root/.config/restic/backup.env

# Инициализируйте новый зашифрованный репозиторий только один раз.
sudo bash -c 'source /root/.config/restic/backup.env && restic init'

Для PostgreSQL сначала создавайте дамп, а затем архивируйте его Restic. Команда ниже рассчитана на локальную базу и пользователя с правами чтения всех нужных объектов. Для Docker-контейнера БД используйте docker exec либо официальный механизм dump внутри контейнера.

# Создайте каталог для дампов, недоступный обычным пользователям.
sudo install -d -m 700 /var/backups/postgresql

# Пример: создайте сжатый дамп базы appdb от имени системного пользователя postgres.
sudo -u postgres pg_dump -Fc appdb > /var/backups/postgresql/appdb.dump
sudo chmod 600 /var/backups/postgresql/appdb.dump
# Создайте ежедневный скрипт: дамп БД, backup Restic, проверка и политика хранения.
sudo tee /usr/local/sbin/backup-server.sh > /dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

source /root/.config/restic/backup.env

DATE="$(date +%F)"
BACKUP_PATHS=(
  /etc
  /home
  /opt
  /srv
  /var/lib/docker/volumes
  /var/backups/postgresql
)

restic backup "${BACKUP_PATHS[@]}" \
  --exclude-caches \
  --exclude='/home//.cache' \
  --tag "server" \
  --tag "$DATE"

restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic check --read-data-subset=1/50
EOF
sudo chmod 700 /usr/local/sbin/backup-server.sh

# Запустите первый бэкап вручную и убедитесь, что он завершается без ошибок.
sudo /usr/local/sbin/backup-server.sh
sudo bash -c 'source /root/.config/restic/backup.env && restic snapshots'

Путь /var/lib/docker/volumes нельзя бездумно копировать во время активной записи базы данных: для PostgreSQL и MySQL используйте dump или штатный backup-инструмент. Для файловых данных можно архивировать volumes, но сначала зафиксируйте консистентность приложения.

# Добавьте запуск каждый день в 03:20 и запись лога в отдельный файл.
sudo tee /etc/cron.d/server-backup > /dev/null <<'EOF'
20 3    root /usr/local/sbin/backup-server.sh >> /var/log/server-backup.log 2>&1
EOF

# Проверьте, что cron видит задание, и посмотрите последние строки лога после запуска.
sudo systemctl status cron --no-pager
sudo tail -n 50 /var/log/server-backup.log

Проверка восстановления

Бэкап считается рабочим только после восстановления. Раз в месяц восстановите один файл и тестовый dump базы в отдельный каталог или на отдельный сервер. Не восстанавливайте базу поверх production-данных без остановки приложения и подтверждённого плана отката.

# Просмотрите содержимое последнего snapshot и восстановите его в тестовый каталог.
sudo bash -c 'source /root/.config/restic/backup.env && restic snapshots'
sudo mkdir -p /tmp/restic-restore
sudo bash -c 'source /root/.config/restic/backup.env && restic restore latest --target /tmp/restic-restore'

# Убедитесь, что нужные файлы и дамп действительно восстановились.
sudo find /tmp/restic-restore -maxdepth 4 -type f | head -n 30

План обновлений

Security-обновления можно применять автоматически, но обновления приложения, Docker-образов и крупных версий базы лучше планировать в maintenance window. Для stateless веб-приложения используйте rolling-обновление: запустите новую версию, проверьте healthcheck, затем переключите reverse proxy. Для одиночной базы данных обычно нужен короткий контролируемый простой.

  1. Раз в неделю просматривайте journalctl -p warning..alert, статус диска и логи бэкапа.
  2. Раз в месяц выполняйте sudo apt update && sudo apt full-upgrade и перезагрузку при необходимости.
  3. Раз в месяц проверяйте восстановление хотя бы одного файла и одного дампа БД.
  4. Раз в квартал пересматривайте пользователей, SSH-ключи, открытые порты и токены доступа.

Troubleshooting + FAQ

После настройки SSH я получаю Permission denied (publickey)

Сначала не закрывайте старую сессию или используйте web-консоль. Проверьте, что входите нужным пользователем: ssh admin@SERVER_IP. На сервере проверьте права: каталог ~/.ssh должен иметь режим 700, а authorized_keys — 600 и принадлежать пользователю. Посмотрите причину в sudo journalctl -u ssh -n 100. Частая ошибка — ключ скопирован в root, а в конфиге уже включён PermitRootLogin no.

UFW включён, но сайт или SSH недоступен

Подключитесь через консоль и выполните sudo ufw status numbered и sudo ss -tulpn. Firewall может разрешать порт, но приложение не слушает его либо привязано только к 127.0.0.1. Для SSH должна быть строка allow для фактического порта. Для сайта проверьте правила 80/tcp и 443/tcp, DNS-запись домена и статус Caddy. При ошибке правила можно удалить по номеру через sudo ufw delete НОМЕР.

Fail2ban не банит адреса или не видит SSH-попытки

Проверьте службу командой sudo systemctl status fail2ban, затем выполните sudo fail2ban-client status sshd. На Ubuntu 24.04 для SSH обычно правильный backend — systemd, поэтому он указан в локальном jail-файле. Посмотрите журналы через sudo journalctl -u fail2ban -n 100. Убедитесь, что в конфигурации указан banaction = ufw, если UFW используется как firewall.

Автоматические обновления включены, но сервер просит перезагрузку

Это нормальная ситуация после обновления ядра, некоторых библиотек или systemd. Проверьте наличие файла /var/run/reboot-required и вывод sudo needrestart -r l. Выберите окно обслуживания, предупредите пользователей и выполните sudo reboot. Автоматические security-обновления уменьшают окно уязвимости, но не могут безопасно перезапустить все приложения без учёта вашей нагрузки и зависимостей.

Какой VPS-конфиг минимально подойдёт?

Для самого hardening достаточно 1 vCPU, 1 ГБ RAM и 20 ГБ SSD, если сервер выполняет роль bastion-host, простого VPN или небольшого бота. Для практического универсального старта лучше 2 vCPU, 2–4 ГБ RAM и 40–80 ГБ NVMe: останется место для Docker, логов, обновлений и резервных дампов. Не рассчитывайте диск только под ОС: заранее заложите место под данные, временные файлы и локальные копии перед выгрузкой в внешний backup.

Что выбрать — VPS или dedicated для этой задачи?

Для hardening, небольшого сайта, VPN, API и нескольких контейнеров достаточно VPS. Он дешевле, быстрее разворачивается и проще масштабируется по памяти или диску. Dedicated нужен не из-за самого Ubuntu hardening, а при тяжёлой постоянной нагрузке: высоком I/O базы, большом игровом сервере, транскодировании, CI или требованиях к гарантированной производительности CPU. В обоих случаях правила SSH, firewall, обновления и бэкапы остаются обязанностью администратора.

Caddy не получает TLS-сертификат и выдаёт ошибку ACME

Проверьте, что A-запись домена указывает на публичный IPv4 VPS, а AAAA-запись либо корректна, либо отсутствует. Порты 80 и 443 должны быть открыты в UFW и во внешнем firewall провайдера. Выполните sudo journalctl -u caddy -n 100 --no-pager. Часто проблема в том, что другой веб-сервер уже занял порт 80 или домен указывает на старый IP. После исправления Caddy повторит попытку автоматически.

Как понять, что Docker случайно не открыл базу или панель в интернет?

Выполните sudo ss -tulpn и проверьте адреса привязки. Опасны сервисы на 0.0.0.0:5432, 0.0.0.0:3306, 0.0.0.0:6379 и похожих портах. В Docker Compose публикуйте внутренние сервисы как 127.0.0.1:5432:5432 либо вообще не используйте секцию ports, если контейнеры общаются по внутренней сети. Оставьте наружу только reverse proxy на 80/443 и SSH на выбранном порту.

Выводы и следующие шаги

Схема: Выводы и следующие шаги
Схема: Выводы и следующие шаги

Теперь новый VPS на Ubuntu 24.04 имеет базовую защиту: обновлённую систему, ключевой SSH-доступ, запрет root-входа, UFW, Fail2ban, sysctl-настройки, TLS для веб-сервиса и зашифрованный внешний бэкап. Это заметно снижает риск типовых автоматизированных атак и ошибок начальной настройки.

Следующим шагом добавьте мониторинг ресурсов и доступности, например проверку диска, памяти, срока TLS-сертификатов и статуса backup-задачи. Затем настройте отдельные политики hardening для вашего приложения: Docker, PostgreSQL, WireGuard, веб-фреймворка или панели управления.

После каждого нового сервиса повторяйте короткий аудит: нужен ли ему публичный порт, кто имеет доступ, где хранятся секреты, как выполняется обновление и можно ли восстановить данные из бэкапа. Именно этот цикл превращает разовую настройку VPS в поддерживаемую инфраструктуру.

Был ли этот гайд полезен?

Ваш отзыв помогает нам улучшать гайды.

Поделиться записью:

Отправьте гайд тому, кому он может пригодиться.

Telegram VKVK WhatsApp Facebook LinkedIn XX

hardening ubuntu 24.04 за 30 минут: чек-лист для нового vps
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.