Октябрь 2024 года. Звонок в пятницу вечером — самое любимое время для таких историй. На проводе — директор юридической компании из Москвы, 45 сотрудников: «Евгений, у нас всё встало. На экранах какой-то текст про биткоины, 1С не открывается, базы зашифрованы». Мы подключились за десять минут. Картина стандартная: сервер на Debian, SSH торчит наружу на 22 порту, пароль root — Company2020. Злоумышленник зашёл, подсадил шифровальщик, подчистил логи. Бэкапы? Лежали на том же сервере. Тоже зашифрованы.

Восстановление заняло трое суток. Часть данных удалось вытащить из теневых копий на рабочих станциях. Часть — нет. Компания потеряла документы по нескольким делам, которые вели последние два месяца. Сумму ущерба считать не буду — цифры неприятные.

И вот что обидно. Эту ситуацию можно было предотвратить за два часа работы. Без специальных знаний, без дорогого оборудования, без подписок на enterprise-решения. Просто сделать то, что написано ниже.

Я занимаюсь IT-инфраструктурой для бизнеса больше 15 лет. За это время через мои руки прошли сотни серверов. И каждый раз, когда я вижу свежеустановленный VPS с открытым root по паролю — у меня дёргается глаз. Потому что я знаю, что будет дальше.

Эта статья — конкретный пошаговый план. Без теории «почему важна безопасность» (вы и сами знаете), без рекламы дорогих продуктов. Команды, конфиги, объяснения. Скопировал — вставил — защитил.

Почему ваш сервер уже атакуют

Вот что многие не понимают: вас не нужно «находить». Боты сканируют весь диапазон IPv4 непрерывно. Весь. 4,3 миллиарда адресов. Полный скан занимает у них от 5 до 40 минут — зависит от мощности ботнета.

Мы ведём статистику по серверам наших клиентов. Вот реальные цифры за 2025 год:

Не верите? Поставьте чистый VPS за 300 рублей у любого хостера, не трогайте настройки и через сутки посмотрите /var/log/auth.log. Гарантирую — вы удивитесь.

Факт из практики: В прошлом году мы расследовали инцидент в бухгалтерской фирме. Сервер взломали через SSH за 6 часов после установки. Пароль был Qwerty123. Злоумышленник установил криптомайнер, который грузил CPU на 100% и гонял электричество на $200 в месяц. Обнаружили только когда хостер прислал предупреждение о превышении трафика.

Теперь к делу. Я буду показывать всё на Debian/Ubuntu — это самые распространённые серверные ОС в малом бизнесе. Для CentOS/AlmaLinux буду давать альтернативные команды там, где они отличаются.

Обновление системы — первое и главное

Звучит банально. Все знают, что нужно обновляться. Но когда я делаю аудит серверов у новых клиентов — на 7 из 10 стоят пакеты, которым больше полугода. А на трёх — вообще ни разу не обновлялись с момента установки.

Каждое обновление безопасности закрывает конкретную дыру. Не абстрактную «уязвимость», а реальный способ попасть на ваш сервер. CVE-2024-6387 (regreSSHion) — помните? Удалённое выполнение кода через OpenSSH. Патч вышел в июле 2024. У кого не было обновлений — тот был открыт для любого бота, который знал про эту дыру.

Обновляем всё:

# Debian / Ubuntu
sudo apt update && sudo apt upgrade -y

# CentOS / AlmaLinux
sudo dnf update -y

После обновления ядра — перезагружаемся:

sudo reboot

Да, перезагрузка. Знаю, что неприятно. Но новое ядро не заработает без неё. Планируйте окно обслуживания — хотя бы раз в месяц, ночью. Две минуты простоя лучше, чем трое суток восстановления после взлома.

Совет: Проверьте, нужна ли перезагрузка, командой cat /var/run/reboot-required (Debian/Ubuntu). Если файл существует — пора перезагружаться.

SSH: закрываем главную дверь

SSH — это парадный вход на ваш сервер. И именно в него ломятся 90% ботов. Сейчас мы превратим эту дверь из фанерной в бронированную.

Все настройки SSH живут в одном файле: /etc/ssh/sshd_config. Перед любыми изменениями — делаем копию:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup

Отключаем root-логин

Root — это суперпользователь. Его логин известен заранее: root. Злоумышленнику остаётся подобрать только пароль. Половина работы уже сделана за него.

Сначала создаём обычного пользователя и даём ему sudo:

# Создаём пользователя
sudo adduser admin

# Добавляем в группу sudo
sudo usermod -aG sudo admin

