Підвищення рівня безпеки LAMP за допомогою директиви Apache Proxy mod_proxy

Проект з розробки 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, стала продовженням робіт по досягненню цієї мети.


Рішення: 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 event Apache 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.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*