Spec-Zone.ru › Apache HTTP Server

Руководство по кэшированию

Этот документ дополняет справочную документацию по mod_cache, mod_cache_disk, mod_file_cache и htcacheclean. В нём описано, как использовать функции кэширования Apache HTTP Server для ускорения обслуживания веб-контента и работы прокси, избегая распространённых проблем и ошибок конфигурации.

Введение

Веб-сервер Apache HTTP Server предлагает ряд функций кэширования, предназначенных для повышения производительности сервера различными способами.

Трёхсостоящее HTTP-кэширование RFC2616
mod_cache и его модули-провайдеры mod_cache_disk обеспечивают интеллектуальное кэширование с учётом HTTP. Содержимое хранится непосредственно в кэше, а mod_cache стремится учитывать все различные заголовки и параметры HTTP, управляющие возможностью кэширования содержимого, как описано в разделе 13 RFC2616. mod_cache предназначен как для простых, так и для сложных конфигураций кэширования, когда вы работаете с проксируемым содержимым, динамическим локальным содержимым или хотите ускорить доступ к локальным файлам на потенциально медленном диске.
Двухсостоящий кэш общих объектов «ключ/значение»
API кэша общих объектов (socache) и его модули-провайдеры предоставляют общесерверный кэш общих объектов на основе пар «ключ/значение». Эти модули предназначены для кэширования низкоуровневых данных, таких как сеансы SSL и учётные данные аутентификации. Благодаря используемым хранилищам данные можно хранить на уровне всего сервера в общей памяти или на уровне центра обработки данных в кэше, например memcache или distcache.
Специализированное кэширование файлов
mod_file_cache позволяет предварительно загружать файлы в память при запуске сервера, что может ускорить доступ и сэкономить файловые дескрипторы для часто используемых файлов, поскольку при каждом запросе нет необходимости обращаться к диску.

Чтобы получить максимальную пользу от этого документа, вам следует знать основы HTTP и прочитать руководства пользователя по сопоставлению URL-адресов с файловой системой и согласованию содержимого.

Трёхсостоящее HTTP-кэширование RFC2616

Связанные модули Связанные директивы
  • mod_cache
  • mod_cache_disk
  • CacheEnable
  • CacheDisable
  • UseCanonicalName
  • CacheNegotiatedDocs

Протокол HTTP содержит встроенную поддержку механизма кэширования согласно разделу 13 RFC2616, и для использования этого механизма можно применять модуль mod_cache.

В отличие от простого двухсостоящего кэша «ключ/значение», в котором содержимое полностью исчезает, когда устаревает, HTTP-кэш предусматривает сохранение устаревшего содержимого и возможность запросить у исходного сервера, изменилось ли оно, а если нет — снова сделать его актуальным.

Запись в HTTP-кэше может находиться в одном из трёх состояний:

Актуальное
Если содержимое достаточно новое (его возраст меньше срока актуальности), оно считается актуальным. HTTP-кэш может отдавать актуальное содержимое, вообще не обращаясь к исходному серверу.
Устаревшее

Если содержимое слишком старое (его возраст превышает срок актуальности), оно считается устаревшим. Перед отправкой устаревшего содержимого клиенту HTTP-кэш должен обратиться к исходному серверу и проверить, актуально ли оно. Если содержимое уже недействительно, исходный сервер отправит замену; в идеале же исходный сервер сообщит кэшу, что содержимое всё ещё актуально, без необходимости заново создавать или отправлять его. Содержимое снова становится актуальным, и цикл продолжается.

Протокол HTTP допускает отправку кэшем устаревших данных при определённых обстоятельствах, например если попытка обновить данные с помощью исходного сервера завершилась ошибкой 5xx или если другой запрос уже обновляет эту запись. В таких случаях к ответу добавляется заголовок Warning.

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

Полное описание работы HTTP-кэширования приведено в разделе 13 RFC2616.

Взаимодействие с сервером

Модуль mod_cache подключается к серверу в одном из двух возможных мест, в зависимости от значения директивы CacheQuickHandler:

Фаза быстрого обработчика

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

В этом случае кэш работает так, словно он «прикручен» к передней части сервера.

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

Запросы с заголовком "Authorization" (например, использующие HTTP Basic Authentication) не кэшируются и не обслуживаются из кэша, когда mod_cache работает в этой фазе.

Фаза обычного обработчика

Эта фаза выполняется на позднем этапе обработки запроса, после завершения всех этапов обработки запроса.

В этом случае кэш работает так, словно он «прикручен» к задней части сервера.

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

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

Если найденное в кэше содержимое устарело, модуль mod_cache преобразует запрос в условный запрос. Если исходный сервер отправит обычный ответ, этот ответ будет помещён в кэш вместо уже сохранённого содержимого. Если исходный сервер отправит ответ 304 Not Modified, содержимое снова будет помечено как актуальное, а фильтр отправит кэшированное содержимое вместо его повторного сохранения.

Увеличение количества попаданий в кэш

Если виртуальный хост доступен по одному из множества различных псевдонимов сервера, установка UseCanonicalName в значение On может значительно повысить долю попаданий в кэш. Это связано с тем, что имя узла виртуального хоста, обслуживающего содержимое, используется в ключе кэша. При значении On для виртуальных хостов с несколькими именами или псевдонимами сервера не будут создаваться разные кэшированные объекты; вместо этого содержимое будет кэшироваться с использованием канонического имени хоста.

Срок актуальности

Правильно сформированное содержимое, предназначенное для кэширования, должно указывать явный срок актуальности в полях max-age или s-maxage заголовка Cache-Control либо включать заголовок Expires.

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

Если срок актуальности отсутствует в запросе или ответе, применяется срок актуальности по умолчанию. Для кэшированных объектов он составляет один час, однако его можно легко переопределить с помощью директивы CacheDefaultExpire.

Если ответ не содержит заголовка Expires, но содержит заголовок Last-Modified, mod_cache может определить срок актуальности эвристически; управлять этим можно с помощью директивы CacheLastModifiedFactor.

Для локального содержимого или удалённого содержимого, в котором не задан собственный заголовок Expires, директиву mod_expires можно использовать для точной настройки срока актуальности, добавив max-age и Expires.

Максимальный срок актуальности также можно контролировать с помощью CacheMaxExpire.

Краткое руководство по условным запросам

Когда срок хранения содержимого в кэше истекает и оно устаревает, httpd не пересылает исходный запрос, а вместо этого изменяет его, делая условным.

Если в исходном кэшированном ответе есть заголовок ETag, mod_cache добавит заголовок If-None-Match к запросу, отправляемому исходному серверу. Если в исходном кэшированном ответе есть заголовок Last-Modified, mod_cache добавит заголовок If-Modified-Since к запросу, отправляемому исходному серверу. Каждое из этих действий делает запрос условным.

Получив условный запрос, исходный сервер должен проверить, изменился ли тег ETag или параметр Last-Modified, в зависимости от запроса. Если изменений нет, исходный сервер должен отправить краткий ответ "304 Not Modified". Это сообщает кэшу, что устаревшее содержимое по-прежнему актуально и должно использоваться для последующих запросов до истечения нового срока актуальности содержимого.

Если содержимое изменилось, оно отправляется так, словно запрос изначально не был условным.

Условные запросы дают два преимущества. Во-первых, при отправке такого запроса исходному серверу можно легко определить, совпадает ли содержимое исходного сервера с содержимым в кэше, не передавая весь ресурс.

Во-вторых, правильно спроектированный исходный сервер должен обрабатывать условные запросы значительно дешевле, чем формировать полный ответ. Для статических файлов обычно достаточно вызвать stat() или аналогичный системный вызов, чтобы проверить, изменились ли размер файла или время его модификации. Поэтому даже локальное содержимое может быстрее отдаваться из кэша, если оно не изменилось.

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

Что можно кэшировать?

Полное описание ответов, которые может кэшировать HTTP-кэш, приведено в разделе 13.4 RFC2616 «Возможность кэширования ответов»; его можно кратко изложить следующим образом:

  1. Кэширование должно быть включено для данного URL-адреса. См. директивы CacheEnable и CacheDisable.
  2. Если код состояния HTTP ответа не равен 200, 203, 300, 301 или 410, в ответе также должен быть указан заголовок "Expires" или "Cache-Control".
  3. Запрос должен быть HTTP-запросом GET.
  4. Если ответ содержит заголовок "Authorization:", он также должен содержать параметр "s-maxage", "must-revalidate" или "public" в заголовке "Cache-Control:", иначе ответ не будет кэшироваться.
  5. Если URL-адрес содержит строку запроса (например, сформированную методом GET HTML-формы), он не будет кэшироваться, если только в ответе не указан явный срок действия посредством заголовка "Expires:" или директивы max-age либо s-maxage в заголовке "Cache-Control:", как указано в разделах 13.9 и 13.2.1 RFC2616.
  6. Если код состояния ответа равен 200 (OK), ответ также должен содержать хотя бы один из заголовков "Etag", "Last-Modified" или "Expires" либо директиву max-age или s-maxage в заголовке "Cache-Control:", если директива CacheIgnoreNoLastMod не использовалась для изменения этого требования.
  7. Если ответ содержит параметр "private" в заголовке "Cache-Control:", он не будет сохранён, если только директива CacheStorePrivate не использовалась для изменения этого требования.
  8. Аналогично, если ответ содержит параметр "no-store" в заголовке "Cache-Control:", он не будет сохранён, если не использовалась директива CacheStoreNoStore.
  9. Ответ не будет сохранён, если он содержит заголовок "Vary:" со значением "*" для сопоставления со всеми вариантами.

Что не следует кэшировать?

Клиент, формирующий запрос, или исходный сервер, создающий ответ, должны решать, можно ли кэшировать содержимое, правильно задавая заголовок Cache-Control. Директива mod_cache должна оставаться без изменений, чтобы соответствующим образом учитывать пожелания клиента или сервера.

Не следует кэшировать содержимое, чувствительное ко времени, а также содержимое, которое зависит от особенностей запроса, не учитываемых согласованием HTTP. Такое содержимое должно объявлять себя непригодным для кэширования с помощью заголовка Cache-Control.

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

Содержимое, изменяющееся в зависимости от заголовков запроса, предоставленных клиентом, можно кэшировать, разумно используя заголовок ответа Vary.

Переменное содержимое и согласование

Если исходный сервер настроен на отправку разного содержимого в зависимости от значений заголовков запроса, например для предоставления нескольких языковых версий по одному URL-адресу, механизм кэширования HTTP позволяет кэшировать несколько вариантов одной страницы по одному URL-адресу.

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

Например, если получен ответ с таким заголовком vary:

Vary: negotiate,accept-language,accept-charset

mod_cache будет отправлять кэшированное содержимое только тем клиентам, чьи заголовки accept-language и accept-charset совпадают с заголовками исходного запроса.

Несколько вариантов содержимого можно кэшировать одновременно; mod_cache использует заголовок Vary и соответствующие значения заголовков запроса, перечисленных в Vary, чтобы определить, какой из вариантов вернуть клиенту.

Примеры настройки кэша

Связанные модули Связанные директивы
  • mod_cache
  • mod_cache_disk
  • mod_cache_socache
  • mod_socache_memcache
  • CacheEnable
  • CacheRoot
  • CacheDirLevels
  • CacheDirLength
  • CacheSocache

Кэширование на диск

Модуль mod_cache использует специальные реализации хранилищ для управления кэшем; для кэширования на диск предусмотрен mod_cache_disk.

Обычно модуль настраивается следующим образом:

CacheRoot   "/var/cache/apache/"
CacheEnable disk /
CacheDirLevels 2
CacheDirLength 1

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

Устройство хранилища кэша

