Повышение уровня безопасности LAMP при помощи директивы Apache Proxy mod_proxy

Виртуальный хостинг с использованием различных пользовательских идентификаторов возможен

В этой статье Ник Маинард дает краткое описание способа повышения безопасности настройки LAMP при помощи модуля Apache mod_proxy. Эта статья касается именно Linux, однако некоторые принципы могут применяться и в других операционных системах.

Ник Маинард (Nick Maynard), сценарный аналитик, IBM

Ник Маинард (Nick Maynard) работал в лаборатории сценарного анализа IBM в Харсли (Hursley) с момента поступления в IBM UK Ltd. после окончания в 2003 году Имперского колледжа науки, технологии и медицины. Он специализируется в областях Linux, Web-сервисов и интеграционных бизнес-технологий. Связаться с Ником можно по адресу nick.maynard@uk.ibm.com



17.05.2007

Проект по разработке HTTP-сервера фонда Apache Software Foundation, известный как Apache, в настоящее время является преобладающим Web-сервером в Интернете, согласно статистическим данным он занимает более 60 процентов рынка. Все больше и больше Apache используется как часть набора свободного программного обеспечения в конфигурации, известной как LAMP, Web-платформа, построенная на базе технологий с открытыми исходными кодами Linux®, Apache, MySQL и PHP. Из этой статьи вы узнаете о способе, позволяющем повысить безопасность установки LAMP путем использования модуля mod_proxy и нескольких внутренних серверов. Я расскажу вам о достоинствах и недостатках такого подхода, и вы увидите пример конфигурации работающей установки.

PHP и Apache: проблемы безопасности

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

Корень проблемы безопасности PHP лежит в том, как сконфигурировано большинство Apache-серверов. Поскольку большинство установок Apache работает под специальным пользовательским идентификатором www-data, весь пользовательский хостинг Web-сайта должен по умолчанию гарантировать, что файлы пользователей будут доступны для чтения этим пользователям. Следовательно есть вероятность, что все пользовательские файлы, доступные через Web, будут доступны всем другим пользователям системы и могут подвергнуться атаке со стороны других, не имеющих отношения к данной системе. Положение становится даже более сложным, когда файлы или каталоги должны быть доступны для записи для пользователя www-data.

Вы можете отчасти избежать этой проблемы при запуске программ CGI, например, написанных с использованием популярных языков Perl и Python, используя механизм suEXEC. Говоря коротко, suEXEC использует специальную промежуточную программу для выполнения программы CGI под пользовательским идентификатором, который является владельцем программы. (Ссылки на статьи с более подробным описанием см. в разделе Ресурсы.) Это очень эффективный механизм, традиционно использовавшийся в течение многих лет.

Однако хостинг страниц PHP с использованием модуля mod_php выполняется как часть основного процесса Apache. Собственно, страницы PHP наследуют все мандаты процесса Apache, и поэтому любые выполняемые на файловой системе действия должны выполняться от имени пользователя www-data.

Запуск Apache с использованием различных пользовательских идентификаторов

Очевидное решение описанной выше проблемы -- хостинг всех запросов для пользовательских доменов от копии Apache, которая имеет только этот пользовательский мандат. Вы можете сконфигурировать Apache так, чтобы при запуске принимать любые пользовательские мандаты. Это может решить проблему для несложных конфигураций, где каждому пользователю назначается индивидуальная комбинация IP адрес/порт, доступная через Интернет.

Для более сложных конфигураций, где IP-адреса пользуются большим спросом, этот метод не работает. Вы можете использовать только виртуальный хостинг -- метод, широко распространенный в установках Apache, где единственная копия Apache контролирует особую комбинацию IP адрес/порт. Это предотвращает возможность хостинга множества доменов, принадлежащих множеству пользователей с одной и той же комбинации IP адрес/порт.

В Apache 2.0 вводится понятие мультипроцессорных модулей (MPM). Среди модулей, предоставляемых с пакетом Apache 2.0, присутствует экспериментальный модуль perchild, позволяющий осуществлять виртуальный хостинг при множестве пользовательских идентификаторов путем назначения distributor-потока для комбинации IP адрес/порт и передачи запросов на satellite-потоки, выполняющиеся под индивидуальными пользовательскими мандатами. К сожалению, perchild оставался экспериментальным и функционировал только в случае удачи и в конце концов был удален из официального Apache, начиная с версии 2.2. Перед этим, понимая, что необходимость в наличии стабильного функционирующего perchild-подобного модуля сохраняется, сообщество Apache начало работу по созданию модулей MPM, способных заполнить образовавшийся пробел. Разработка MetuxMPM и его подпроцесса, созданного через fork, peruser, явилась продолжением работ по достижению этой цели. (Ссылки на статьи с описанием модулей MetuxMPM и peruser см. в разделе Ресурсы).


