MAATRIX / Блог / Десять советов из интернета, которые сломают ваш сервер

Десять советов из интернета, которые сломают ваш сервер

MAATRIX

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

Права доступа: быстро — не значит правильно

1. «Сделай chmod 777, если права не работают»

Звучит так: приложение не может прочитать или записать файл, ошибка Permission denied — и первый совет из поисковой выдачи: chmod -R 777 /var/www/app. Помогает мгновенно, ошибка исчезает, все довольны.

Почему это работает: 777 — это «читать, писать, выполнять могут все» (владелец, группа, остальные). Естественно, ошибка прав доступа пропадёт — вы просто отключили сами права доступа как механизм.

Что ломается: любой процесс на сервере — включая скомпрометированный через уязвимость в другом приложении — теперь может дописать в ваши файлы что угодно, включая веб-шелл в папку с PHP-скриптами. На виртуальном хостинге с несколькими пользователями это ещё хуже: соседи по машине физически могут читать и менять ваши файлы. Отдельная засада — рекурсивный 777 на директорию с исполняемыми файлами и конфигами: даже боты, сканирующие интернет на предмет открытых на запись wp-config.php, находят такие сервера.

Как правильно: сначала понять, кто на самом деле должен владеть файлом.

ls -la /var/www/app
ps aux | grep nginx    # или php-fpm, gunicorn — кто реальный процесс-владелец

Дальше — выставить владельца и группу под реальный процесс, а права — по минимуму нужного:

chown -R www-data:www-data /var/www/app
find /var/www/app -type d -exec chmod 755 {} \;
find /var/www/app -type f -exec chmod 644 {} \;

Если пишущий процесс и читающий — разные пользователи (например, деплой через SSH-пользователя, а отдаёт nginx), решение — общая группа с правом записи для группы (chmod 775/2775 с setgid на директории), а не «всем всё».

2. «Используй root для всего, так меньше проблем с правами»

Звучит так: зачем возиться с sudo и группами, если можно зайти под root и работать без ограничений — команды выполняются без вопросов, cron не спотыкается о права, docker не ругается на сокет.

Почему кажется рабочим: root действительно снимает 90% ошибок прав доступа — просто потому что root может всё. Субъективно это ощущается как «навёл порядок», хотя на деле убрали единственный барьер между опечаткой и катастрофой.

Что ломается: одна неверная команда под root выполняется без предупреждений и без права на ошибку. Классика — rm -rf ./ вместо rm -rf ./cache/ после случайного cd не туда, или find / -name "*.log" -delete с забытым уточнением пути. Под обычным пользователем такая команда чаще всего упрётся в Permission denied на системных файлах и нанесёт локальный ущерб; под root она пройдёт до конца. Отдельная проблема — привычка работать под root расползается на приложения: контейнеры и сервисы запускаются от root «для простоты», и уязвимость в одном из них сразу даёт полный контроль над хостом. Если такой сервер обслуживает несколько человек, это ещё и невозможность понять, кто что сделал — в логах везде один и тот же root.

Как правильно: заводить именных пользователей с sudo для тех, кому нужен административный доступ, и root-логин по SSH отключать вовсе (PermitRootLogin no в /etc/ssh/sshd_config). О том, как раздать команде доступ без выдачи root-пароля и что делать, если пароль root всё же потерян, — в статьях как раздать доступ команде без выдачи root и сброс пароля root на VPS.

Конфиги и настройки: чужое решение — не универсальное

3. «Скопируй конфиг с форума один в один, он же рабочий у автора»

Звучит так: человек на форуме выложил свой nginx.conf или my.cnf, у него всё летает — копируем целиком, чтобы не разбираться в деталях.

Почему кажется рабочим: конфиг действительно откуда-то работает, синтаксис валиден, сервис стартует без ошибок — визуально всё в порядке.

Что реально ломается: в чужом конфиге зашиты пути, специфичные для его сервера (root /home/username/site;), версии ПО (директивы, которых нет в вашей версии nginx или MySQL, — сервис либо не стартует, либо тихо игнорирует опцию), и параметры под его нагрузку и железо. Частый случай — innodb_buffer_pool_size или worker_connections, взятые с сервера на 32 ГБ RAM и вставленные на VPS с 2 ГБ: сервис либо не запускается, либо съедает всю память и падает под первой же нагрузкой. Ещё хуже — когда в конфиге настройки безопасности заточены под чужую сетевую топологию: allow/deny с чужими IP-адресами разработчика, оставленные «для теста» debug-режимы.

