Назад | Перейти на главную страницу

Многосайтовый хостинг - упускается важная уязвимость для защиты сайтов друг от друга?

РЕДАКТИРОВАТЬ №2 23 июля 2015 г .: Ищете новый ответ, который определяет важный элемент безопасности, пропущенный в приведенной ниже настройке, или может дать повод полагать, что все покрыто.

РЕДАКТИРОВАТЬ № 3 29 июля 2015 г .: Я особенно ищу возможную неправильную конфигурацию, например, непреднамеренное разрешение чего-то, что можно использовать для обхода ограничений безопасности или, что еще хуже, оставить что-то широко открытым.

Это настройка многосайтового / общего хостинга, и мы хотим использовать общий экземпляр Apache (то есть запускаемый под одной учетной записью), но с PHP / CGI, работающим от имени каждого пользователя веб-сайта, чтобы гарантировать, что ни один сайт не может получить доступ к файлам другого сайта, и мы хотим убедитесь, что ничего не упущено (например, если мы не знали о предотвращении атак по символическим ссылкам).

Вот что у меня есть на данный момент:

Я бы пошел с MPM ITK, если бы он не был таким медленным и не запускался от имени пользователя root, но мы специально хотим использовать общий Apache, но при этом убедитесь, что это безопасно.

я нашел http://httpd.apache.org/docs/2.4/misc/security_tips.html, но он не был исчерпывающим по этой теме.

Если это полезно знать, мы планируем использовать CloudLinux с CageFS и mod_lsapi.

Есть ли еще что-нибудь, о чем нужно знать или делать?

РЕДАКТИРОВАТЬ 20 июля 2015: Люди представили несколько хороших альтернативных решений, которые в целом ценны, но обратите внимание, что этот вопрос касается только безопасности общей установки Apache. В частности, есть ли что-то, что не описано выше, что могло бы позволить одному сайту получить доступ к файлам другого сайта или каким-то образом поставить под угрозу другие сайты?

Спасибо!

Я полностью согласен с тем, что у вас есть.

Раньше я запускал такую ​​многопользовательскую установку несколько лет назад и в основном обнаружил тот же компромисс: mod_php работает быстро (отчасти потому, что все выполняется внутри одного процесса), а suexec работает медленно, но безопасно (потому что каждый запрос порождает новый обработать). Я выбрал suexec, потому что требовалась изоляция пользователя.

В настоящее время вы можете рассмотреть третий вариант: предоставить каждому пользователю собственный демон php-fpm. Возможно ли это, зависит от количества пользователей, потому что каждый из них должен получить хотя бы один процесс php-fpm, используя свою учетную запись пользователя (затем демон использует механизм, подобный prefork, для масштабирования запросов, поэтому количество процессов и их использование памяти может быть ограничивающим фактором). Вам также понадобится автоматическая генерация конфигурации, но это можно сделать с помощью нескольких сценариев оболочки.

Я не использовал этот метод в больших средах, но ИМХО, это хорошее решение для обеспечения хорошей производительности веб-сайта PHP, но при этом изолировать пользователей на уровне процесса.