Решение: mod_proxy

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

Листинг 1. Пример конфигурации обратного прокси для переадресации основного запроса
ProxyRequests Off

ProxyPass /foo http://foo.example.com/bar
ProxyPassReverse /foo http://foo.example.com/bar

Код в Листинге 1 -- простой пример, в котором показано перенаправление запроса любой страницы хоста /foo на соответствующую страницу, размещаемую на http://foo.example.com/bar. Например, страница /foo/index.htm будет перенаправлена на http://foo.example.com/bar/index.htm. Вы можете использовать этот принцип для решения проблемы.

Пример сценария

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

Таким образом, у администратора имеется два домена: www.startup.tld, принадлежащий недавно созданной онлайн компании (идентификатор пользователя startup), и www.reckless.tld, принадлежащий частному лицу (идентификатор пользователя nimrod). Для решения проблемы администратор принял решение использовать mod_proxy. Администратор выдал каждому пользователю его собственную копию Apache, запущенную под его собственным ID на приватной комбинации IP-адрес/порт, и использовал решение mod_proxy для предоставления доступа к обоим доменам через наружный сервер, запущенный под ID www-data на публичной комбинации IP-адрес/порт. Законченный сценарий показан на Рисунке 1.

Рисунок 1. Образец сценария
Образец сценария

Рекомендуемые версии Apache

Для каждого элемента конфигурации в нашем образце приложения администратор Apache должен использовать версии Apache, перечисленные в Таблице 1.

Таблица 1. Версии Apache, использованные в примере приложения
ЭлементВерсия ApacheОбъяснение
Внешний серверApache 2, выполняющий MPM worker или MPM eventApache 2 добавляет важное расширение для модуля mod_proxy. MPM worker и MPM event выполняются в виде thread'ов и помогают уменьшить непроизводительный расход памяти на внешнем сервере.
Внутренние серверыApache 1.3, или Apache 2, выполняющие prefork MPMАдминистратор Apache должен осознавать, что модуль PHP не должен запускаться под thread-окружением. Эти два варианта предлагают основанные на порождении процессов окружения для модуля PHP.

Конфигурирование внутренних Apache instance

Фрагменты Листингов 2 и 3 иллюстрируют важные моменты конфигурирования, отличающиеся от стандартной конфигурации Apache. Их необходимо добавлять в случае необходимости. Так, в пример конфигурации не включена функциональность PHP.

Листинг 2. Конфигурация Apache для недавно созданной онлайн компании
# Stuff every Apache configuration needs
ServerType standalone
LockFile /var/lock/apache/accept.startup.lock
PidFile /var/run/apache.startup.pid

ServerName necessaryevil.startup.tld
DocumentRoot "/home/startup/web"

# Essential modules
LoadModule access_module /usr/lib/apache/1.3/mod_access.so

# Which user to run this Apache configuration as
User startup
Group startup

# This must be off else the host isn't passed correctly
UseCanonicalName Off

# The IP/port combination to listen on
Listen 127.0.0.2:10000

# Using name-based virtual hosting allows you to host multiple sites per IP/port combo
NameVirtualHost 127.0.0.2:10000

<VirtualHost 127.0.0.2:10000>
        ServerName www.startup.tld

        # You can add aliases so long as the facade server is aware of them!
        ServerAlias startup.tld

        DocumentRoot "/home/startup/web/www.startup.tld"

        <Directory /home/startup/web/www.startup.tld/>
            Options Indexes FollowSymLinks MultiViews ExecCGI Includes
            AllowOverride All
            Order allow,deny
            Allow from all
        </Directory>

</VirtualHost>
Листинг 3. Конфигурация Apache для частного клиента
# Stuff every Apache configuration needs
ServerType standalone
LockFile /var/lock/apache/accept.nimrod.lock
PidFile /var/run/apache.nimrod.pid

ServerName necessaryevil.nimrod.tld
DocumentRoot "/home/nimrod/web"

# Essential modules
LoadModule access_module /usr/lib/apache/1.3/mod_access.so

# Which user to run this Apache configuration as
User nimrod
Group nimrod

# This must be off else the host isn't passed correctly
UseCanonicalName Off

# The IP/port combination to listen on
Listen 127.0.0.2:10001

# Using name-based virtual hosting allows you to host multiple sites per IP/port combo
NameVirtualHost 127.0.0.2:10001

<VirtualHost 127.0.0.2:10001>
        ServerName www.reckless.tld

        # You can add aliases so long as the facade server is aware of them!
        ServerAlias reckless.tld

        DocumentRoot "/home/nimrod/web/www.reckless.tld"

        <Directory /home/nimrod/web/www.reckless.tld/>
            Options Indexes FollowSymLinks MultiViews ExecCGI Includes
            AllowOverride All
            Order allow,deny
            Allow from all
        </Directory>

