Apache як проксі-сервер, бібліотека Лінуксцентра http

Apache httpd давно завоював славу самого популярного в світі web-сервера. Однак, багато хто навіть не здогадуються, що він може скласти конкруенцію не тільки IIS, а й Squid.

Розглянемо типову для невеликої організації конструкцію: шлюз в Інтернет, що працює під управлінням Unix або Microsoft Windows, проксі-сервер, web-сервер мережі Інтранет, поштовий сервер і т.д. Виявляється, число її елементів можна дещо скоротити, і відповідно до золотим правилом інженера, збільшити тим самим загальну надійність системи. Сьогодні ми поговоримо про делегування Apache основних функцій кешуючого проксі-сервера (наприклад, Squid) і навіть дечого понад них. В якості базової ОС будемо використовувати Linux, хоча багато що зі сказаного нижче може бути без обмеження спільності застосовано і для інших платформ.

Згоден, використання Apache в якості проксі-сервера виглядає дещо нестандартно, однак, воно має ряд переваг. Це, в першу чергу, можливість динамічного стиснення документів, що відправляються клієнтам, що може вилитися в серйозну економію, якщо для передачі даних використовується орендований канал з помегабайтной оплатою вхідного трафіку (припустимо, офісів у фірми два, а сервер всього один). Крім того, воно скорочує число сервісів, що працюють в системі, а значить, у потенційного зловмисника буде менше мішеней для проведення атаки, а у адміністратора, в свою чергу, менше об'єктів, що вимагають невсипущого спостереження і підтримки. Втім, як і все в нашому недосконалому світі, Apache в ролі проксі-сервера має і деякі недоліки, як-то: містить експериментальні або написані сторонніми розробниками модулі (при бажанні можна обійтися і без них) і невідомим чином поводиться при збільшенні навантаження ( цілком допускаю, що все буде чудово працювати, однак, спеціалізованого стрес-тестування не проводив). Яка чаша переважить - вирішувати вам. Керуючись особистим досвідом, я цілком можу рекомендувати застосування проксі-сервера на базі Apache в невеликих мережах.

Покінчивши з теоретичними питаннями, перейдемо до технічних деталей. Для реалізації задуманого нам знадобиться Apache версії 2.0.53 і вище (більш ранні версії мають помилки в mod_cache, що перешкоджають нормальній роботі з кешуватися документами) з включеними mod_proxy, mod_cache і mod_deflate. На відміну від спеціалізованих рішень на зразок згаданого вище Squid, проксі-сервер на базі Apache має істотно модульну архітектуру, всі мислимі і немислимі функції якої побудовані за принципом: загальна база + провайдери. Ми не раз переконаємося в цьому по ходу викладу. Отже, приступимо до першої фази:

Запуск проксі-сервера

Для того, щоб Apache міг приймати і обробляти проксі-запити, необхідно завантажити модуль mod_proxy, що входить в стандартний комплект поставки і прекрасно документований. Тут і далі в цій статті ми не будемо дублювати сторінки керівництва, зупиняючись лише на нетривіальних моментах. mod_proxy, як і велика частина інших згаданих у статті модулів, зазвичай не збирається в стандартній конфігурації Apache, тому вам, імовірно, доведеться заново скомпілювати сервер, вказавши відповідні параметри сценарієм configure. За підтримку mod_proxy відповідає опція «--enable-proxy», інші ж параметри я буду приводити в тексті в дужках після імені відповідного модуля.

Відповідно до представленої вище формулою, mod_proxy утворює фундамент, на якому працює система підтримки проксі-запитів. Їх реалізації, специфічні для різних протоколів, винесено в окремі модулі: mod_proxy_http (--enable-proxy-http), mod_proxy_ftp (--enable-proxy-ftp) і mod_proxy_connect (--enable-proxy-connect). Останній з них необхідний для роботи із запитами HTTP CONNECT, зокрема, захищеними SSL-з'єднаннями.