Как правильно: брать чужой конфиг как референс, а не как готовый файл — построчно понимать, что делает каждая директива, и подставлять свои значения. Минимум — свериться с официальной документацией по каждому непонятному параметру и проверить конфиг перед применением:

nginx -t                      # проверка синтаксиса nginx перед reload
mysqld --validate-config      # аналог для MySQL/MariaDB

4. «Просто увеличь таймауты побольше, если что-то не успевает»

Звучит так: запрос падает по таймауту — значит, таймаут слишком маленький, увеличиваем proxy_read_timeout до 300 секунд, wait_timeout MySQL до часа, и ошибка уходит.

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

Что реально ломается: увеличенный таймаут не устраняет причину медленной операции — он просто прячет симптом и переносит проблему дальше по цепочке. Если запрос к базе выполняется 40 секунд, дело в отсутствующем индексе или блокировке, а не в лимите. С таймаутом в 300 секунд эта проблема продолжает происходить, но теперь незаметно — до тех пор, пока несколько таких запросов одновременно не займут все воркеры backend'а или все соединения к базе, и сервер не встанет колом уже целиком, причём диагностировать станет сложнее — конкретный «виновник» размывается среди десятков зависших запросов. Про похожую историю с зависаниями после рестарта — в статье MySQL не запускается после перезагрузки: там тоже симптом лечили не с той стороны.

Как правильно: сначала найти, что именно долго выполняется, и лечить это.

# MySQL: включить лог медленных запросов
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;

# посмотреть, что происходит прямо сейчас
SHOW PROCESSLIST;

Таймауты — это защита от аномалий, а не инструмент подгонки под медленную логику. Разумный таймаут стоит держать чуть выше типичного времени ответа при нормальной нагрузке, а не «с запасом побольше».

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Безопасность: выключить — не значит настроить

5. «Отключи firewall, если что-то не подключается, чтобы протестировать»

Звучит так: сервис не отвечает снаружи, непонятно — блокирует firewall или дело в самом сервисе. Быстрый способ проверить: systemctl stop firewalld или ufw disable, а потом «включу обратно, как протестирую».

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

Что реально ломается: firewall почти никогда не включают обратно вовремя — тестирование затягивается, переключаются на другую задачу, а сервер остаётся полностью открытым внешнему миру на неопределённое время. Дальше это вопрос часов, а не дней: автоматические сканеры находят открытые порты (SSH, базы данных, панели администрирования) почти сразу после появления сервера в интернете. Именно так базы MongoDB и Redis без аутентификации регулярно оказываются стёртыми и с запиской о выкупе — не потому что их специально искали, а потому что боты сканируют весь диапазон IP непрерывно. Похожая история бывает и с самим firewall, только наоборот — ошиблись в правиле и потеряли доступ, это разобрано в статье ошиблись в правиле firewall и потеряли доступ.

Как правильно: диагностировать точечно, не выключая защиту целиком — открыть конкретный порт для конкретного IP на время теста и сразу закрыть после:

# UFW: точечно разрешить порт с конкретного IP
ufw allow from 203.0.113.10 to any port 8080

# после теста — обязательно откатить
ufw delete allow from 203.0.113.10 to any port 8080

Если нужно быстро понять, firewall ли причина, — часто достаточно посмотреть его логи (journalctl -u ufw или iptables -L -v -n со счётчиками пакетов), не трогая сами правила.

6. «Отключи SELinux/AppArmor, он мешает всему работать»

Звучит так: приложение падает с непонятной ошибкой доступа, в логах ничего криминального, а в /var/log/audit/audit.log — что-то про avc: denied. Самый частый совет — setenforce 0 или aa-teardown и забыть.

Почему кажется рабочим: SELinux и AppArmor — это дополнительный уровень контроля поверх обычных прав Unix, и он действительно нередко блокирует легитимные действия нового сервиса, который никто под него не настраивал (нестандартный порт, нестандартный путь для веб-контента). Отключение снимает блокировку сразу и без разбора, в чём было дело.

