LAMP — это программный стек, состоящий из Linux (операционной системы, которая является базовым уровнем), Apache (веб-сервера, который «сидит сверху ОС), MySQL (или MariaDB, системы управления реляционной базой данных) и, наконец, PHP (скриптовый язык на стороне сервера, который используется для обработки и отображения информации сохранённой а базе данных).
В этой статье мы предполагаем, что каждый компонент стека LAMP уже установлен и запущен, и мы сфокусируемся исключительно на защите LAMP сервера(ов). Мы должны помнить, тем не менее, что защита на стороне сервера — это очень обширная тема и, следовательно, не может быть решена должным образом и полностью в одной статье.
В этом посте мы осветим базовые, необходимые действия для защиты каждой части стека.
Защита Linux
Так как, возможно, вы хотите управлять вашим сервером CentOS через ssh, вам нужно рассмотреть следующий совет по безопасности удалённого доступа к серверу, отредактировав файл /etc/ssh/sshd_config file.
1) Используйте всегда, когда это возможно, аутентификацию основанную на ключе вместо базовой аутентификации (имя пользователя + пароль) для удалённого входа на ваш сервер. Мы предполагаем, что вы уже создали пару ключей с вашим именем пользователя на вашей клиентской машине и скопировали его на ваш сервер (смотрите этот урок).
PasswordAuthentication no RSAAuthentication yes PubkeyAuthentication yes
2) Поменяйте порт, который будет прослушиваться sshd. Хорошая идея сделать номер порта выше чем 1024:
Port XXXX
3) Разрешите только протокол 2:
Protocol 2
4) Настройте аутентификационный таймаут, не разрешайте вход под рутом и ограничьте пользователей, который могут войти через ssh:
LoginGraceTime 2m PermitRootLogin no AllowUsers gacanepa
5) Разрешите только определённые хосты (и/или сети) для входа по ssh:
В файле the /etc/hosts.deny:
sshd: ALL
В файле the /etc/hosts.allow:
sshd: XXX.YYY.ZZZ. AAA.BBB.CCC.DDD
где XXX.YYY.ZZZ. Представляет первые 3 байта (октета) сетевого адреса IPv4, а AAA.BBB.CCC.DDD это IPv4 адрес. С этими настройками только хосты из сети XXX.YYY.ZZZ.0/24 и хосты AAA.BBB.CCC.DDD будут допущены для связи через ssh. Все другие хосты будут отключены до того, как они получат приглашение на ввод учётных данных и получат ошибку вроде этой:
(Не забудьте перезагрузить демон sshd, чтобы изменения вступили в силу: service sshd restart).
Мы должны отметить, что такое решение — быстрый, но, в некоторой степени, рудиментарный способ блокировки входящих соединений на ваш сервер. Для дальнейшей настройки, масштабирования и гибкости вам следует рассмотреть использование простых iptables и/или fail2ban.
Защита Apache
1) Убедитесь, что системный пользователь, под которым запущен веб-сервер Apache, не имеет доступа к шеллу:
# grep -i apache /etc/passwd
Если пользователь apache имеет дефолтный шелл (такой как /bin/sh), мы должны изменить это на /bin/false или /sbin/nologin:
# usermod -s /sbin/nologin apache
Следующие предложения (со второго по пятый) относятся к файлу /etc/httpd/conf/httpd.conf:
2) Отключение листинга каталогов: это предотвратит отображение содержимого каталогов в браузере, если в каталоге отсутствует индексный файл (index.html, index.htm, index.php).
Удалите слово Indexes в директиве Options:
# The Options directive is both complicated and important. Please see # http://httpd.apache.org/docs/2.2/mod/core.html#options # for more information. # Options Indexes FollowSymLinks
Должно получиться:
Options None
В дополнение, вам нужно убедиться, что настройки директорий и виртуальных хостов не переопределяют глобальную конфигурацию.
Следуя примеру выше, если мы рассмотрим настройки для каталога /var/www/icons, мы увидим, что "Indexes MultiViews FollowSymLinks" должны быть изменены на "None".
<Directory "/var/www/icons"> Options Indexes MultiViews FollowSymLinks AllowOverride None Order allow,deny Allow from all </Directory> |
<Directory "/var/www/icons"> Options None AllowOverride None Order allow,deny Allow from all </Directory> |
До | После |
3) Спрячьте версию Apache, а также информацию об модулях/ОС в сообщениях об ошибках (например, на странице, которая не найдена или запрещена для просмотра.
ServerTokens Prod # Это означает, что ответ http вернёт просто "Apache" но не номер версии ServerSignature Off # Информация об ОС спрятана
4) Отключите ненужные модули, закомментировав линии, где эти модуля декларируются:
ПОДСКАЗКА: отключение autoindex_module — это другой способ спрятать листинг каталогов в которых нет индексного файла.
5) Ограничьте размер HTTP запроса (тело и заголовки) и установите таймаут соединения:
Директива | Контекст | Пример и значение |
LimitRequestBody | серверный config, virtual host, directory, .htaccess |
Ограничьте размер выгружаемого файла максимальными 100 KiB. для директории выгрузки:
<Directory "/var/www/test/uploads"> LimitRequestBody 102400 </Directory> Эта директива определяет размер байт с 0 (значит неограничено) до 2147483647 (2GB), что разрешено в теле запроса. |
LimitRequestFieldSize | серверный config, virtual host |
Измените разрешённый размер заголовок HTTP запроса на 4KiB (по умолчанию — 8KiB), серверная ширина:
LimitRequestFieldSize 4094 Эта директива определяет величину байтов, которая разрешена в заголовке запроса HTTP и даёт администратору лучший контроль над ненормальным поведением клиентских запросов, которые могут быть полезны для избежания некоторых форм атак отказа в обслуживании. |
TimeOut | серверный config, virtual host |
Измените таймаут с 300 (это значение по умолчанию, если не задана величина) на 120:
TimeOut 120 Количество времени в секундах, сервер будет ждать определённых событий перед сбросом запроса. |
Ещё больше директив и инструкций, а также информацию по их настройке вы найдёте в документации Apache.
Защита MySQL сервера
Мы начнём с запуска скрипта mysql_secure_installation, который поставляется с пакетом mysql-server.
1) Если мы не установили пароль рута для MySQL сервера во время установки, сейчас самое время сделать это, и помните: это основа в производственной среде.
Процесс продолжается:
2) Удалите анонимного пользователя:
3) Разрешите рут доступ только с локалхоста:
4) Удалите дефолтную базу данных под названием test:
5) Примените изменения:
6) Следующее, мы отредактируем некоторые переменные в файле
[mysqld] bind-address=127.0.0.1 # MySQL будет принимать соединения только с localhost local-infile=0 # Отключение прямого доступа к файловой системе log=/var/log/mysqld.log # Включение лог файла, чтобы видеть зловредную активность
Не забудьте перезапустить MySQL сервер с 'service mysqld restart'.
Сейчас, когда мы пришли к рутинному администрированию базой данных, вы найдёте следующие предложения полезными:
- Если по каким-то причинам нам нужно управлять базой данных удалённо, мы можем делать это, вначале, соединившись через ssh к нашему серверу для выполнения необходимых запросов и административных задач локально.
- Мы можем захотеть включить прямой доступ к файловой системе позже, например, если нам нужно выполнить массовый импорт файлов в базу данных.
- Храните логи, это не так критично, как первые две вещи упомянутые ранее, но может пригодиться для решения проблем нашей базы данных и/или быть в курсе незнакомой деятельности.
- НИКОГДА НЕ сохраняйте чувствительную информацию (такую как пароли, номера кредитных карт, банковские ПИНы — названо только несколько примеров) в простом текстовом формате. Подумайте об использовании функций хэша для обфускации этой информации.
- Убедитесь, что специфичные для приложений базы данных могут быть доступны только соответствующим пользователям, которые были созданы приложением для этой цели.
Для настройки разрешений доступа пользователей MySQL, используйте эти инструкции.
Вначале получите список пользователей из таблицы user:
gacanepa@centos:~$ mysql -u root -p
Enter password: [Здесь ваш пароль рута] mysql> SELECT User,Host FROM mysql.user;
Убедитесь, что каждый пользователь имеет только доступ (и минимальные разрешения) к базе данных, которая ему нужна.
В следующем примере мы проверим разрешения пользователя db_usuario:
mysql> SHOW GRANTS FOR 'db_usuario'@'localhost';
Вы можете отменять разрешения и доступ по мере необходимости.
Защита PHP
Поскольку эта статья ориентирована на безопасность компонентов стэка LAMP, мы не будем вдаваться в подробности, сколько озабоченности вызывает программная ипостась. Мы будем исходить из предположения, что наши веб-приложения безопасны, в том смысле, что разработчики должным образом выполнили свою задачу и убедились, что отсутствуют уязвимости, которые могут дать место для обычных атак, таких как XSS или SQL инъекции.
1) Отключите ненужные модули:
Мы можем отобразить листинг текущих модулей следующей командой: php -m
И отключите те, которые не нужны, либо удалением, либо переименованием соответствующего файла в каталоге /etc/php.d.
Например, поскольку расширение mysql стало устаревшим с версии PHP v5.5.0 (и будет удалено в будущем), мы можем захотеть отключить его:
# php -m | grep mysql # mv /etc/php.d/mysql.ini /etc/php.d/mysql.ini.disabled
2) Спрячьте информацию о версии PHP:
# echo "expose_php=off" >> /etc/php.d/security.ini [или отредактируйте файл security.ini, если он уже существует]
3) Задайте open_basedir к нескольким специфичным каталогам (в php.ini), чтобы ограничеть доступ к базовой файловой системе:
4) Отключите удалённое выполнение кодов/команд, наряду с очень эксплуатируемыми функциями, такими как exec(), system(), passthru(), eval() и так далее (в php.ini):
allow_url_fopen = Off allow_url_include = Off disable_functions = "exec, system, passthru, eval"
Подведение итогов
1) Храните пакеты обновленными до их последних версий (сравнивайте вывод следующих команд с выводом 'yum info [package]'):
Следующие команды выведут текущие версии Apache, MySQL и PHP:
# httpd -v # mysql -V (capital V) # php -v
Затем 'yum update [package]' может быть использована для обновления пакета, чтобы иметь последние патчи безопасности.
2) Убедитесь, что конфигурационные файлы могут быть записаны только аккаунтом рута:
# ls -l /etc/httpd/conf/httpd.conf # ls -l /etc/my.cnf # ls -l /etc/php.ini /etc/php.d/security.ini
3) Наконец, если у вас есть такая возможность, запустите эти сервисы (веб-сервер, сервер базы данных и сервер приложений) в отдельной физической или виртуальных машинах (и защитите связь между ними посредством файервола), т. е. в случае если один из них будет скомпрометирован, атакующий не будет иметь немедленного доступа к другим. В этом случае, возможно вам придётся изменить некоторые из конфигураций, описанных в этой статье. Помните, что это всего лишь некоторые примеры, которые могут быть использованы для увеличения безопасности на вашем LAMP сервере.
Отличная статья, тут не предлагают включить глобальные переменные для php и отключить файрволл))