первичная настройка хоста и безопасности

Это гайд-памятка по базовой настройке VPS. Гайд написан под Ubuntu 24.04 LTS на DigitalOcean. На других дистрибутивах базовая логика та же, отличаться будут только команды и расположение конфигов. Все разделы опциональные и собирались под мои задачи.

Содержание:

В конце чеклист настроек.

Главное


Этап 1. Настройка non-root юзера и привязка ssh-ключа

На VPS создаём отдельного пользователя <username> для повседневной работы:

adduser username
usermod -aG sudo username       # даем права sudo
mkdir -p /home/username/.ssh
cp ~/.ssh/authorized_keys /home/username/.ssh/
chown -R username:username /home/username/.ssh
chmod 700 /home/username/.ssh
chmod 600 /home/username/.ssh/authorized_keys

Этап 2. Запрет root-логина и паролей по SSH

Отключаем небезопасные способы входа в ssh конфиге: sudo nano /etc/ssh/sshd_config.

PermitRootLogin no          # не пускать под root
PasswordAuthentication no   # не пускать под паролем
PubkeyAuthentication yes    # пускать под ключом

Применить:

sudo systemctl reload ssh

Перед тем, как закрыть сессию под рутом, проверяем коннект с локальной машины (в новом терминале, не закрывая текущий рут-сеанс): ssh username@<IP_VPS>.

Этап 3. Файрвол UFW

UFW (Uncomplicated Firewall) - это обёртка над iptables. Закрываем всё входящее, оставляем 22, 80, 443:

sudo ufw default deny incoming        # дефолт - блокировать входящий трафик 
sudo ufw default allow outgoing       # дефолт - разрешить исходящий трафик
# открываем порты на ssh
sudo ufw allow 22/tcp
# открываем порты на http(s), если нужно сервисам
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# включаем файрвол
sudo ufw enable
# посмотреть текущее состояние
sudo ufw status verbose

Вывод последней команды будет примерно таким:

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
443/tcp                    ALLOW IN    Anywhere
22/tcp (v6)                ALLOW IN    Anywhere (v6)
80/tcp (v6)                ALLOW IN    Anywhere (v6)
443/tcp (v6)               ALLOW IN    Anywhere (v6)

Если в будущем планируется ставить какие-то сервисы, то они должны работать на 127.0.0.1 и проксироваться через реверс-прокси (например, Caddy) на 80/443. Не открываем новые порты наружу без причины.

Этап 4. fail2ban от брутфорса

fail2ban защищает от ботов, которые будут стучаться на открытые порты. Он читает логи, находит неудачные попытки логина и временно банит IP.

sudo apt install -y fail2ban
sudo nano /etc/fail2ban/jail.local
[sshd]
enabled = true      # включает jail
maxretry = 3        # лимит попыток коннекта
bantime = 3600      # бан на 1 час
findtime = 600      # окно, в течение которого происходит maxretry. 10 минут
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

Этап 5. Автообновления безопасности

unattended-upgrades - механизм автоматических апдейтов Ubuntu/Debian.

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

“Automatically download and install stable updates?” -> yes.

--priority=low нужен, чтобы мы получили диалоговое окно с подтверждением автоапдейтов.

Проверяем, в /etc/apt/apt.conf.d/20auto-upgrades должно быть:

# Раз в день обновляем список пакетов
APT::Periodic::Update-Package-Lists "1";
# Раз в день запускаем установку обновлений
APT::Periodic::Unattended-Upgrade "1";

Перезагрузку после обновлений ядра оставим ручной, это ок. Раз в месяц можно делать ребут: sudo reboot.

Этап 6. Базовые утилиты

sudo apt install -y curl wget htop ncdu tmux tree

htop - мониторинг процессов, ncdu - найти кто ест диск, tmux - детачаемые сессии, tree - визуализация папок.

Этап 7. Часовой пояс и hostname

Часовой пояс необходимо настроить, чтобы логи писались и cron-таски работали по твоему времени, а не по UTC.

Имя хоста просто для удобства.

sudo timedatectl set-timezone <таймзона>
sudo hostnamectl set-hostname <хостнейм>

Этап 8. Выделение swap

При нехватке памяти в Linux процесс убивается OOM-killer’ом, поэтому выделяем своп (обычно x2 от RAM).

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

Этап 9. Git, Docker + Docker Compose

sudo apt install -y git

Дока Docker Engine: https://docs.docker.com/engine/install/ubuntu/

sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

sudo usermod -aG docker $USER

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

docker run hello-world

Этап 10. DigitalOcean Metrics Agent

Этапы 10-11 про базовую настройку метрик средствами DO. Помимо этого у меня работает Prometheus + Grafana / Alerts, об этом будет в отдельном гайде.

Дока DO Metrics Agent: https://docs.digitalocean.com/products/monitoring/how-to/install-metrics-agent/

Без do-agent DO видит только базовые внешние метрики. С ним работают расширенные графики, алерты по памяти/диску/CPU.

curl -sSL https://repos.insights.digitalocean.com/install.sh -o /tmp/install.sh
less /tmp/install.sh                     # просмотреть, что делает
sudo bash /tmp/install.sh                # запустить
systemctl status do-agent                # проверить

Агент работает под отдельным пользователем do-agent.

Этап 11. Resource Alerts в DO

После установки do-agent создаем в Monitoring -> Create Alert Policy:

Этап 12. SSH-конфиг на локальной машине

На локальной машине добавить в ~/.ssh/config:

Host vps
    HostName <IP VPS>
    User <username>
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 60
    ServerAliveCountMax 3

Теперь вместо ssh username@IP_VPS — просто ssh vps.

Этап 13. Бэкапы DO

Бэкап средствами DigitalOcean: Droplets -> дроплет -> Backups & Snapshots -> Setup Automated Backups -> Weekly Backups.

Стоит 20% стоимости дроплета.

Этап 14. Лимит логов journald

Ограничим journald место под логи. В /etc/systemd/journald.conf:

SystemMaxUse=500M
sudo systemctl restart systemd-journald
sudo journalctl --vacuum-size=500M       # подрезать накопленные логи разово

Чеклист

Безопасность

Базовая система

Инфраструктура

На локальной машине