Что реально ломается: вы не устранили конкретное ограничение — вы убрали весь механизм, который в том числе не даёт скомпрометированному процессу (тому же веб-серверу, если в нём найдут RCE-уязвимость) вылезти за пределы своей директории и полезть в чужие файлы или системные бинарники. Разница ощутима именно в инцидентах: с включённым SELinux/AppArmor эксплуатация уязвимости в одном сервисе часто остаётся локализованной; без него — процесс получает те же права, что и весь остальной софт на сервере.

Как правильно: разобраться, что именно заблокировано, и разрешить точечно, а не выключать целиком.

# SELinux: посмотреть, что реально блокируется
ausearch -m avc -ts recent

# сгенерировать точечное разрешающее правило под конкретный случай
audit2allow -a -M myapp
semodule -i myapp.pp

# для нестандартного порта — не выключать, а разрешить порт нужному сервису
semanage port -a -t http_port_t -p tcp 8090

Для AppArmor аналогично — профиль сервиса можно перевести в complain режим (логирует, но не блокирует) на время отладки, а не сносить целиком:

aa-complain /etc/apparmor.d/usr.sbin.nginx

Диагностика: спрятать симптом — не значит найти причину

7. «Перезагрузи сервер, если не понимаешь, в чём проблема»

Звучит так: сервис завис, память подъедена, сайт не отвечает — и вместо разбора сразу reboot. Через минуту всё снова работает, проблема как будто решена.

Почему кажется рабочим: перезагрузка действительно сбрасывает большинство острых симптомов — зависшие процессы, утечки памяти, забитые очереди соединений. Субъективный эффект «стало лучше» наступает мгновенно.

Что реально ломается: причина утечки или зависания никуда не делась, она просто откатилась во времени вместе с состоянием процессов. Если сервис тёк по памяти из-за бага, он потечёт снова — и рано или поздно перезагрузки понадобятся всё чаще, пока не станет ясно, что каждая из них съедает не только время, но и стирает важные диагностические данные: содержимое /tmp, состояние сетевых соединений, буферы логов, которые ещё не сброшены на диск. Отдельно неприятна ситуация, когда сама перезагрузка идёт не по плану — про это статьи сервер сам перезагрузился, как понять почему и перезагрузка растянулась на час — то есть даже привычный «быстрый рестарт» не гарантированно быстрый.

Как правильно: если перезагрузка неизбежна прямо сейчас (продакшн, простой недопустим) — сначала по возможности зафиксировать состояние, потом рестартовать, а разбор перенести на сразу после:

# снимок состояния перед рестартом
free -h > /root/incident-$(date +%F).log
ps aux --sort=-%mem | head -20 >> /root/incident-$(date +%F).log
journalctl -u myapp --since "-1 hour" >> /root/incident-$(date +%F).log
dmesg | tail -100 >> /root/incident-$(date +%F).log

Дальше — читать эти логи не «когда будет время», а как обязательный шаг после инцидента, иначе следующий рестарт будет по той же причине.

8. «Не нужны бэкапы, у меня же RAID»

Звучит так: данные и так дублируются на нескольких дисках, зачем ещё бэкапы — RAID переживёт отказ диска без потери данных.

Почему кажется рабочим: RAID (кроме RAID 0) действительно переживает отказ одного физического диска без потери данных — это его прямая задача, и в этом смысле совет не врёт наполовину.

Что реально ломается: RAID защищает только от одного конкретного сценария — физической поломки диска. Он не спасает от случайного rm -rf или DROP TABLE, от шифровальщика, от битой миграции базы, от ошибки в скрипте деплоя, который затирает продакшн-данные, — потому что все диски в массиве синхронно получают одну и ту же порчу данных, RAID добросовестно реплицирует и ошибку тоже. Отдельно — контроллер или сама рассыпающаяся конфигурация RAID могут быть источником проблемы, а не защитой от неё, если за массивом никто не следит: разбор ровно такого случая — в статье диск в RAID сыпался месяц, мониторинг молчал. Полный разбор того, почему RAID путают с резервной копией, — в статье миф: RAID — это резервная копия.