Щоб Apache міг приймати проксі-запити, необхідно явно дозволити їх, використовуючи директиву "ProxyRequests On". Однак, не поспішайте цього робити, не подбавши про безпеку мережевих з'єднань! Оплачувати мегабайти, завантажені заповзятливими підлітками з ProxyHunter'ом в руках - не найприємніше проведення часу. Параметри доступу до сервера задаються в секції і, зокрема, можуть мати такий вигляд:

# Для всіх проксі-запитів

Order deny, allow # Спершу заборонити, потім дозволити

Deny from All # Заборонити всім

Allow from 192.168.0.1/24 # Дозволити доступ з внутрішньої мережі організації

# Для всіх проксі-запитів

AuthName "Tresspassers" # «Стороннім в.»

AuthFile / some / secret / file # Ім'я файлу, що містить реквізити користувачів

Require valid-user # Пропускати всіх, хто перерахований в / some / secret / file

Внісши необхідні зміни в httpd.conf, не забудьте перезапустити Apache. Після цього відкрийте свій улюблений браузер і упевніться, що налаштування безпеки діють саме так, як ви задумали.

кешування

Кешуванням даних в Apache завідує модуль mod_cache (--enable-cache). Саме він приймає рішення про те, чи припустимо локальне збереження того чи іншого об'єкта. Безпосереднім записом даних на носії займаються модулі- "провайдери", з яких нас в першу чергу буде цікавити mod_disk_cache (--enable-disk-cache), який реалізує зберігання кешу на жорсткому диску.

Відзначимо, що в Apache 2.0 обидва цих модуля (mod_cache і mod_disk_cache) мають статус експериментальних. Ситуація обіцяє змінитися в Apache 2.1, який поки що перебуває в стані альфа-версії.

Щоб включити кешування, використовуйте директиву "CacheEnable disk /", де "disk" - ідентифікатор модуля-провайдера. Місцезнаходження дискового кешу і його бажаний обсяг (в кілобайтах) задається відповідно директивами "CacheRoot <имя каталога>"І" CacheSize », Що відносяться вже не до mod_cache, а mod_disk_cache. Apache вживає заходів до того, щоб конфіденційні дані ніколи не потрапляли в кеш сервера, проте, зайва безпеку все ж не зашкодить. Я рекомендую зробити каталог, в якому зберігається кеш, недоступним ні для кого, крім Apache.

# Chown apache: apache / path / to / cache

# Chmod 0700 / path / to / cache

Природно, якщо у вашій системі Apache працює від імені іншого користувача, ім'я та групу власника каталогу також слід змінити відповідним чином.

З метою підвищення продуктивності дисковий кеш має багаторівневу структуру. Глибиною вкладеності підкаталогів і максимальною довжиною їх імені управляють директиви CacheDirLevels і CacheDirLength. За замовчуванням для них використовуються наступні значення: CacheDirLevels 2, CacheDirLength 3

На жаль, Apache 2.0 не має ніяких штатних засобів для керування вмістом кешу. Ви не можете поступово видаляти старі дані або робити це при перевищенні кешем деякої дискової квоти. Частина з цих проблем вирішена в Apache 2.1 за допомогою спеціальної утиліти htcacheclean, яка очищає кеш в міру необхідності. Мені не відомо, перенесена вона в гілку 2.0, однак, як деякої заміни, ви можете написати сценарій, періодично очищающий каталог (і, для вірності, перезапускати Apache), самостійно.

На даному етапі ми завершили всі роботи, необхідні для отримання "ідентичного натуральному ароматизатора" Squid, а точніше, того підмножини його функцій, яке використовується в типовій малої мережі. Тепер ми підемо трохи далі і реалізуємо щось нове - прозоре стиснення web-сторінок.