Для сохранения объектов в кэше mod_cache_disk создаёт 22-символьный хэш запрашиваемого URL-адреса. В этот хэш входят имя хоста, протокол, порт, путь и все аргументы CGI URL-адреса, а также элементы, заданные заголовком Vary, чтобы разные URL-адреса не совпадали.

Каждый символ может быть одним из 64 различных символов, то есть всего возможно 64^22 хэшей. Например, URL-адрес может получить хэш xyTGxSMO2b68mBCykqkp1w. Этот хэш используется как префикс имён файлов, относящихся к данному URL-адресу в кэше, однако сначала он разбивается на каталоги в соответствии с директивами CacheDirLevels и CacheDirLength.

Директива CacheDirLevels задаёт количество уровней подкаталогов, а CacheDirLength — количество символов в имени каждого каталога. При приведённых выше настройках хэш будет преобразован в префикс имени файла /var/cache/apache/x/y/TGxSMO2b68mBCykqkp1w.

Цель этого способа — сократить количество подкаталогов или файлов в отдельном каталоге, поскольку работа большинства файловых систем замедляется по мере увеличения их количества. При значении "1" для CacheDirLength на каждом уровне может быть не более 64 подкаталогов. При значении 2 может быть 64 * 64 подкаталогов и так далее. Если у вас нет веских причин поступить иначе, рекомендуется установить значение "1" для CacheDirLength.

Значение CacheDirLevels зависит от предполагаемого количества файлов в кэше. При значении "2", использованном в приведённом выше примере, в общей сложности может быть создано до 4096 подкаталогов. Если в кэше хранится 1 миллион файлов, на каждый каталог придётся примерно 245 кэшированных URL-адресов.

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

Если содержимое согласуется с помощью заголовка "Vary", для соответствующего URL-адреса будет создан каталог ".vary". В этом каталоге будут находиться несколько файлов ".data", соответствующих различным вариантам согласованного содержимого.

Обслуживание дискового кэша

Модуль mod_cache_disk не пытается ограничивать объём дискового пространства, используемого кэшем, хотя при любой ошибке диска он корректно прекращает работу и ведёт себя так, словно кэша не было.

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

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

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


Рисунок 1: Типичный цикл роста и очистки кэша.

Поскольку mod_cache_disk самостоятельно не контролирует объём используемого пространства, необходимо настроить htcacheclean так, чтобы после очистки оставался достаточный «запас для роста».

Кэширование в memcached

С помощью модуля mod_cache_socache модуль mod_cache может кэшировать данные, используя различные реализации (так называемые «провайдеры»). Например, с помощью модуля mod_socache_memcache можно указать, что в качестве механизма хранения данных следует использовать memcached.

Обычно модуль настраивается следующим образом:

CacheEnable socache /
CacheSocache memcache:memcd.example.com:11211

Дополнительные серверы memcached можно указать, добавив их через запятую в конец строки CacheSocache memcache::

CacheEnable socache /
CacheSocache memcache:mem1.example.com:11211,mem2.example.com:11212

Этот формат также используется другими провайдерами mod_cache_socache. Например:

CacheEnable socache /
CacheSocache shmcb:/path/to/datafile(512000)
CacheEnable socache /
CacheSocache dbm:/path/to/datafile

Общее двухсостоящее кэширование общих объектов «ключ/значение»

Связанные модули Связанные директивы
  • mod_authn_socache
  • mod_socache_dbm
  • mod_socache_dc
  • mod_socache_memcache
  • mod_socache_shmcb
  • mod_ssl
  • AuthnCacheSOCache
  • SSLSessionCache
  • SSLStaplingCache

В Apache HTTP Server предусмотрен низкоуровневый кэш общих объектов для кэширования таких данных, как сеансы SSL или учётные данные аутентификации, через интерфейс socache.

Для каждой реализации предусмотрены дополнительные модули, предоставляющие следующие хранилища:

mod_socache_dbm
Кэш общих объектов на основе DBM.
mod_socache_dc
Кэш общих объектов на основе Distcache.
mod_socache_memcache
Кэш общих объектов на основе Memcache.
mod_socache_shmcb
Кэш общих объектов в разделяемой памяти.

Кэширование учётных данных аутентификации

Связанные модули Связанные директивы
  • mod_authn_socache
  • AuthnCacheSOCache

Модуль mod_authn_socache позволяет кэшировать результат аутентификации, снижая нагрузку на серверы аутентификации.

Кэширование сеансов SSL

Связанные модули Связанные директивы
  • mod_ssl
  • SSLSessionCache
  • SSLStaplingCache

Модуль mod_ssl использует интерфейс socache для предоставления кэша сеансов и кэша stapling.

Специализированное кэширование файлов

Связанные модули Связанные директивы
  • mod_file_cache
  • CacheFile
  • MMapFile

На платформах, где файловая система может работать медленно или файловые дескрипторы дорого обходятся, предусмотрена возможность предварительной загрузки файлов в память при запуске.

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

Кэширование файловых дескрипторов

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

CacheFile

Самая простая форма кэширования в httpd — это кэширование файловых дескрипторов, предоставляемое mod_file_cache. Вместо содержимого файлов этот кэш хранит таблицу открытых файловых дескрипторов. Файлы, которые необходимо кэшировать таким образом, указываются в файле конфигурации с помощью директивы CacheFile.

Директива CacheFile указывает httpd открыть файл при запуске и повторно использовать этот файловый дескриптор при всех последующих обращениях к файлу.

CacheFile /usr/local/apache2/htdocs/index.html

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

Хотя использование CacheFile не приводит к кэшированию содержимого файлов как такового, при изменении файла во время работы httpd эти изменения не будут обнаружены. Файл будет неизменно отдаваться в том виде, в каком он был при запуске httpd.

Если файл удалить во время работы httpd, сервер продолжит удерживать открытый файловый дескриптор и отдавать файл в том виде, в каком он был при запуске httpd. Обычно это также означает, что, хотя файл будет удалён и перестанет отображаться в файловой системе, дополнительное свободное место не будет восстановлено, пока httpd не остановится и файловый дескриптор не будет закрыт.

Кэширование в памяти

Непосредственная отправка данных из системной памяти — самый быстрый способ обслуживания содержимого. Чтение файлов с дискового контроллера, а тем более из удалённой сети, на порядки медленнее. Работа дисковых контроллеров обычно связана с физическими процессами, а скорость сетевого доступа ограничена доступной полосой пропускания. Доступ к памяти, напротив, занимает всего несколько наносекунд.

Системная память, однако, недешева: в пересчёте на байт это самый дорогой вид хранилища, поэтому важно использовать её эффективно. Кэширование файлов в памяти уменьшает объём памяти, доступный системе. Как мы увидим далее, кэширование средствами операционной системы не представляет особой проблемы, но при использовании собственного кэша httpd в памяти важно не выделять под него слишком много памяти. В противном случае системе придётся выгружать данные в область подкачки, что, скорее всего, снизит производительность.

Кэширование операционной системой

Практически все современные операционные системы кэшируют файловые данные в памяти, управляемой непосредственно ядром. Это эффективная функция, и в большинстве случаев операционные системы справляются с ней хорошо. Например, рассмотрим разницу во времени чтения файла в Linux при первом и втором обращении:

colm@coroebus:~$ time cat testfile > /dev/null
real    0m0.065s
user    0m0.000s
sys     0m0.001s
colm@coroebus:~$ time cat testfile > /dev/null
real    0m0.003s
user    0m0.003s
sys     0m0.000s

Даже для этого небольшого файла время чтения существенно различается. Это объясняется тем, что ядро сохранило содержимое файла в памяти.

Если на вашем компьютере есть «свободная» память, всё больше файлов будет сохраняться в этом кэше. Это может быть очень эффективным способом кэширования в памяти, не требующим дополнительной настройки httpd.

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

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

Кэширование с помощью MMapFile