Проверяем, что можем зайти под новым пользователем (в отдельном окне терминала!). Только после этого отключаем root.

Открываем конфиг:

sudo nano /etc/ssh/sshd_config

Находим строку и меняем:

PermitRootLogin no
Внимание! Не закрывайте текущую SSH-сессию, пока не убедились, что можете зайти под новым пользователем. Иначе рискуете заблокировать себя. Я видел это раз двадцать — люди в спешке отключают root, перезапускают SSH и обнаруживают, что нового пользователя забыли создать. Дальше — обращение в поддержку хостера и сброс через VNC-консоль.

Только ключи, никаких паролей

Пароль можно подобрать. Даже сложный — вопрос времени и мощности. А вот SSH-ключ длиной 4096 бит — нельзя. Математически невозможно при текущих вычислительных мощностях.

Генерируем ключ на вашем локальном компьютере (не на сервере!):

# На вашем ПК / ноутбуке
ssh-keygen -t ed25519 -C "admin@company"

Ed25519 — современный алгоритм. Быстрее RSA, короче ключи, та же стойкость. Если нужна совместимость со старыми системами — используйте ssh-keygen -t rsa -b 4096.

Копируем публичный ключ на сервер:

# С вашего ПК
ssh-copy-id -i ~/.ssh/id_ed25519.pub admin@ваш_сервер

Проверяем вход по ключу (в новом окне!). Если зашли без ввода пароля — отлично. Теперь отключаем парольную аутентификацию:

# В /etc/ssh/sshd_config
PasswordAuthentication no
PubkeyAuthentication yes

Меняем порт SSH

Это не защита. Давайте сразу договоримся. Опытный атакующий найдёт ваш SSH на любом порту за секунды через nmap. Но 99% атак — это тупые боты, которые стучатся только в порт 22. Сменив порт, вы убираете из логов тысячи мусорных записей и снижаете нагрузку на Fail2ban.

В /etc/ssh/sshd_config:

Port 2222

Выберите порт от 1024 до 65535. Не используйте стандартные порты других сервисов (80, 443, 3306 и т.д.). Я обычно ставлю что-нибудь вроде 2222, 2299 или 4422 — легко запомнить.

Теперь применяем все изменения разом:

sudo systemctl restart sshd

И сразу проверяем подключение в новом окне:

ssh -p 2222 admin@ваш_сервер

Работает? Отлично. Теперь ваш SSH выглядит так:

Уже одно это отсекает 99% автоматических атак. Но мы не остановимся.

Fail2ban — автобан ботов

Fail2ban мониторит логи авторизации и банит IP-адреса после нескольких неудачных попыток входа. Проще говоря: три неправильных пароля — и ваш IP заблокирован на час. Для ботов это смертельно — они не могут перебирать пароли, если их банят после трёх попыток.

Устанавливаем:

# Debian / Ubuntu
sudo apt install fail2ban -y

# CentOS / AlmaLinux
sudo dnf install epel-release -y
sudo dnf install fail2ban -y

Создаём локальный конфиг (не редактируем основной — он перезатрётся при обновлении):

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

Мои рабочие настройки, проверенные на десятках серверов:

[DEFAULT]
bantime  = 3600
findtime = 600
maxretry = 3
banaction = iptables-multiport

[sshd]
enabled = true
port    = 2222
logpath = /var/log/auth.log
maxretry = 3

Что тут написано на человеческом языке:

Запускаем:

sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Проверяем статус:

sudo fail2ban-client status sshd

Через сутки выполните эту команду снова — увидите, сколько IP уже забанено. У нас на боевых серверах обычно 50-80 забаненных адресов в любой момент времени.

Из практики: На одном из серверов клиента Fail2ban забанил 12 847 уникальных IP-адресов за первый месяц работы. Это 12 847 ботов, которые больше не смогли подбирать пароли. Без Fail2ban каждый из них мог бы сделать тысячи попыток.

Файрвол: разрешаем только нужное

Философия простая: запретить всё, разрешить только то, что нужно. Не наоборот. Если вашему серверу нужны только SSH и веб-сервер — значит, открыты только порты 2222, 80 и 443. Всё остальное — закрыто.

UFW (Ubuntu / Debian)

UFW — Uncomplicated Firewall. Название не врёт — он действительно простой. Это обёртка над iptables, которая экономит часы набора криптических правил.

# Устанавливаем (обычно уже есть в Ubuntu)
sudo apt install ufw -y

# Политика по умолчанию: входящие — запретить, исходящие — разрешить
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Разрешаем SSH на нашем порту
sudo ufw allow 2222/tcp comment 'SSH'

# Разрешаем веб-сервер (если нужен)
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'

# Включаем
sudo ufw enable
Критически важно: Разрешите SSH до включения файрвола! Иначе вы заблокируете себе доступ. Я не шучу — это ошибка номер один. Мы получаем такие звонки раз в пару месяцев: «Включил UFW и не могу зайти». Дальше — консоль VNC у хостера и сброс правил.

Проверяем правила:

sudo ufw status verbose

Должно быть примерно так:

Status: active

To                         Action      From
--                         ------      ----
2222/tcp                   ALLOW       Anywhere        # SSH
80/tcp                     ALLOW       Anywhere        # HTTP
443/tcp                    ALLOW       Anywhere        # HTTPS

Чисто и понятно. Всё, что не в списке — заблокировано.

firewalld (CentOS / AlmaLinux)

Если вы на CentOS, RHEL или AlmaLinux — у вас firewalld. Он мощнее UFW (зоны, rich rules, прямые правила iptables), но для нашей задачи нужно буквально пять команд:

# Убеждаемся, что запущен
sudo systemctl enable firewalld
sudo systemctl start firewalld

# Добавляем SSH на нестандартном порту
sudo firewall-cmd --permanent --add-port=2222/tcp

# Убираем стандартный SSH (порт 22)
sudo firewall-cmd --permanent --remove-service=ssh

# Добавляем веб-сервер (если нужен)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

# Применяем
sudo firewall-cmd --reload

Проверяем:

sudo firewall-cmd --list-all

Результат должен показать только нужные порты и сервисы. Ничего лишнего.

Мониторинг: знать что происходит

Защита без мониторинга — это замок на двери без камеры. Вы не узнаете, что кто-то пытался войти, пока не станет поздно. Мониторинг — это ваши глаза и уши на сервере.

Логи и auditd

Первым делом — научимся читать логи. Вот файлы, которые нужно проверять регулярно:

Быстрая проверка — кто заходил последним:

# Последние 20 входов
last -20

# Неудачные попытки
lastb -20

# Кто сейчас на сервере
w

Для серьёзного мониторинга ставим auditd — подсистему аудита ядра Linux:

# Установка
sudo apt install auditd audispd-plugins -y    # Debian/Ubuntu
sudo dnf install audit -y                       # CentOS/AlmaLinux

# Запуск
sudo systemctl enable auditd
sudo systemctl start auditd

Добавляем правила аудита. Создаём файл:

sudo nano /etc/audit/rules.d/hardening.rules

Вот набор правил, который я использую на всех клиентских серверах:

# Мониторинг изменений в /etc/passwd и /etc/shadow
-w /etc/passwd -p wa -k passwd_changes
-w /etc/shadow -p wa -k shadow_changes
-w /etc/group -p wa -k group_changes

# Мониторинг SSH-конфигурации
-w /etc/ssh/sshd_config -p wa -k sshd_config

# Мониторинг crontab (часто используется для закрепления)
-w /etc/crontab -p wa -k cron_changes
-w /var/spool/cron/ -p wa -k cron_changes

# Мониторинг sudo
-w /etc/sudoers -p wa -k sudoers_changes
-w /etc/sudoers.d/ -p wa -k sudoers_changes

# Отслеживание запуска подозрительных команд
-a always,exit -F arch=b64 -S execve -F path=/usr/bin/wget -k exec_wget
-a always,exit -F arch=b64 -S execve -F path=/usr/bin/curl -k exec_curl

Применяем:

sudo auditctl -R /etc/audit/rules.d/hardening.rules

Теперь, если кто-то изменит файл паролей, конфиг SSH или добавит задание в cron — вы узнаете. Смотрим аудит-логи:

# Все события за сегодня
sudo ausearch -ts today

# Только изменения в passwd
sudo ausearch -k passwd_changes

# Красивый отчёт
sudo aureport --summary

Tripwire / AIDE — контроль целостности

Auditd отслеживает действия в реальном времени. А AIDE (Advanced Intrusion Detection Environment) — это контроль целостности файлов. Он делает «снимок» системы: какие файлы есть, какой у них размер, хеш, права. И потом сравнивает. Если что-то изменилось без вашего ведома — вы получите отчёт.

# Установка
sudo apt install aide -y

# Инициализация базы данных (занимает 2-5 минут)
sudo aideinit

# Копируем базу
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db

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

sudo aide --check

Эту команду нужно запускать регулярно. Лучше всего — через cron, раз в сутки:

sudo crontab -e

Добавляем строку:

0 6 * * * /usr/bin/aide --check | mail -s "AIDE report $(hostname)" admin@company.ru

Каждое утро в 6:00 вам будет приходить отчёт. Если всё чисто — пустое письмо. Если что-то изменилось — вы узнаете первым.

Случай из практики: AIDE помог нам обнаружить компрометацию на сервере клиента в 2024 году. Злоумышленник подменил /usr/sbin/sshd на модифицированную версию, которая логировала все пароли в скрытый файл. Обычными средствами это не заметишь — сервис работает нормально. Но AIDE показал: хеш файла изменился, хотя обновлений не было. После этого мы переустановили систему и сменили все пароли.

Автоматические обновления безопасности

Ручные обновления — это хорошо. Но вы не можете обновлять сервер каждый день. А критические патчи иногда выходят в пятницу вечером, когда вы уже на даче. Решение — автоматические обновления безопасности.

На Debian/Ubuntu ставим unattended-upgrades:

sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgrades

Проверяем конфигурацию:

sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

Убедитесь, что разрешены обновления безопасности:

Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}-security";
};

Опционально — настраиваем уведомления на почту и автоперезагрузку:

Unattended-Upgrade::Mail "admin@company.ru";
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";

Для CentOS/AlmaLinux:

sudo dnf install dnf-automatic -y
sudo nano /etc/dnf/automatic.conf

Ключевые параметры:

[commands]
upgrade_type = security
apply_updates = yes

[emitters]
emit_via = email
email_from = root@hostname
email_to = admin@company.ru

Активируем таймер:

sudo systemctl enable --now dnf-automatic.timer

Теперь критические обновления будут ставиться автоматически. Без вашего участия. Спите спокойно — в буквальном смысле.

Бэкапы — последняя линия обороны

Вернёмся к истории из начала статьи. Юридическая компания потеряла данные, потому что бэкапы лежали на том же сервере. Это не бэкап. Это копия файлов рядом с оригиналом.

Правило 3-2-1 — простое и работающее:

Вот минимальный скрипт бэкапа, который я ставлю на каждый новый сервер:

#!/bin/bash
# /opt/backup.sh — ежедневный бэкап

BACKUP_DIR="/opt/backups"
REMOTE="ftp://user:pass@backup-server.ru/"
DATE=$(date +%Y-%m-%d)
RETAIN_DAYS=14

# Создаём локальный бэкап
mkdir -p $BACKUP_DIR
tar -czf $BACKUP_DIR/server-$DATE.tar.gz \
    /etc/ \
    /home/ \
    /var/www/ \
    /opt/projects/ \
    --exclude='*.log' \
    --exclude='node_modules' \
    --exclude='.cache'

# Отправляем на удалённый FTP
curl -T $BACKUP_DIR/server-$DATE.tar.gz $REMOTE

# Удаляем старые локальные бэкапы
find $BACKUP_DIR -name "*.tar.gz" -mtime +$RETAIN_DAYS -delete

echo "Backup completed: $DATE"

Даём права и ставим в cron:

chmod +x /opt/backup.sh
sudo crontab -e

Добавляем:

# Бэкап каждый день в 3:00
0 3 * * * /opt/backup.sh >> /var/log/backup.log 2>&1

Для баз данных (PostgreSQL, MySQL) — отдельный дамп перед основным бэкапом:

# PostgreSQL
pg_dumpall -U postgres | gzip > /opt/backups/pg-$DATE.sql.gz

# MySQL / MariaDB
mysqldump --all-databases -u root -p'password' | gzip > /opt/backups/mysql-$DATE.sql.gz
Главное правило бэкапов: бэкап, который не проверен — не существует. Раз в месяц разворачивайте бэкап на тестовом сервере и убедитесь, что данные на месте. Мы видели случаи, когда бэкапы делались полгода, но архив был повреждён — и восстанавливать оказалось нечего.

Если бюджет позволяет — используйте rsync с инкрементальными бэкапами или специализированные решения вроде restic или BorgBackup. Они дедуплицируют данные и шифруют архивы. Но даже простой tar + FTP — лучше, чем ничего.

Чеклист безопасности сервера

Распечатайте этот список и пройдитесь по каждому пункту. Серьёзно. На каждый сервер, за который вы отвечаете.

Если вы можете поставить галочку напротив каждого пункта — ваш сервер защищён лучше, чем 95% серверов малого бизнеса в России. Без шуток. Большинство взломов происходит через элементарные вещи: пароль 123456, открытый root, отсутствие обновлений.

Часто задаваемые вопросы

Сколько времени нужно на базовую защиту сервера?

Базовая настройка — SSH hardening, файрвол, Fail2ban, обновления — занимает 1-2 часа. Если вы делаете это впервые, заложите 3-4 часа с учётом чтения документации. Полноценная настройка с мониторингом, аудитом и бэкапами — от 4 до 8 часов.

Можно ли защитить сервер без root-доступа?

Частично. Вы можете настроить SSH-ключи для своего пользователя, но для установки Fail2ban, настройки файрвола и auditd нужны права sudo или root. На VPS root-доступ обычно предоставляется по умолчанию. Если у вас shared-хостинг — эти настройки делает провайдер.

Fail2ban замедляет работу сервера?

Нет. Fail2ban потребляет менее 30 МБ оперативной памяти. Он парсит логи и добавляет правила в iptables. На серверах с 1 ГБ RAM проблем не будет. За 15 лет практики я ни разу не видел, чтобы Fail2ban создавал заметную нагрузку.

Стоит ли менять порт SSH? Это правда помогает?

От целенаправленной атаки — не поможет, ваш порт найдут за секунды. Но от массовых ботов — помогает отлично. По нашей статистике, смена порта снижает количество попыток брутфорса на 95-98%. Боты сканируют порт 22 и, не найдя его открытым, идут дальше. Меньше мусора в логах, меньше нагрузки на Fail2ban.

Какой файрвол лучше — UFW или firewalld?

UFW проще и идеален для одиночных серверов. Это стандарт для Ubuntu и Debian. Firewalld мощнее, поддерживает зоны и динамические правила, по умолчанию в CentOS/RHEL/AlmaLinux. Для малого бизнеса с одним-двумя серверами UFW более чем достаточен. Если у вас десяток серверов с разными ролями — смотрите в сторону firewalld.

Как понять, что сервер уже взломан?

Признаки: необъяснимая нагрузка на CPU (майнеры), незнакомые процессы в top/htop, новые пользователи в /etc/passwd, изменённые системные файлы, странные задания в crontab -l, исходящий трафик на неизвестные IP. Команда last покажет последние входы — если видите незнакомые IP, это тревожный сигнал. Проверьте также netstat -tlnp на предмет подозрительных слушающих портов.

Заключение

Давайте честно: абсолютной защиты не существует. Если кто-то целенаправленно хочет взломать именно ваш сервер и готов потратить на это время и ресурсы — он это сделает. Но такие атаки — менее 1% от общего числа. Остальные 99% — это массовые боты, скрипт-кидди с готовыми инструментами и оппортунисты, которые ищут лёгкую добычу.

Всё, что описано в этой статье, превращает ваш сервер из лёгкой добычи в крепость. Бот стучится в порт 22 — закрыто. Пытается подобрать пароль — нет паролей, только ключи. Нашёл SSH на другом порту — Fail2ban банит после трёх попыток. Даже если случится невероятное и кто-то проникнет — AIDE заметит изменения, а бэкап позволит откатиться.

Вот что нужно сделать прямо сейчас:

  1. Подключиться к вашему серверу и обновить все пакеты
  2. Создать обычного пользователя с sudo, настроить SSH-ключи и отключить root-логин
  3. Установить и настроить Fail2ban
  4. Включить файрвол и закрыть все ненужные порты
  5. Настроить бэкап на внешнее хранилище

Два часа. Максимум — четыре, если делаете впервые. После этого вы можете спать спокойно, зная, что ваш сервер не станет следующей жертвой очередного бота из Юго-Восточной Азии.

Если разбираться нет времени или желания — мы в АйТи Фреш занимаемся этим каждый день. Аудит безопасности, hardening, мониторинг, бэкапы — под ключ, с гарантией. Работаем с юридическими лицами по всей России. Позвоните или оставьте заявку.

Полезные ссылки: CIS Benchmarks — стандарты безопасности, Fail2ban — официальный сайт, AIDE — документация

Нужен аудит безопасности сервера?

ООО «АйТи Фреш» защитит вашу инфраструктуру

Не хотите разбираться в конфигах SSH и правилах файрвола? Мы проведём аудит, настроим защиту, мониторинг и бэкапы под ключ — с гарантией результата. Работаем с юридическими лицами в Москве и регионах. Поддержка 24/7.

15+лет опыта
25+клиентов
40Gсвоя сеть
24/7поддержка