Как правильно: RAID и бэкапы решают разные задачи и нужны оба — RAID для доступности при отказе железа, бэкапы (желательно на отдельном физическом носителе или во внешнем хранилище) для восстановления после человеческой ошибки, атаки или логической порчи данных. Регулярный автоматизированный бэкап с проверкой восстановления — минимум для любого сервера с важными данными.

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

9. «Используй последнюю ночную/бета-версию, там самые новые фичи»

Звучит так: в стабильном релизе не хватает нужной функции или фикса, а в nightly/beta-ветке она уже есть — ставим её на прод, чтобы не ждать.

Почему кажется рабочим: формально это правда — нужная функция или патч в бета-версии действительно есть раньше, чем в стабильном релизе, и локально на тестовом стенде всё может работать без нареканий.

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

Как правильно: на проде — только стабильные релизы из официальных репозиториев с проверенной историей обновлений безопасности. Если нужная функция есть только в бете — тестировать её отдельно на некритичном окружении и ждать, пока она дойдёт до стабильного релиза, либо бэкпортировать конкретный патч, а не всю ветку целиком.

10. «Если не работает — сотри всё и накати систему заново»

Звучит так: сервер ведёт себя странно, куча накопленных настроек, непонятно, что где сломано — проще всего снести и поставить систему с нуля.

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

Что реально ломается: вместе с симптомом стирается и вся диагностическая информация о причине — логи, история изменений конфигов, состояние на момент сбоя. Если проблема была не в самой ОС, а во внешнем факторе — уязвимом коде приложения, скомпрометированном SSH-ключе, вредоносном cron-задании, оставленном атакующим, — переустановка системы её не устранит, а лишь отложит: причина не в системе, и через какое-то время всё повторится на чистом сервере с той же уязвимостью в том же приложении. Отдельная опасность — переустановка «для скорости» без снятия дампа базы или бэкапа конфигов превращает решаемую проблему в потерю данных.

Как правильно: переустановка — легитимный последний шаг, но после диагностики, а не вместо неё. Минимальный чек-лист перед сносом системы: снят бэкап данных и конфигов, изучены логи на предмет признаков компрометации (новые пользователи, неизвестные cron-задания, подозрительные процессы), понятна хотя бы примерная причина изначального сбоя — чтобы не воспроизвести её на новой системе.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Если я уже сделал chmod 777 на проде, как аккуратно откатить без падения сервиса?

Сначала определите реального владельца процесса (ps aux, systemctl status), затем выставьте chown на него и права 755/644 (или 750/640, если файлы не должны быть доступны на чтение остальным), проверьте работу сервиса сразу после — если что-то перестало работать, значит, права были нужны более узкой группе пользователей, чем предполагалось, и стоит разобраться точечно, а не возвращаться к 777.

Как понять, что таймаут увеличили правильно, а не просто спрятали проблему?

Если после увеличения таймаута среднее время ответа операции осталось прежним (просто перестали появляться ошибки по превышению лимита) — проблема спрятана, а не решена. Если вы нашли и устранили причину медленной операции (индекс, блокировка, N+1-запрос), а таймаут подняли лишь с небольшим запасом сверх нового нормального времени ответа — это правильная настройка.

Обязательно ли отключать root-логин по SSH, если я единственный, кто администрирует сервер?

Да, это стоит сделать в любом случае — боты постоянно перебирают пароли именно к учётной записи root по всему интернету, и отключение root-логина по SSH убирает эту атаку целиком независимо от того, сколько людей администрируют сервер.

RAID + бэкапы — это не избыточно для небольшого проекта?

Нет: RAID и бэкапы закрывают разные риски (отказ диска и человеческая/логическая ошибка соответственно), и для проекта любого размера, где данные хоть сколько-то ценны, отсутствие любого из двух — это не экономия, а отложенный риск полной потери данных.

Как быстро протестировать firewall-правило, не отключая firewall целиком?

Открыть конкретный порт для конкретного тестового IP одной командой (ufw allow from <IP> to any port <порт>), проверить, и сразу закрыть тем же способом с delete — это занимает не больше времени, чем полное отключение, но не оставляет сервер открытым, если про откат забудут.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →