feat: Добавлена новая статья Debian 12: настройка Docker-хоста для production и скорректирована старая Debian 12: базовая настройка и hardening для production. Обновлены ссылки на них
This commit is contained in:
@@ -0,0 +1,837 @@
|
||||
---
|
||||
title: "Debian 12: базовая настройка и hardening для production"
|
||||
date: 2026-05-22
|
||||
draft: false
|
||||
description: "Пошаговая настройка чистого Debian 12 (Bookworm) для production: SSH, firewall, fail2ban, swap, sysctl, автообновления, логи, бэкап конфигов."
|
||||
tags: ["debian 12", "security", "hardening", "ssh", "ufw", "fail2ban", "sysctl", "production", "linux"]
|
||||
categories: ["Системное администрирование"]
|
||||
series: ["Linux Hardening"]
|
||||
series_order: 1
|
||||
---
|
||||
|
||||
# Debian 12: базовая настройка и hardening для production
|
||||
|
||||
Поставил чистый Debian 12 и думаешь сразу накатывать приложения? Не торопись. Час на базовую настройку сейчас - это недели сэкономленного времени на разгребание последствий взлома или падения.
|
||||
|
||||
Статья покрывает всё что нужно для production-сервера без контейнеров. Пройдёшь по шагам и получишь сервер с закрытым SSH, firewall, защитой от брутфорса, ограничением ресурсов ядра и автоматическими обновлениями безопасности. Docker - в следующей статье серии.
|
||||
|
||||
## Исходные данные
|
||||
|
||||
- Чистый Debian 12 (Bookworm)
|
||||
- Root доступ по SSH
|
||||
- Статический IP
|
||||
|
||||
Проверь версию:
|
||||
|
||||
```bash
|
||||
lsb_release -a
|
||||
```
|
||||
|
||||
Ожидаемый вывод:
|
||||
```
|
||||
Distributor ID: Debian
|
||||
Description: Debian GNU/Linux 12 (bookworm)
|
||||
Release: 12
|
||||
Codename: bookworm
|
||||
```
|
||||
|
||||
Все команды выполняются от `root` если не указано иное.
|
||||
|
||||
## Обновление системы
|
||||
|
||||
```bash
|
||||
apt update
|
||||
apt upgrade -y
|
||||
apt dist-upgrade -y
|
||||
apt autoremove -y
|
||||
```
|
||||
|
||||
Проверь нужна ли перезагрузка:
|
||||
|
||||
```bash
|
||||
[ -f /var/run/reboot-required ] && echo "Reboot needed" || echo "No reboot needed"
|
||||
```
|
||||
|
||||
Если нужна - перезагрузись:
|
||||
|
||||
```bash
|
||||
reboot
|
||||
```
|
||||
|
||||
## Базовые утилиты
|
||||
|
||||
```bash
|
||||
apt install -y \
|
||||
sudo curl wget git vim htop iotop iftop \
|
||||
net-tools dnsutils tcpdump screen tmux rsync \
|
||||
util-linux unzip ca-certificates gnupg2 lsb-release \
|
||||
smartmontools
|
||||
```
|
||||
|
||||
## Настройка системы
|
||||
|
||||
### Hostname
|
||||
|
||||
```bash
|
||||
hostnamectl set-hostname srv01.example.com
|
||||
```
|
||||
|
||||
Добавь в `/etc/hosts`:
|
||||
|
||||
```bash
|
||||
nano /etc/hosts
|
||||
```
|
||||
|
||||
```
|
||||
127.0.0.1 localhost
|
||||
203.0.113.10 srv01.example.com srv01
|
||||
|
||||
::1 localhost ip6-localhost ip6-loopback
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
||||
```
|
||||
|
||||
Замени `203.0.113.10` на реальный IP сервера, `srv01.example.com` - на своё имя.
|
||||
|
||||
Проверь FQDN:
|
||||
|
||||
```bash
|
||||
hostname -f
|
||||
# srv01.example.com
|
||||
```
|
||||
|
||||
### Timezone
|
||||
|
||||
```bash
|
||||
timedatectl set-timezone Europe/Moscow
|
||||
```
|
||||
|
||||
Проверь:
|
||||
|
||||
```bash
|
||||
timedatectl
|
||||
```
|
||||
|
||||
### Локаль
|
||||
|
||||
```bash
|
||||
apt install -y locales
|
||||
dpkg-reconfigure locales
|
||||
```
|
||||
|
||||
Выбери `en_US.UTF-8` как основную. Добавь `ru_RU.UTF-8` если нужна кириллица в системных сообщениях.
|
||||
|
||||
Проверь:
|
||||
|
||||
```bash
|
||||
locale
|
||||
# LANG=en_US.UTF-8
|
||||
```
|
||||
|
||||
## Пользователь и SSH
|
||||
|
||||
### Создание пользователя
|
||||
|
||||
Root сессия - одна ошибка без возможности откатиться. `sudo` даёт контроль и лог действий. Создай непривилегированного пользователя:
|
||||
|
||||
```bash
|
||||
adduser admin
|
||||
```
|
||||
|
||||
Добавь в sudo:
|
||||
|
||||
```bash
|
||||
usermod -aG sudo admin
|
||||
```
|
||||
|
||||
Проверь:
|
||||
|
||||
```bash
|
||||
groups admin
|
||||
# admin : admin sudo
|
||||
```
|
||||
|
||||
### SSH ключи
|
||||
|
||||
На своей рабочей машине сгенерируй ключ:
|
||||
|
||||
```bash
|
||||
# Linux/macOS
|
||||
ssh-keygen -t ed25519 -C "admin@srv01"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# Windows
|
||||
ssh-keygen -t ed25519
|
||||
```
|
||||
|
||||
Скопируй публичный ключ на сервер:
|
||||
|
||||
```bash
|
||||
# Linux/macOS
|
||||
ssh-copy-id admin@203.0.113.10
|
||||
```
|
||||
|
||||
```powershell
|
||||
# Windows
|
||||
type $env:userprofile\.ssh\id_ed25519.pub | ssh admin@203.0.113.10 "mkdir -m 700 -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
|
||||
```
|
||||
|
||||
Проверь вход по ключу - не должен спрашивать пароль:
|
||||
|
||||
```bash
|
||||
ssh admin@203.0.113.10
|
||||
```
|
||||
|
||||
### SSH hardening
|
||||
|
||||
Залогинься под `admin` и открой конфиг:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/ssh/sshd_config
|
||||
```
|
||||
|
||||
Замени содержимое (или найди и измени каждый параметр):
|
||||
|
||||
```
|
||||
# Нестандартный порт - отсекает 90% ботов
|
||||
Port 2222
|
||||
|
||||
# Только ключи
|
||||
PubkeyAuthentication yes
|
||||
AuthorizedKeysFile .ssh/authorized_keys
|
||||
|
||||
# Запретить root логин
|
||||
PermitRootLogin no
|
||||
|
||||
# Только ключи, без паролей
|
||||
PasswordAuthentication no
|
||||
PermitEmptyPasswords no
|
||||
KbdInteractiveAuthentication no
|
||||
|
||||
# Ограничения сессий
|
||||
MaxAuthTries 3
|
||||
MaxSessions 3
|
||||
LoginGraceTime 30
|
||||
|
||||
# Таймауты - отключать неактивные сессии
|
||||
ClientAliveInterval 300
|
||||
ClientAliveCountMax 2
|
||||
|
||||
# Отключить лишнее
|
||||
X11Forwarding no
|
||||
PrintMotd no
|
||||
UsePAM yes
|
||||
AcceptEnv LANG LC_*
|
||||
|
||||
# Только IPv4 (убери если используешь IPv6)
|
||||
AddressFamily inet
|
||||
```
|
||||
|
||||
**КРИТИЧНО:** Перед перезапуском SSH открой вторую сессию и не закрывай её - страховка если что-то пойдёт не так.
|
||||
|
||||
Проверь конфиг на ошибки:
|
||||
|
||||
```bash
|
||||
sudo sshd -t
|
||||
```
|
||||
|
||||
Нет вывода - нет ошибок. Перезапусти:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart sshd
|
||||
```
|
||||
|
||||
В новом терминале проверь подключение на новом порту:
|
||||
|
||||
```bash
|
||||
ssh -p 2222 admin@203.0.113.10
|
||||
```
|
||||
|
||||
Если работает - старые сессии можно закрывать.
|
||||
|
||||
### SSH banner (опционально)
|
||||
|
||||
Создай предупреждение при входе:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/ssh/banner
|
||||
```
|
||||
|
||||
```
|
||||
###############################################################################
|
||||
# Доступ только для авторизованных пользователей. #
|
||||
# Все действия логируются. #
|
||||
# Несанкционированный доступ преследуется по закону. #
|
||||
###############################################################################
|
||||
```
|
||||
|
||||
Добавь в `sshd_config`:
|
||||
|
||||
```
|
||||
Banner /etc/ssh/banner
|
||||
```
|
||||
|
||||
Перезапусти SSH:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart sshd
|
||||
```
|
||||
|
||||
## Firewall (UFW)
|
||||
|
||||
**Важно:** сначала настраиваем правила, потом включаем. Иначе заблокируешь себя.
|
||||
|
||||
```bash
|
||||
sudo apt install -y ufw
|
||||
```
|
||||
|
||||
Политика по умолчанию:
|
||||
|
||||
```bash
|
||||
# Блокировать все входящие
|
||||
sudo ufw default deny incoming
|
||||
|
||||
# Разрешить все исходящие
|
||||
sudo ufw default allow outgoing
|
||||
```
|
||||
|
||||
Разрешаем SSH на новом порту:
|
||||
|
||||
```bash
|
||||
# Замени 2222 на свой порт если менял
|
||||
sudo ufw allow 2222/tcp comment 'SSH'
|
||||
```
|
||||
|
||||
Включаем firewall:
|
||||
|
||||
```bash
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
Проверь статус:
|
||||
|
||||
```bash
|
||||
sudo ufw status verbose
|
||||
```
|
||||
|
||||
Ожидаемый вывод:
|
||||
```
|
||||
Status: active
|
||||
Logging: on (low)
|
||||
Default: deny (incoming), allow (outgoing), disabled (routed)
|
||||
New profiles: skip
|
||||
|
||||
To Action From
|
||||
-- ------ ----
|
||||
2222/tcp ALLOW IN Anywhere # SSH
|
||||
2222/tcp (v6) ALLOW IN Anywhere (v6) # SSH
|
||||
```
|
||||
|
||||
### Rate limiting на SSH
|
||||
|
||||
```bash
|
||||
# Блокировать IP после 6 подключений за 30 секунд
|
||||
sudo ufw limit 2222/tcp comment 'SSH rate limit'
|
||||
```
|
||||
|
||||
### Открытие дополнительных портов
|
||||
|
||||
Когда будешь ставить сервисы - открывай только нужные порты:
|
||||
|
||||
```bash
|
||||
# HTTP/HTTPS
|
||||
sudo ufw allow 80/tcp comment 'HTTP'
|
||||
sudo ufw allow 443/tcp comment 'HTTPS'
|
||||
|
||||
# PostgreSQL только с конкретного IP
|
||||
sudo ufw allow from 192.168.1.10 to any port 5432 comment 'PostgreSQL'
|
||||
```
|
||||
|
||||
Проверь что слушает на хосте:
|
||||
|
||||
```bash
|
||||
ss -tulnp
|
||||
```
|
||||
|
||||
Всё что слушает - должно быть либо закрыто firewall, либо намеренно открыто.
|
||||
|
||||
## Fail2ban
|
||||
|
||||
```bash
|
||||
sudo apt install -y fail2ban
|
||||
```
|
||||
|
||||
Создай локальный конфиг - не редактируй `jail.conf`, он перезаписывается при обновлении:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/fail2ban/jail.local
|
||||
```
|
||||
|
||||
```ini
|
||||
[DEFAULT]
|
||||
# Бан на 1 час
|
||||
bantime = 3600
|
||||
# За 10 минут
|
||||
findtime = 600
|
||||
# После 3 неудачных попыток
|
||||
maxretry = 3
|
||||
# Не банить свои IP
|
||||
ignoreip = 127.0.0.1/8 ::1
|
||||
# Явно указываем backend - важно для совместимости в серии Ubuntu/Rocky
|
||||
backend = systemd
|
||||
|
||||
[sshd]
|
||||
enabled = true
|
||||
port = 2222
|
||||
filter = sshd
|
||||
maxretry = 3
|
||||
bantime = 3600
|
||||
```
|
||||
|
||||
Замени `2222` на свой SSH порт.
|
||||
|
||||
Запусти:
|
||||
|
||||
```bash
|
||||
sudo systemctl enable fail2ban
|
||||
sudo systemctl start fail2ban
|
||||
```
|
||||
|
||||
Проверь статус:
|
||||
|
||||
```bash
|
||||
sudo fail2ban-client status
|
||||
```
|
||||
|
||||
```
|
||||
Status
|
||||
|- Number of jail: 1
|
||||
`- Jail list: sshd
|
||||
```
|
||||
|
||||
Проверь статус конкретного jail:
|
||||
|
||||
```bash
|
||||
sudo fail2ban-client status sshd
|
||||
```
|
||||
|
||||
## Swap
|
||||
|
||||
Swap в виде файла гибче раздела: можно увеличить или уменьшить без переразбивки диска.
|
||||
|
||||
### Создание swap файла
|
||||
|
||||
Проверь текущий swap:
|
||||
|
||||
```bash
|
||||
free -h
|
||||
sudo swapon --show
|
||||
```
|
||||
|
||||
Создай файл (пример - 2GB):
|
||||
|
||||
```bash
|
||||
# Создать файл нужного размера
|
||||
sudo fallocate -l 2G /swapfile
|
||||
```
|
||||
|
||||
Если `fallocate` не поддерживается файловой системой:
|
||||
|
||||
```bash
|
||||
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress
|
||||
```
|
||||
|
||||
Установи права - swap файл не должен читаться другими пользователями:
|
||||
|
||||
```bash
|
||||
sudo chmod 600 /swapfile
|
||||
```
|
||||
|
||||
Инициализируй и активируй:
|
||||
|
||||
```bash
|
||||
# Разметить как swap
|
||||
sudo mkswap /swapfile
|
||||
|
||||
# Включить
|
||||
sudo swapon /swapfile
|
||||
```
|
||||
|
||||
Проверь:
|
||||
|
||||
```bash
|
||||
free -h
|
||||
sudo swapon --show
|
||||
```
|
||||
|
||||
Добавь в `/etc/fstab` для автомонтирования после перезагрузки:
|
||||
|
||||
```bash
|
||||
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
|
||||
```
|
||||
|
||||
### Настройка swappiness
|
||||
|
||||
`swappiness` определяет агрессивность использования swap. Для production снижаем - swap только когда RAM заполнена на 90%+:
|
||||
|
||||
```bash
|
||||
# Проверить текущее значение (по умолчанию 60)
|
||||
cat /proc/sys/vm/swappiness
|
||||
```
|
||||
|
||||
Установи постоянно:
|
||||
|
||||
```bash
|
||||
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.d/99-swap.conf
|
||||
sudo sysctl -p /etc/sysctl.d/99-swap.conf
|
||||
```
|
||||
|
||||
### Изменение размера swap (когда потребуется)
|
||||
|
||||
```bash
|
||||
# Отключить текущий swap
|
||||
sudo swapoff /swapfile
|
||||
|
||||
# Изменить размер (пример - увеличить до 4GB)
|
||||
sudo fallocate -l 4G /swapfile
|
||||
|
||||
# Переинициализировать
|
||||
sudo mkswap /swapfile
|
||||
|
||||
# Включить
|
||||
sudo swapon /swapfile
|
||||
```
|
||||
|
||||
Проверь результат:
|
||||
|
||||
```bash
|
||||
free -h
|
||||
```
|
||||
|
||||
Запись в `/etc/fstab` менять не нужно - путь тот же.
|
||||
|
||||
### Удаление swap (если потребуется)
|
||||
|
||||
```bash
|
||||
sudo swapoff /swapfile
|
||||
sudo rm /swapfile
|
||||
```
|
||||
|
||||
Удали строку из `/etc/fstab`:
|
||||
|
||||
```bash
|
||||
sudo sed -i '/\/swapfile/d' /etc/fstab
|
||||
```
|
||||
|
||||
## Sysctl - защита ядра
|
||||
|
||||
Создай отдельный файл - чище чем писать в `/etc/sysctl.conf`:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/sysctl.d/99-hardening.conf
|
||||
```
|
||||
|
||||
```
|
||||
# Защита от SYN flood
|
||||
net.ipv4.tcp_syncookies = 1
|
||||
net.ipv4.tcp_max_syn_backlog = 2048
|
||||
net.ipv4.tcp_synack_retries = 2
|
||||
|
||||
# Игнорировать ICMP redirects (защита от MITM)
|
||||
net.ipv4.conf.all.accept_redirects = 0
|
||||
net.ipv4.conf.default.accept_redirects = 0
|
||||
net.ipv6.conf.all.accept_redirects = 0
|
||||
net.ipv6.conf.default.accept_redirects = 0
|
||||
|
||||
# Не отправлять ICMP redirects
|
||||
net.ipv4.conf.all.send_redirects = 0
|
||||
net.ipv4.conf.default.send_redirects = 0
|
||||
|
||||
# Игнорировать source routed packets
|
||||
net.ipv4.conf.all.accept_source_route = 0
|
||||
net.ipv6.conf.all.accept_source_route = 0
|
||||
|
||||
# Защита от IP spoofing
|
||||
net.ipv4.conf.all.rp_filter = 1
|
||||
net.ipv4.conf.default.rp_filter = 1
|
||||
|
||||
# Логировать подозрительные пакеты
|
||||
net.ipv4.conf.all.log_martians = 1
|
||||
|
||||
# Защита от time-wait assassination
|
||||
net.ipv4.tcp_rfc1337 = 1
|
||||
|
||||
# Отключить IPv6 если не используешь
|
||||
# net.ipv6.conf.all.disable_ipv6 = 1
|
||||
# net.ipv6.conf.default.disable_ipv6 = 1
|
||||
```
|
||||
|
||||
Примени:
|
||||
|
||||
```bash
|
||||
sudo sysctl -p /etc/sysctl.d/99-hardening.conf
|
||||
```
|
||||
|
||||
Проверь что применилось:
|
||||
|
||||
```bash
|
||||
sudo sysctl net.ipv4.tcp_syncookies
|
||||
# net.ipv4.tcp_syncookies = 1
|
||||
```
|
||||
|
||||
## Автообновления безопасности
|
||||
|
||||
```bash
|
||||
sudo apt install -y unattended-upgrades apt-listchanges
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
|
||||
```
|
||||
|
||||
Раскомментируй/измени:
|
||||
|
||||
```
|
||||
Unattended-Upgrade::Mail "root";
|
||||
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
|
||||
Unattended-Upgrade::Remove-Unused-Dependencies "true";
|
||||
Unattended-Upgrade::Automatic-Reboot "false";
|
||||
```
|
||||
|
||||
`Automatic-Reboot "false"` - важно для production. Перезагрузку после обновления ядра делать вручную в удобное время.
|
||||
|
||||
Включи:
|
||||
|
||||
```bash
|
||||
sudo dpkg-reconfigure -plow unattended-upgrades
|
||||
```
|
||||
|
||||
Выбери `Yes`.
|
||||
|
||||
Настрой расписание:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/apt/apt.conf.d/10periodic
|
||||
```
|
||||
|
||||
```
|
||||
APT::Periodic::Update-Package-Lists "1";
|
||||
APT::Periodic::Download-Upgradeable-Packages "1";
|
||||
APT::Periodic::AutocleanInterval "7";
|
||||
APT::Periodic::Unattended-Upgrade "1";
|
||||
```
|
||||
|
||||
Проверь что сервис работает:
|
||||
|
||||
```bash
|
||||
sudo systemctl status unattended-upgrades
|
||||
```
|
||||
|
||||
## Отключение ненужных сервисов (при наличии)
|
||||
|
||||
Посмотри что запущено:
|
||||
|
||||
```bash
|
||||
systemctl list-units --type=service --state=running
|
||||
```
|
||||
|
||||
Стандартные кандидаты на отключение - проверь что не используешь перед отключением:
|
||||
|
||||
```bash
|
||||
# Bluetooth - на сервере не нужен
|
||||
sudo systemctl disable --now bluetooth.service
|
||||
|
||||
# avahi-daemon - mDNS/DNS-SD, нужен редко
|
||||
sudo systemctl disable --now avahi-daemon.service
|
||||
|
||||
# ModemManager - управление модемами
|
||||
sudo systemctl disable --now ModemManager.service
|
||||
```
|
||||
|
||||
Проверь что слушает на сетевых портах:
|
||||
|
||||
```bash
|
||||
ss -tulnp
|
||||
```
|
||||
|
||||
Всё незнакомое - выясни что это и реши нужно ли.
|
||||
|
||||
## Логи и ротация
|
||||
|
||||
### Ограничение journald
|
||||
|
||||
```bash
|
||||
sudo nano /etc/systemd/journald.conf
|
||||
```
|
||||
|
||||
Раскомментируй/измени:
|
||||
|
||||
```
|
||||
SystemMaxUse=500M
|
||||
SystemMaxFileSize=100M
|
||||
MaxRetentionSec=1month
|
||||
```
|
||||
|
||||
Перезапусти:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart systemd-journald
|
||||
```
|
||||
|
||||
Проверь размер:
|
||||
|
||||
```bash
|
||||
sudo journalctl --disk-usage
|
||||
```
|
||||
|
||||
На чистом Debian 12 rsyslog не установлен - логи пишутся только в journald. Настройки выше достаточно.
|
||||
Если устанавливаешь rsyslog отдельно - создай /etc/logrotate.d/rsyslog с правилами ротации вручную.
|
||||
|
||||
## Мониторинг диска
|
||||
|
||||
На VPS имя устройства зависит от гипервизора - не всегда `/dev/sda`. Определи актуальное:
|
||||
|
||||
```bash
|
||||
# Найти дисковые устройства
|
||||
lsblk -d -o NAME,TYPE | grep disk
|
||||
# NAME TYPE
|
||||
# vda disk
|
||||
#
|
||||
# Результат зависит от гипервизора и провайдера:
|
||||
# /dev/sda - KVM у некоторых провайдеров, Xen
|
||||
# /dev/vda - KVM (наиболее распространённый вариант)
|
||||
# /dev/xvda - Xen
|
||||
```
|
||||
|
||||
Проверь состояние:
|
||||
|
||||
```bash
|
||||
# Замени vda на своё устройство
|
||||
sudo smartctl -H /dev/vda
|
||||
```
|
||||
|
||||
Ожидаемый вывод:
|
||||
```
|
||||
# ATA диски:
|
||||
# SMART overall-health self-assessment test result: PASSED
|
||||
#
|
||||
# SCSI/NVMe диски (типично для VPS):
|
||||
# SMART Health Status: OK
|
||||
#
|
||||
# Оба варианта означают одно: диск здоров
|
||||
```
|
||||
|
||||
Если `FAILED` - диск умирает. Срочно бэкап и замена.
|
||||
|
||||
Детали SMART:
|
||||
|
||||
```bash
|
||||
sudo smartctl -a /dev/vda
|
||||
```
|
||||
|
||||
Обращай внимание на `Reallocated_Sector_Ct`, `Pending_Sector_Count`, `Offline_Uncorrectable` - если ненулевые, диск проблемный.
|
||||
|
||||
Примечание:
|
||||
На виртуальных дисках (VMware, KVM) SMART может быть недоступен: `SMART support is: Unavailable - device lacks SMART capability.`
|
||||
В этом случае smartctl полезен только для физических серверов.
|
||||
На VPS ориентируйся на мониторинг от провайдера.
|
||||
|
||||
## Бэкап конфигов
|
||||
|
||||
Конфиги на диске - не бэкап. Скрипт архивирует `/etc/` и SSH ключи.
|
||||
|
||||
```bash
|
||||
nano ~/backup-configs.sh
|
||||
```
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
BACKUP_DIR="$HOME/backups"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_FILE="$BACKUP_DIR/config_backup_$DATE.tar.gz"
|
||||
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# Сохранить список установленных пакетов
|
||||
dpkg --get-selections > "$HOME/installed-packages.txt"
|
||||
|
||||
# Архивировать конфиги и SSH ключи
|
||||
sudo tar -czf "$BACKUP_FILE" \
|
||||
/etc/ \
|
||||
/root/.ssh/ \
|
||||
/home/*/.ssh/ \
|
||||
"$HOME/installed-packages.txt" \
|
||||
2>/dev/null
|
||||
|
||||
echo "Backup: $BACKUP_FILE"
|
||||
ls -lh "$BACKUP_FILE"
|
||||
|
||||
# Удалить бэкапы старше 30 дней
|
||||
find "$BACKUP_DIR" -name "config_backup_*.tar.gz" -mtime +30 -delete
|
||||
```
|
||||
|
||||
Права и первый запуск:
|
||||
|
||||
```bash
|
||||
chmod +x ~/backup-configs.sh
|
||||
~/backup-configs.sh
|
||||
```
|
||||
|
||||
Ожидаемый вывод:
|
||||
```
|
||||
Backup: /home/admin/backups/config_backup_20260522_030000.tar.gz
|
||||
-rw-r--r-- 1 root root 1.2M May 22 03:00 /home/admin/backups/config_backup_20260522_030000.tar.gz
|
||||
```
|
||||
|
||||
Автоматизация через cron (каждое воскресенье в 3:00):
|
||||
|
||||
```bash
|
||||
crontab -e
|
||||
```
|
||||
|
||||
```
|
||||
0 3 * * 0 /home/admin/backup-configs.sh >> /var/log/backup-configs.log 2>&1
|
||||
```
|
||||
|
||||
### Восстановление
|
||||
|
||||
Восстановить конфиги:
|
||||
|
||||
```bash
|
||||
sudo tar -xzf ~/backups/config_backup_ДАТА.tar.gz -C /
|
||||
```
|
||||
|
||||
Восстановить список пакетов:
|
||||
|
||||
```bash
|
||||
sudo dpkg --set-selections < ~/installed-packages.txt
|
||||
sudo apt-get dselect-upgrade
|
||||
```
|
||||
|
||||
## Финальная проверка
|
||||
```bash
|
||||
# Открытые порты
|
||||
ss -tulnp
|
||||
|
||||
# Статус firewall
|
||||
sudo ufw status verbose
|
||||
|
||||
# Статус fail2ban
|
||||
sudo fail2ban-client status sshd
|
||||
|
||||
# Состояние диска
|
||||
sudo smartctl -H /dev/vda
|
||||
|
||||
# Swap
|
||||
free -h
|
||||
```
|
||||
|
||||
## Что дальше
|
||||
|
||||
Сервер готов к установке приложений. База одинакова для любой нагрузки - веб, база данных, почта.
|
||||
|
||||
Если следующий шаг - контейнеры, читай продолжение серии: [Debian 12: настройка Docker-хоста для production](/posts/debian-12-docker-hardening/).
|
||||
|
||||
**Стек этой статьи:** Debian 12 (Bookworm) · UFW · Fail2ban · OpenSSH · unattended-upgrades · systemd · smartmontools
|
||||
Reference in New Issue
Block a user