</VirtualHost>

В Листинге 4 показана конфигурация для внешнего instance Apache.

Листинг 4. Конфигурация Apache для внешнего instance Apache
# Stuff every Apache configuration needs
LockFile /var/lock/apache/accept.www-data.lock
PidFile /var/run/apache.www-data.pid

ServerName necessaryevil.facade.server
DocumentRoot "/home/www-data"

# Essential modules
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so

# Which user to run this Apache configuration as
User www-data
Group www-data

# These must be set else the host isn't passed correctly
UseCanonicalName Off
ProxyVia On
ProxyRequests Off
# This must also be set, though it's only an option in Apache2
ProxyPreserveHost On    

# The IP/port combination to listen on
Listen 9.20.1.1:80

# Using name-based virtual hosting allows you to host multiple sites per IP/port combo
NameVirtualHost 9.20.1.1:80

# Configuration to forward requests for startup.tld
<VirtualHost 9.20.1.1:80>
        ServerName www.startup.tld
        ServerAlias startup.tld

        ProxyPass / http://127.0.0.2:10000/
        ProxyPassReverse / http://127.0.0.2:10000/
        ProxyPassReverse / http://www.startup.tld:10000/
        ProxyPassReverse / http://startup.tld:10000/
</VirtualHost>

# Configuration to forward requests for reckless.tld
<VirtualHost 9.20.1.1:80>
        ServerName www.reckless.tld
        ServerAlias reckless.tld

        ProxyPass / http://127.0.0.2:10001/
        ProxyPassReverse / http://127.0.0.2:10001/
        ProxyPassReverse / http://www.reckless.tld:10001/
        ProxyPassReverse / http://reckless.tld:10001/
</VirtualHost>

Здесь важно отметить директиву ProxyPreserveHost. Эта директива появилась, начиная с версии Apache 2. Она решает некоторые проблемы перенаправления на внутренние серверы корректных заголовков HTTP. Настоятельно рекомендуется использовать Apache 2 instance в качестве внешнего сервера.

Запуск примера конфигурации

Все конфигурации выполняет пользователь root. Apache берет привилегии, требуемые конфигурационным файлом для всех связанных с хостингом процессов. В Листинге 5 показано, как это запустить.

Листинг 5. Запуск серверов примера
/usr/sbin/apache -f /etc/apache/startup.tld.conf
/usr/sbin/apache -f /etc/apache/nimrod.tld.conf
/usr/sbin/apache2 -f /etc/apache2/facade.tld.conf

Ограничения mod_proxy

Крайне важно заметить, что метод, описанный в этой статье, не будет работать с доменами, требующими SSL-соединений. Это происходит потому, что протокол SSL не позволяет виртуальный хостинг доменов. Вследствие этого ограничения любой SSL-хостинг должен осуществляться способом, когда каждый домен SSL имеет хостинг на своей собственной комбинации IP/порт. Это ограничение касается всех конфигураций Apache, не только тех, которые используют это решение. Тем не менее вы можете запускать домены SSL под идентификатором пользователя их владельца.


Заключение

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

Ресурсы

Научиться

  • Оригинал этого учебного пособия на developerWorks.
  • suEXEC support: получите документацию непосредственно от Apache и узнайте, как уменьшить риски, связанные с безопасностью, когда ваши пользователи разрабатывают и запускают личные программы CGI или SSI.
  • Introduction to LAMP technology (Jono Bacon, developerWorks, май 2005): в этом учебном пособии, которое является хорошим введением в Linux-Apache-MySQL-PHP или LAMP, Web-среду разработки, поищите решения распространенных проблем.
  • developerWorks Web development zone.
  • Linux zone.
  • Technology bookstore: здесь вы найдете список книг на эти и другие технические темы.
  • Технические события developerWorks и интернет-конференции: участвуйте в текущих технических сессиях, которые позволят сократить вашу кривую обучения и повысить качество и улучшить результаты ваших самых трудных проектов разработки программного обеспечения.

Получить продукты и технологии

  • peruser MPM: узнайте больше об этом MPM, базирующемся на metuxmpm модуле Apache 2, являющемся работающей реализацей perchild MPM.
  • IBM trial software: постройте ваш следующий проект разработки при помощи этих средств, доступных непосредственно с developerWorks.
  • Зона developerWorks Web Development Downloads and products: найдите продукты, доступные для свободного выкачивания.

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux, Open source, Web-архитектура
ArticleID=223669
ArticleTitle=Повышение уровня безопасности LAMP при помощи директивы Apache Proxy mod_proxy
publish-date=05172007