Модуль mod_file_cache предоставляет директиву MMapFile, позволяющую сопоставить содержимое статического файла с памятью при запуске httpd (с помощью системного вызова mmap). При всех последующих обращениях к этому файлу httpd будет использовать его содержимое из памяти.

MMapFile /usr/local/apache2/htdocs/index.html

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

Директива MMapFile не отслеживает объём выделяемой памяти, поэтому её не следует использовать чрезмерно. Каждый дочерний процесс httpd копирует эту память, поэтому крайне важно, чтобы отображаемые файлы не были настолько большими, чтобы системе пришлось использовать область подкачки.

Вопросы безопасности

Аутентификация и контроль доступа

Использование mod_cache с параметрами по умолчанию, когда CacheQuickHandler задано значение On, очень похоже на установку кэширующего обратного прокси перед сервером. Запросы будет обслуживать модуль кэширования, если он не решит, что нужно обратиться к исходному серверу, как это сделал бы внешний кэш. Это существенно меняет модель безопасности httpd.

Обход иерархии файловой системы для проверки потенциальных файлов .htaccess был бы очень затратной операцией и частично свёл бы на нет цель кэширования — ускорение запросов. Поэтому mod_cache не проверяет, разрешено ли отдавать кэшированный объект. Иными словами, если mod_cache сохранил содержимое в кэше, оно будет отдаваться до истечения срока его действия.

Например, если ваша конфигурация разрешает доступ к ресурсу по IP-адресу, следует убедиться, что это содержимое не кэшируется. Для этого можно использовать директиву CacheDisable или mod_expires. Если не принять меры, mod_cache — подобно обратному прокси — сохранит содержимое при отправке, а затем будет отдавать его любому клиенту с любого IP-адреса.

Если директиве CacheQuickHandler присвоено значение Off, выполняется полный набор этапов обработки запроса, и модель безопасности остаётся неизменной.

Локальные атаки

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

Если учётная запись пользователя Apache скомпрометирована, например из-за уязвимости в процессе CGI, кэш может стать целью атаки. При использовании mod_cache_disk вставить или изменить кэшированный объект относительно легко.

По сравнению с другими типами атак, которые можно осуществить от имени пользователя Apache, это создаёт несколько повышенный риск. Если вы используете mod_cache_disk, помните об этом: устанавливайте обновления httpd сразу после выпуска исправлений безопасности и, если возможно, запускайте процессы CGI от имени пользователя, отличного от Apache, используя suEXEC.

Отравление кэша

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

Например, если DNS-серверы, используемые системой, на которой работает httpd, уязвимы к отравлению DNS-кэша, злоумышленник может управлять тем, куда httpd подключается при запросе содержимого с исходного сервера. Другой пример — так называемые атаки с контрабандой HTTP-запросов.

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

Отказ в обслуживании / вытеснение кэша

Механизм Vary позволяет кэшировать несколько вариантов одного и того же URL одновременно. В зависимости от значений заголовков, переданных клиентом, кэш выберет подходящий вариант для возврата клиенту. Этот механизм может стать проблемой, если предпринимается попытка варьировать содержимое по заголовку, который при обычном использовании может содержать широкий диапазон значений, например по заголовку User-Agent. В зависимости от популярности конкретного веб-сайта для одного и того же URL могут быть созданы тысячи или миллионы дублирующих записей кэша, вытесняя из кэша другие записи.

В других случаях может потребоваться менять URL определённого ресурса при каждом запросе, обычно добавляя к URL строку «cachebuster». Если сервер объявляет это содержимое кэшируемым на протяжении значительного срока свежести, такие записи могут вытеснить из кэша легитимные записи. Хотя mod_cache предоставляет директиву CacheIgnoreURLSessionIdentifiers, эту директиву следует использовать осторожно, чтобы нижестоящие прокси-серверы или кэши браузеров не подвергались той же проблеме отказа в обслуживании.

© 2018 The Apache Software Foundation
Licensed under the Apache License, Version 2.0.
https://httpd.apache.org/docs/2.4/en/caching.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API