Большинство статей по безопасности Joomla повторяют одни и те же рекомендации: обновляйтесь, используйте сложные пароли, ставьте Admin Tools. Это работает, но есть и другой путь — защита на уровне файловой системы и веб-сервера, которая не зависит от уязвимостей в коде.
В этой статье я поделюсь методами, которые применил на реальном проекте (интернет-магазин на Joomla + VirtueMart) и которые кардинально отличаются от стандартных подходов.
Основная идея: запретить, а не лечить
Традиционный подход к безопасности Joomla строится на обнаружении и блокировке атак через плагины (Admin Tools, RSFirewall и т.д.). Мой подход — превентивный: даже если злоумышленник найдет уязвимость и загрузит вредоносный файл, он не сможет его выполнить.
Это достигается через два ключевых механизма:
- Запрет выполнения PHP на уровне веб-сервера (Nginx) в папках, где его быть не должно
- Защита файлов от изменения на уровне файловой системы (chattr +i)
1. Запрет выполнения PHP через Nginx
Стандартный подход (неэффективный)
Обычно в Joomla используют .htaccess с правилами вроде:
<FilesMatch "\.(php|phtml)$">
Order allow,deny
Deny from all
</FilesMatch>
Но это работает только в Apache и не защищает от обхода через другие расширения.
Мой подход (Nginx)
В конфигурации Nginx я добавил следующие блоки:
1.1. Защита папок загрузок и кэша
# ЗАПРЕТ PHP В ПАПКАХ ЗАГРУЗОК
location ~* ^/(images|media|stories)/.*\.(php|phtml|php\d*|phar)$ {
deny all;
return 403;
}
# ЗАПРЕТ PHP В ПАПКАХ КЭША И ВРЕМЕННЫХ
location ~* ^/(tmp|cache|administrator/cache|images/tmp)/.*\.(php|phtml|php\d*|phar)$ {
deny all;
return 403;
}
Почему это работает:
- Перехватывает любой запрос к PHP-файлам внутри этих папок
- Возвращает 403 Forbidden, даже если файл физически существует
- Не зависит от Joomla или PHP
1.2. Защита конфигурационного файла
# ЗАПРЕТ ДОСТУПА К CONFIGURATION.PHP
location ~ ^/configuration\.php$ {
deny all;
return 403;
}
1.3. Защита специфических папок сторонних компонентов
# ЗАПРЕТ PHP В ПАПКЕ com_excel2vm/xls
location /administrator/components/com_excel2vm/xls/ {
location ~ \.(php|phtml|php\d*|phar)$ {
deny all;
return 403;
}
}
1.4. Запрет листинга директорий
location / {
autoindex off;
try_files /does_not_exists @fallback;
}
2. Защита файлов через chattr +i (неизменяемость)
Этот метод я считаю самым мощным, но о нем почти не пишут в контексте Joomla.
Что такое chattr +i?
Команда chattr +i делает файл неизменяемым. Даже root не сможет его изменить, переименовать или удалить, пока атрибут не будет снят.
# Защита файлов от изменения chattr +i /var/www/www-root/data/www/mi55.ru/index.php chattr +i /var/www/www-root/data/www/mi55.ru/configuration.php chattr +i /var/www/www-root/data/www/mi55.ru/defines.php
Что я защитил рекурсивно
# Защита всех компонентов, модулей, плагинов chattr -R +i /var/www/www-root/data/www/mi55.ru/components/ chattr -R +i /var/www/www-root/data/www/mi55.ru/administrator/components/ chattr -R +i /var/www/www-root/data/www/mi55.ru/modules/ chattr -R +i /var/www/www-root/data/www/mi55.ru/plugins/ chattr -R +i /var/www/www-root/data/www/mi55.ru/templates/ chattr -R +i /var/www/www-root/data/www/mi55.ru/libraries/ chattr -R +i /var/www/www-root/data/www/mi55.ru/api/ chattr -R +i /var/www/www-root/data/www/mi55.ru/cli/
Почему это эффективно
- Даже если злоумышленник получит доступ к файловой системе (например, через LFI), он не сможет изменить код
- Защита сохраняется после обновлений (нужно только временно снять атрибут)
- Работает на уровне ядра Linux — обойти сложнее, чем права доступа (chmod)
Проверка защиты
# Просмотр защищенных файлов lsattr /var/www/www-root/data/www/mi55.ru/*.php | grep "i-" # Результат: ----i---------e------- /var/www/.../configuration.php ----i---------e------- /var/www/.../defines.php ----i---------e------- /var/www/.../index.php
3. Регулярная очистка мусора
Не менее важный аспект — удаление лишних файлов, которые могут стать вектором атаки.
Что я удалил:
- Файлы macOS (
._*,.DS_Store,__MACOSX) — они не нужны для работы - Бэкапы в корне (папка
/1C_DB_Backup/была удалена) - Пустые или подозрительные файлы (например,
components/com_excel2vm/excel2vm.phpразмером 0 байт)
# Скрипт очистки
find /var/www/www-root/data/www/mi55.ru -name "._*" -type f -delete
find /var/www/www-root/data/www/mi55.ru -name ".DS_Store" -type f -delete
find /var/www/www-root/data/www/mi55.ru -name "__MACOSX" -type d -exec rm -rf {} \;
Сравнение с традиционными методами
| Аспект | Традиционный подход | Мой подход |
|---|---|---|
| Защита от выполнения PHP | Плагины (Admin Tools) | Nginx (серверный уровень) |
| Защита файлов | Права доступа (chmod) | Неизменяемость (chattr +i) |
| Защита конфигурации | .htaccess | Запрет в Nginx + chattr |
| Зависимость от Joomla | Высокая | Минимальная |
| Обход через уязвимости | Возможен | Затруднен |
| Сложность настройки | Низкая | Средняя |
| Надежность | Средняя | Высокая |
Важные нюансы
1. Обновление компонентов
При обновлении Joomla или VirtueMart необходимо временно снять защиту:
# Снятие защиты перед обновлением chattr -i /var/www/www-root/data/www/mi55.ru/index.php chattr -R -i /var/www/www-root/data/www/mi55.ru/libraries/ # ... выполнить обновление ... # Повторное применение защиты chattr +i /var/www/www-root/data/www/mi55.ru/index.php chattr -R +i /var/www/www-root/data/www/mi55.ru/libraries/
2. Папки, которые нельзя защищать
Некоторые папки должны оставаться доступными для записи:
# НЕ ЗАЩИЩАТЬ! /tmp/ /cache/ /administrator/cache/ /images/ /media/ /stories/ /logs/ /t3-assets/
Мониторинг и поддержка
Для поддержания безопасности я использую простой скрипт:
#!/bin/bash # /usr/local/bin/security-check.sh SITE="/var/www/www-root/data/www/mi55.ru" echo "=== ПРОВЕРКА НОВЫХ PHP-ФАЙЛОВ ===" find $SITE -name "*.php" -mtime -1 -not -path "*/tmp/*" -not -path "*/cache/*" 2>/dev/null echo "=== ПРОВЕРКА ЗАЩИЩЕННЫХ ФАЙЛОВ ===" lsattr $SITE/*.php 2>/dev/null | grep "i-" echo "=== ПРОВЕРКА ПРАВ ДОСТУПА ===" find $SITE -type f -perm /111 -name "*.php" 2>/dev/null | head -10
Результаты
После применения этих методов:
- Все проверки безопасности пройдены — curl-запросы к защищенным папкам возвращают 403
- Сайт работает стабильно — никаких проблем с производительностью
- Нет ложных срабатываний — легитимные запросы проходят нормально
- Упрощен мониторинг — теперь я проверяю только новые файлы, а не их содержимое
Заключение
Традиционные методы защиты Joomla хороши, но они не дают полной гарантии. Добавление серверного уровня защиты (Nginx) и неизменяемости файлов (chattr +i) создает многоуровневую систему, которую сложно обойти даже при наличии уязвимости в коде.
Этот подход требует больше времени на первоначальную настройку, но окупается за счет:
- Минимальной зависимости от Joomla-плагинов
- Защиты даже в случае компрометации файловой системы
- Простоты мониторинга и обслуживания
Помните: безопасность — это процесс, а не состояние. Регулярно проверяйте новые файлы, обновляйте компоненты и адаптируйте защиту под меняющиеся угрозы.