Октябрь 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 после нескольких неудачных попыток входа. Три неправильных пароля — и адрес заблокирован на час. Для ботов, которые перебирают пароли по словарю, это фатально: они просто не успевают ничего перебрать.

Ставим:

# 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

Через сутки запустите эту же команду ещё раз — увидите живую картину. На наших боевых серверах в бане постоянно висит от 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 вместо UFW будет firewalld. Он посложнее — там зоны, 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? Это правда помогает?

От целенаправленной атаки это не спасёт — опытный пентестер найдёт ваш порт за секунды простым сканированием. Но против массовых ботов работает отлично. По нашей статистике, смена порта 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поддержка