Уже предоставлено много хороших технических ответов (пожалуйста, также посмотрите здесь: https://security.stackexchange.com/q/77/52572 и Советы по защите LAMP-сервера), но я все же хотел бы упомянуть здесь важный момент (с другой точки зрения) о безопасности: безопасность - это процесс. Я уверен, что вы уже об этом думали, но я все же надеюсь, что было бы полезно (в том числе и для других читателей) иногда переосмыслить это.

Например, в вашем вопросе вы концентрируетесь в основном на технических мерах: «этот вопрос касается только безопасности общей установки Apache. В частности, есть ли какие-либо шаги безопасности, которые важно предпринять, но которые отсутствуют в приведенном выше списке при запуске общего доступа Apache и PHP ».

Почти все ответы здесь и на другие 2 вопроса, которые я упомянул, также кажутся чисто техническими (за исключением рекомендации оставаться в курсе). И, с моей точки зрения, это может создать у некоторых читателей ложное впечатление, что если вы однажды настроите свой сервер в соответствии с передовой практикой, то вы останетесь в безопасности навсегда. Поэтому не забывайте, пожалуйста, о моментах, которые я упускаю в ответах:

  1. Прежде всего не забывайте, что безопасность - это процесс и, в частности, о цикле «Планирование-Выполнение-Проверка-Действие», рекомендованном многими стандартами, включая ISO 27001 (http://www.isaca.org/Journal/archives/2011/Volume-4/Pages/Planning-for-and-Implementing-ISO27001.aspx). По сути, это означает, что вам необходимо регулярно пересматривать меры безопасности, обновлять и тестировать их..

  2. Регулярно обновляйте свою систему. Это не поможет против целевых атак с использованием уязвимостей нулевого дня, но поможет почти во всех автоматических атаках.

  3. Следите за своей системой. Я действительно упускаю этот момент в ответах. С моей точки зрения, чрезвычайно важно получать уведомление как можно раньше о какой-либо проблеме с вашей системой.

    Вот что об этом говорит статистика: «Среднее время от проникновения до обнаружения составляет 173,5 дня» (http://www.triumfant.com/detection.html), «Среднее количество дней до обнаружения 205 дней» (https://www2.fireeye.com/rs/fireye/images/rpt-m-trends-2015.pdf). И я надеюсь, что эти цифры - не то, что мы все хотим иметь.

    Существует множество решений (в том числе и бесплатных) не только для мониторинга состояния сервиса (например, Nagios), но и систем обнаружения вторжений (OSSEC, Snort) и систем SIEM (OSSIM, Splunk). Если это станет слишком сложным, вы можете хотя бы включить что-то вроде «fail2ban» и / или перенаправить свои журналы на отдельный сервер системного журнала и иметь Уведомления по электронной почте о важных событиях.

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

  4. Помните об уязвимостях. То же, что и мониторинг. Просто подпишитесь на список уязвимостей, чтобы получать уведомления об обнаружении критической уязвимости в Apache или другом сервисе, важном для вашей установки. Цель состоит в том, чтобы получать уведомления о наиболее важных событиях, которые появятся перед следующим запланированным обновлением.

  5. Составьте план, что делать в случае инцидента (и регулярно обновляйте и пересматривайте его в соответствии с вашим циклом «Планирование-Выполнение-Проверка-Действие»). Если вы задаете вопросы о безопасной настройке, это означает, что безопасность вашей системы становится для вас важной. Однако что делать, если ваша система взломана, несмотря на все меры безопасности? Опять же, я имею в виду не только технические меры, такие как «переустановка ОС»: куда вы должны сообщить об аварии в соответствии с действующим законодательством? Можно ли сразу выключить / отключить сервер (сколько это стоит для вашей компании)? К кому следует обращаться, если главное ответственное лицо находится в отпуске / заболело?

  6. Иметь сервер резервного копирования, архивирования и / или замены / репликации. Безопасность также означает доступность вашего сервиса. Регулярно проверяйте резервное копирование / архивирование / репликацию, а также регулярно тестируйте процедуры восстановления.

  7. Тестирование на проникновение? (опять же, см. цикл «Планируй-Выполняй-Проверяй-Действуй» :) Если кажется, что это слишком много, вы могли бы хотя бы попробовать некоторые бесплатные онлайн-инструменты, которые сканируют ваши веб-службы на наличие вредоносных программ и проблем с безопасностью.

SELinux может быть полезен с mod_selinux. Здесь представлено краткое руководство:

Как я могу использовать SELinux для ограничения скриптов PHP?

Поскольку инструкции немного устарели, я проверил, работает ли это на RHEL 7.1:

Я использовал Версия Fedora 19 и скомпилирован с макетом против RHEL 7.1 + EPEL.

YMMV, если вы используете базовый макет конфигурации epel, поставляется с:

[mockbuild@fedora mod_selinux]$ mock -r rhel-7-x86_64 --rebuild \
    mod_selinux-2.4.3-2.fc19.src.rpm

Сначала обновите целевую систему, чтобы убедиться, что selinux-policy актуален.

Установите на целевой ящик (или сначала установите на локальное зеркало):

yum localinstall mod_selinux-2.4.3-2.el7.x86_64.rpm

Теперь вы должны назначить каждому виртуальному хосту в apache категорию. Это делается путем добавления строки, такой как в приведенном ниже примере, которая называется selinuxDomainVal.

<VirtualHost *:80>
    DocumentRoot /var/www/vhosts/host1
    ServerName host1.virtual
    selinuxDomainVal *:s0:c0
</VirtualHost>

<VirtualHost *:80>
    DocumentRoot /var/www/vhosts/host2
    ServerName host2.virtual
    selinuxDomainVal *:s0:c1 
</VirtualHost>

Затем в корне документа для каждого хоста переименуйте их корни документов в ту же категорию, что и те, которые помечены в конфигурации httpd.

chcon -R -l s0:c0 /var/www/vhosts/host1
chcon -R -l s0:c1 /var/www/vhosts/host2

Если вы хотите, чтобы маркировка выполнялась, если вы выполняете перемаркировку системы, вам лучше также обновить локальную политику!

semanage fcontext -a -t httpd_sys_content_t -r s0-s0:c0 '/var/www/vhosts/host1(/.*)?' 
semanage fcontext -a -t httpd_sys_content_t -r s0-s0:c1 '/var/www/vhosts/host2(/.*)?'

Я бы посоветовал, чтобы каждый сайт работал под собственным демоном Apache, а Apache был удален. Все системные функции php завершатся сбоем, так как chroot-среда Apache не будет иметь доступа к / bin / sh. Это также означает, что функция php mail () также не будет работать, но если вы используете внешнего почтового провайдера для отправки почты из своего почтового приложения, то это не должно быть проблемой для вас.

Все, что у вас есть, кажется хорошо продуманным. Единственное, что я видел проблемой, это то, что большинство эксплойтов так или иначе стремятся получить root-доступ. Таким образом, даже если каждый сайт и его соответствующие процессы и скрипты правильно заключены в тюрьму и у всего есть собственный пользователь и разрешения, хакеру с root наплевать, они просто обойдут все, что вы настроили.

Я предлагаю использовать какое-то программное обеспечение виртуальных машин (VMware, VirtualBox, Qemu и т. Д.), Чтобы дать каждому сайту собственную тюрьму ОС. Это позволяет вам, как системному администратору, не беспокоиться об одном взломанном сайте. Если хакер получает root-права, используя php (или любое другое программное обеспечение) на виртуальной машине сайта, просто приостановите виртуальную машину и проанализируйте ее позже, примените исправления или откатитесь до непрерывного состояния. Это также позволяет администраторам сайта применять определенное программное обеспечение или настройки безопасности к своей конкретной среде сайта (что может нарушить работу другого сайта).

Единственное ограничение - ваше оборудование, но с приличным сервером и правильными расширениями ядра с этим легко справиться. Я успешно запустил этот тип настройки на Linode, при условии, что хост и гость были очень редкими. Если вам комфортно работать с командной строкой, как я полагаю, у вас не должно возникнуть проблем.

Этот тип настройки сокращает количество векторов атак, которые вы должны отслеживать, и позволяет вам сосредоточиться на безопасности хост-компьютеров и заниматься всем остальным на уровне каждого сайта.

Ваш вариант использования идеально подходит для контейнеров докеров.

Каждый контейнер может представлять клиента или клиента с уникальными идентификаторами пользователей, назначенными каждой группе контейнеров Apache в качестве дополнительной безопасности. Ключом было бы сбросить привилегии root при запуске контейнера перед запуском вашего стека apache. Каждый клиент получает свою собственную службу БД со своими уникальными паролями, без головной боли, связанной с запуском десятков виртуальных машин, каждая из которых требует собственных специальных ядер-снежинок и других накладных расходов. В конце концов, в основе docker лежит chroot. При правильном администрировании я в любой день возьму это на себя за типичный виртуальный кластер.

Здесь уже много хороших предложений. Однако есть вещи, которые до сих пор упускались из виду.

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

По моему опыту, такие вещи, как анализ журналов, когда они предоставляются службой хостинга, запускаются с правами root почти так же часто, как и нет, а программное обеспечение для анализа журналов не подвергается такому аудиту безопасности, как нам хотелось бы. Это немного сложно и зависит от настройки. С одной стороны, вы не хотите, чтобы ваш процесс apache, принадлежащий root (то есть родительский процесс), записывал в любой каталог, который пользователь может скомпрометировать. Вероятно, это означает, что нельзя писать прямо в тюрьму. С другой стороны, вам нужно сделать эти файлы доступными для процессов в тюрьме для анализа, и вы хотите, чтобы это происходило как можно ближе к реальному времени. Если вы можете предоставить своим тюрьмам доступ к монтированию файловой системы с журналами только для чтения, это должно быть хорошо.

Приложения PHP обычно не обслуживают свои собственные статические файлы, и если у вас есть общий процесс apache, я предполагаю, что ваш процесс apache считывает данные прямо из тюрем из среды хоста? Если так, то это вызывает множество опасений.

.htaccess файлы очевидны, и вам нужно быть очень осторожными с тем, что вы разрешаете. Многие, если не самые важные php-приложения, очень зависят от расположения файлов .htaccess, что вы, вероятно, не можете допустить, не нарушив запланированную схему.

Менее очевидно, как apache в любом случае решает, что такое статический файл. например Что он делает с *.php.gif или *.php.en файл? Если этот или другой механизм вводит в заблуждение дискриминацию относительно того, что такое статический файл, может ли apache вообще запускать php из-за пределов тюрьмы? Я бы установил отдельный легкий веб-сервер для статического контента, который не настроен с помощью каких-либо модулей для выполнения динамического контента, и имел бы балансировщик нагрузки, решающий, какие запросы отправлять на статический сервер, а какие - на динамический.

Что касается предложения Стефана Docker, можно иметь один веб-сервер, который находится вне контейнера и который общается с демонами php в каждом контейнере для динамического содержимого, а также иметь второй веб-сервер, который находится в контейнере докера, и который разделяет тома, которые каждый использует для своего контента, и, таким образом, может обслуживать статический контент, который почти такой же, как и в предыдущем абзаце. Я рекомендую докер среди различных подходов к типу тюрьмы, но с этим или другим подходом типа тюрьмы у вас будет куча других проблем, над которыми нужно работать. Как работает загрузка файлов? Вы помещаете демонов передачи файлов в каждый контейнер? Используете ли вы подход на основе git в стиле PAAS? Как сделать доступными журналы, сгенерированные внутри контейнера, и переворачивать их? Как вы управляете заданиями cron и выполняете их? Собираетесь ли вы предоставить пользователям какой-либо доступ к оболочке, и если да, то это еще один демон внутри контейнера? и т. д. и т. д.

Первое, что я не вижу, - это управление процессами, поэтому один процесс не может лишить другой процесс ЦП или ОЗУ (или ввода-вывода, если на то пошло, хотя ваша файловая система может быть спроектирована так, чтобы это предотвратить). Одно из основных преимуществ подхода «контейнеров» к вашим экземплярам PHP по сравнению с попыткой запустить их все в одном образе «ОС» состоит в том, что таким образом вы можете лучше ограничить использование ресурсов. Я знаю, что это не ваш дизайн, но это нужно учитывать.

В любом случае, вернемся к варианту использования PHP, работающего за Apache, в основном функционирующего как прокси. suexec делает не предотвратить запуск чего-либо от имени пользователя apache - он предоставляет способность для запуска от имени другого пользователя. Таким образом, одна проблема заключается в том, чтобы убедиться, что все сделано правильно - страница документации для этого указывает на эту потенциальную опасность: https://httpd.apache.org/docs/2.2/suexec.html. Итак, вы знаете, скепсис и все такое.

С точки зрения безопасности может быть полезно иметь ограниченный набор пользовательских двоичных файлов для работы (который предоставляет cagefs), особенно если они скомпилированы по-другому или с другой библиотекой (например, с той, которая не включает нежелательные возможности) но опасность в том, что в этот момент вы больше не следуете известному дистрибутиву для получения обновлений, вы следуете другому дистрибутиву (cagefs) для ваших установок PHP (по крайней мере, в отношении инструментов пользовательского пространства). Хотя, поскольку вы, вероятно, уже следуете за конкретным дистрибутивом с cloudlinux, это дополнительный риск, который не обязательно интересен сам по себе.

Я бы оставил AllowOverride там, где вы могли это задумать. Основная идея глубокоэшелонированной защиты состоит в том, чтобы не полагаться на один-единственный слой для защиты всего стека. Всегда предполагайте, что что-то может пойти не так. Смягчите, когда это произойдет. Повторяйте до тех пор, пока не будете максимально смягчены, даже если перед вашими участками стоит только один забор.

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

Это свалка моих мозгов. Надеюсь, там есть что-то не очень полезное. :)