Після своєї завантаження mod_deflate створює фільтр "DEFLATE", який може бути встановлений стандартним чином, наприклад, за допомогою директиви "SetOutputFilter DEFLATE". Керівництво до модуля рекомендує остерігатися і відключити стиснення даних для браузерів, які, незважаючи на заявлену функціональність (виноска: Відзначимо, що відсікання клієнтів, які не підтримують стиснення даних, mod_deflate виробляє сам, без будь-якої участі адміністратора) не можуть забезпечити належний рівень підтримки (наприклад, Netscape Navigator 4.x може коректно обробляти тільки стислі дані типу text / html, а його версії 4.06-4.08 не здатні навіть на це), однак, стосовно до проксі-сервера це має сенс лише в тому випадку, коли такі "динозаври до сих пір знаходяться в обігу у вашій організації. З інших директив, підтримуваних mod_deflate, слід згадати DeflateCompressionLevel,

встановлює ступінь стиснення даних (число від 0 до 9). Більше значення цієї величини забезпечує менший розмір результуючих файлів, але підвищує навантаження на процесор. Для середньостатистичної системи оптимальним вибором вважається 6. Ви можете не використовувати цю директиву, тоді матимуть місце значення за замовчуванням, прийняті при складанні системної бібліотеки Zlib.

mod_filter

Здавалося б, все добре. Наш Apache тепер вміє обробляти проксі-запити, зберігати їх в кеші і навіть стискати перед відправкою. Однак, через деякий (зазвичай - досить нетривалий) час виявляються дивні артефакти. Архіви чомусь виявляються упакованими двічі, що лякає непідготовлених користувачів. І тут же виникають два віковічних українських питання: "Хто винен?" І "Що робити?"

val / mod_filter.zip. Щоб встановити його, розпакуйте архів в тимчасовий каталог на вашому сервері і дайте команду: apxs -c -i -a mod_filter.c.

Основна ідея mod_filter полягає в тому, щоб замінити звичайний фільтр так званим "розумним" (smart filter). «Розумний» фільтр - це деяка абстрактна конструкція, яка містить умови спрацьовування і набір так званих провайдерів (знову це слово!), Які, в свою чергу, є звичайними фільтрами. У перспективі подібний підхід може скоротити кількість дублюючого коду, що зустрічається практично в кожному модулі і дає відповідь на питання: "Чи повинні ми обробити цю порцію даних?" Втім, зараз нас будуть цікавити суто практичні аспекти.

Умови спрацьовування "розумного" фільтра можуть використовувати найрізноманітнішу інформацію: поля заголовків прямого запиту (req) і відповіді на нього (resp), значення внутрішніх змінних Apache, що встановлюються за допомогою mod_setenvif (env), імена обробників (handler), а таже тип переданих даних (Content-type).

Для створення "розумного" фільтра використовується директива "FilterDeclare <имя фильтра>". Підключенням окремих провайдерів управляє директива "FilterProvider <имя фильтра> <имя провайдера> <условие>". Тут під ім'ям провайдера мається на увазі назва "звичайного" фільтра, наприклад, DEFLATE. Після завершення "розумного" фільтра, слід додати його в «ланцюжок» командою FilterChain. При обробці запиту, що поступив ланки ланцюжка послідовно проглядаються до тих пір, поки не буде знайдений фільтр, умова спрацьовування якого для даного конкретного запиту виявиться істинним. За замовчуванням додавання нового "розумного фільтра" відбувається в кінець ланцюжка, проте, це поведінка можна придушити, використовуючи спеціальні префікси в директиві FilterChain. Подробиці шукайте в документації.

Тепер шлях вирішення проблеми стає зрозумілим. Нам необхідно додати "розумний" фільтр "Compressor" (звичайно, ви можете використовувати інше ім'я), який буде обробляти дані з типом "text / *". Насправді, діапазон MIME-типів, що підлягають стисненню, може бути більш широким. Я, наприклад, використовую наступну конструкцію:

FilterProvider Compressor DEFLATE resp = Content-type $ text /

FilterProvider Compressor DEFLATE resp = Content-type $ application / xhtml

FilterProvider Compressor DEFLATE resp = Content-type $ application / xml

висновок

Врізка 1. Приклад виклику configure, що забезпечує підтримку всіх необхідних модулів

--enable-proxy --enable-proxy-http --enable-proxy-ftp --enable-proxy-connect \

Врізка 2. Фрагмент файлу httpd.conf, який реалізує описану в статті систему