Чтобы сервер начали перебирать, его не нужно рекламировать. Достаточно, чтобы он отвечал по адресу. Вот сутки из журнала обычного корпоративного сайта: 117 529 запросов всего, из них 494 — перебор чужих адресов с 29 разных адресов в сети.
Искали в основном не уязвимости платформы, а забытые файлы:
| Что запрашивали | Что рассчитывали найти |
|---|---|
/.env, /.env.bak, /.env.prod, /app/.env, /api/.env | файл с настройками: пароль базы, ключи платёжных сервисов, токены |
/.git/config, /.git/HEAD | выложенный в публичную папку репозиторий, а в нём — исходники и пароли |
/.aws/credentials, /.aws/config | ключи доступа к облаку |
/backup, файлы .sql | дамп базы или архив сайта рядом с самим сайтом |
/wp-login.php, /admin.php, phpmyadmin | вход, где можно подобрать пароль |
Ни один из этих запросов не был адресным: перебирают всё подряд, по спискам, круглосуточно. Поэтому и защита начинается не с редких сценариев, а с того, через что заходят массово.
Вход на сервер
Первое, что проверяется у любого сервера, — вход по SSH с паролем. Пока он разрешён, подбор идёт постоянно, и журнал входов растёт на десятки мегабайт в неделю.
Порядок такой. Сначала заводится вход по ключу и проверяется, что он работает, — у всех, кому нужен доступ, включая подрядчиков. Потом в /etc/ssh/sshd_config закрывается остальное:
PermitRootLogin no
PasswordAuthentication no
Port 54322
Первая строка запрещает входить сразу под root: администратор заходит под своей учётной записью и повышает права уже на сервере — видно, кто и что делал. Вторая убирает вход по паролю. Третья переносит SSH с 22-го порта.
Про порт стоит сказать честно: сам по себе он не защищает. Сканирование находит открытый порт за минуты, и если вход по паролю разрешён, перенос ничего не даст. Польза в другом — массовый перебор идёт по 22-му, и после переноса журналы перестают забиваться мусором, а живые попытки входа в них становятся видны.
Главное правило при этих правках: не закрывайте за собой дверь. Перед перезапуском SSH откройте второе соединение и проверьте вход новым способом в нём. Если что-то пойдёт не так, у вас останется работающая сессия, через которую можно всё вернуть.
Автоматическая блокировка подбора
Даже с ключами попытки входа продолжаются, и к ним добавляется подбор паролей в админку сайта и к почте. Это закрывается fail2ban: он читает журналы, считает неудачные попытки с одного адреса и блокирует его на заданное время.
Минимальная настройка — вход по SSH, админка и почта. Два условия, без которых от него больше вреда, чем пользы:
- Белый список. Ваши офисные адреса и адрес, с которого вы администрируете сервер, добавляются в
ignoreip. Иначе однажды вы заблокируете сами себя, и восстанавливать доступ придётся через панель хостинга. - Разумное время блокировки. Час-сутки. Вечная блокировка копит правила тысячами и со временем начинает тормозить сам межсетевой экран.
Чего fail2ban не умеет: останавливать распределённый перебор, когда каждый адрес делает по две-три попытки. Против этого работает только отсутствие пароля как способа входа.
Что смотрит наружу
Вторая по частоте находка — службы, которые слушают весь интернет, хотя нужны только самому серверу. Посмотреть, что открыто, можно одной командой:
ss -tlnp
В выводе интересна вторая колонка. 127.0.0.1:5432 — служба доступна только локально, это нормально. 0.0.0.0:5432 — база данных открыта всему интернету, и это уже вопрос.
Типичный набор того, что находится открытым: база данных, memcached или Redis, почтовые порты, панель управления веб-окружением, поставленный когда-то для одной задачи phpMyAdmin. Веб-окружение Битрикса, например, поднимает несколько служебных портов, включая панель настройки на 8893 — её в интернет выставлять незачем, доступ к ней достаточно оставить из своей сети или через SSH-туннель.
Отдельно про phpMyAdmin: если он нужен редко, его лучше не держать установленным постоянно — это ещё одна форма входа с паролем, которую будут подбирать.
Публичная папка
Всё, что лежит в папке сайта, доступно по адресу — если вы явно не запретили. Правил тут два.
Ничего лишнего в публичной папке. Дампы базы, архивы резервных копий, копии конфигурации вроде settings.php.bak, выгруженный репозиторий, файлы с настройками. Именно это и ищут те самые 494 запроса в сутки. Проверить легко: запросите свой домен с /.env, /.git/config и названиями архивов — вы должны получать 404, а не файл.
Запрет исполнения PHP там, куда сайт пишет файлы. Папки загрузок принимают файлы от пользователей, и если в них можно выполнить скрипт, любая следующая дыра в стороннем модуле превращается в постоянный доступ. В nginx это выглядит так:
location ^~ /upload/ {
location ~ \.php$ { return 403; }
}
Важная деталь для смешанной конфигурации: если сайт работает на связке nginx и Apache, статику отдаёт nginx мимо правил .htaccess, и запрет, прописанный только в нём, может не сработать. Проверять нужно запросом, а не наличием строки в файле.
Как это выглядит, когда настройки нет, мы разбирали в кейсе про сайт без обновлений: шесть закладок, поисковый клоакинг и повторное заражение через неделю после первой чистки — ровно потому, что положить новый файл и выполнить его можно было снова.
Обновления
Обновления безопасности операционной системы ставятся автоматически — это одна из немногих вещей, которую можно смело отдать роботу. Версию PHP и версию платформы обновляют иначе: осознанно, с проверкой на копии, потому что на старом коде смена версии ломает работающие страницы.
Тянуть с этим тоже не стоит. В октябре 2026 в PHP закрыли две уязвимости с оценкой 9,2 из 10, каждая позволяет выполнить произвольный код на сервере без авторизации, и для веток вне поддержки исправлений не выпустили вовсе. Порядок обновления пакетов сервера, PHP и базы мы расписывали отдельно.
Копии и журналы
Резервная копия на том же диске, что и сайт, спасает от неудачного обновления и не спасает ни от отказа диска, ни от шифровальщика, ни от взлома — потому что лежит там же, куда получил доступ атакующий. Копия должна уезжать с сервера, а проверяться — восстановлением, а не наличием архива нужного размера.
Журналы нужны, чтобы после инцидента понять, что произошло: когда появился файл, с какого адреса обращались, что отвечал сервер. Два требования: ротация должна работать (иначе журнал вырастает до гигабайтов и однажды забивает диск), а срок хранения — быть разумным, месяц-два. Разбор чаще всего начинается с фразы «а когда это началось?», и ответ на неё есть только в журналах.
Проверка за пятнадцать минут
Короткий список, который имеет смысл прогнать прямо сейчас:
- Запросить у своего сайта
/.env,/.git/configи пару вариантов имени архива — должно быть 404. - Посмотреть
ss -tlnpи найти службы, открытые на0.0.0.0, которым это не нужно. - Проверить в
/etc/ssh/sshd_configзначенияPermitRootLoginиPasswordAuthentication. - Положить в папку загрузок безобидный файл с расширением
.phpи запросить его: он не должен выполниться. - Посмотреть размер журнала входов: если это сотни мегабайт, вас перебирают давно и успешно забивают диск.
- Проверить, где лежит последняя резервная копия и когда её последний раз разворачивали.
Снаружи часть этого проверяет и наш экспресс-аудит сайта: доступность служебных файлов, заголовки, сертификат. То, что видно только с самого сервера, — порты, доступы, права — проверяется уже на нём.
Если разбираться с этим некому, мы делаем это как отдельную работу — базовая защита сервера: доступы, блокировка перебора, межсетевой экран, права в публичной папке и копии, с отчётом и командами для самостоятельной проверки.
Статья была полезна?
Частые вопросы
Нужно ли переносить SSH на нестандартный порт?
Это полезно, но не как защита. Открытый порт находится сканированием за минуты, поэтому от целенаправленной попытки перенос не спасает. Он убирает массовый перебор, который идёт по 22-му порту: журнал перестаёт забиваться, и в нём становятся видны настоящие попытки входа. Защищают вход по ключам и отключённый вход по паролю.
Можно ли закрыть вход root и не потерять доступ к серверу?
Да, если соблюдать порядок. Сначала заводится отдельная учётная запись с правом повышения привилегий, проверяется вход по ключу под ней, и только потом в настройках SSH запрещается вход root. Перед перезапуском службы держите открытым второе соединение — через него можно вернуть настройки, если новый способ входа не сработал.
Fail2ban защитит от подбора пароля в админку сайта?
От простого подбора с одного адреса — да, он заблокирует адрес после нескольких неудачных попыток. От распределённого, когда каждый адрес делает две-три попытки и меняется, не защитит ни он, ни другие подобные инструменты. Против такого работают сложные пароли, двухфакторная авторизация и ограничение доступа к админке по адресам.
Что из этого можно сделать на обычном хостинге?
На общем хостинге нет доступа к настройкам SSH, межсетевому экрану и службам, поэтому остаётся то, что относится к файлам сайта: убрать из публичной папки дампы, архивы и копии конфигурации, запретить исполнение PHP в папках загрузки, разобраться с правами и доступами к панели. Остальное — только на своём сервере или VPS.