Как использовать подробные ошибки HTTP в IIS 7.0

Команда IIS

Введение

Каждый Web-Site администратор или веб-разработчик видели сообщения "404 - Файл не найден", "401 - несанкционированный" или "500 - ошибка сервера" в браузере. В этой статье показано, как и почему службы IIS создают эти ошибки и как их можно настроить.

Многие могут подумать, что создание сообщений об ошибках, кажется, не оправдывает полную статью. Но в ошибках больше, чем кажется на первый взгляд. Сообщения об ошибках — это щепетильная тема, так как каждая ошибка раскрывает о вашем веб-сайте больше, чем вам бы хотелось. Чем больше информации кто-то может собрать о вашем сайте, тем более похоже, что вы будете взломаны. Поиск "взлома Google" или "межсайтового скрипта" показывает богатство информации по этому разделу.

Однако сообщения об ошибках также являются ценным средством для устранения неполадок. Разработчикам и администраторам Web-Site требуется максимально подробная информация при возникновении ошибки. В идеале сообщение об ошибке дает рекомендации по устранению проблемы. Вот как IIS решает эти фундаментально противоположные цели.

Ошибки, какие ошибки?

В этой статье рассматриваются ошибки HTTP, указанные в протоколе RFC HTTP (RFC 2616 — раздел 6.1.1). Ошибка HTTP всегда выражается путем отправки ответа с кодом состояния больше 400 обратно клиенту запроса.

Ошибки клиента

Коды состояния от 400 до 500 указывают ошибку, которую клиент сделал, например неправильный синтаксис или запрос к ресурсу, который не существует. Это можно попробовать, запросив фиктивный URL-адрес на выбранном вами веб-сайте, например: http://<IIS7Server>/this_resource_does_not_exist. Вы получаете ошибку "404 — файл не найден".

Ошибки сервера

Коды состояния, начиная с 500, являются ошибками, вызванными сервером. Наиболее распространенными причинами ошибок 500 на системах IIS являются:

  • Страница ASP или ASPX, содержащая синтаксическую ошибку
  • Конфигурация веб-сервера или конфигурация приложения не может быть прочитана или недопустима
  • Сайт остановлен

Важно отметить, что браузеры, такие как IE, часто заменяют ошибки, возвращаемые с веб-сервера собственными ошибками. Это затрудняет устранение неполадок. В IE эту функцию можно отключить. Перейдите в меню "Сервис", выберите "Параметры браузера", перейдите на вкладку "Дополнительно" и установите флажок "Показать понятные сообщения об ошибках HTTP" и снимите флажок. Чтобы просмотреть необработанный ответ, используйте такие средства HTTP, как WFETCH, в наборе ресурсов IIS 6.0 (см. статью "Связанные ссылки").

Ошибки HTTP в IIS

Существует две вещи, которые могут произойти, когда модуль httpError (custerr.dll) обнаруживает ошибку:

  • Создается настраиваемая ошибка
  • Создается подробная ошибка

Кастомные ошибки — это страницы ошибок, которые видят обычные пользователи веб-сайта. Они содержат краткое описание ошибки о том, почему произошла ошибка, но ничего другого. Ниже приведена настраиваемая ошибка, возникающая при запросе ресурса, который не существует, например: http://< IIS7Server>/this_resource_does_not_exist

Снимок экрана: ошибка H T T P 404 (файл или каталог не найден) на веб-странице в Internet Explorer.

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

Скриншот страницы приложения

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

Схема подстатуса состояния, тела сущности и пути задания ошибки при создании подробной ошибки.

Поток данных

Сначала: проверка ошибок

Модуль httpError получает уведомление перед отправкой ответа (уведомление RQ_SEND_RESPONSE). Модуль httpError проверяет код состояния этого ответа и немедленно возвращает, если код состояния не превышает 400.

Во-вторых: пользовательская ошибка или подробная ошибка

Следующая проверка определяется источником запроса (это локальный или удаленный запрос) и параметром свойства errorMode. Свойство errorMode имеет значение DetailedLocalOnly, что означает, что пользовательские ошибки создаются для каждого удаленного запроса. Если для параметра errorMode задано значение "Custom", все ответы на ошибки станут ошибками типа "Custom Error". Если для параметра errorMode задано значение "Подробные", все ответы на ошибки будут становиться "Подробными ошибками". В следующей таблице объясняется следующее поведение:

режимОшибки Источник запроса Действие
DetailedLocalOnly (по умолчанию) Локальный Подробная ошибка
DetailedLocalOnly (по умолчанию) Remote Настраиваемая ошибка
Настройка Локальный Настраиваемая ошибка
Настройка Remote Настраиваемая ошибка
Подробный Локальный Подробная ошибка
Подробный Remote Подробная ошибка

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

Если custerr.dll определяет, что необходимо создать детализированную ошибку, требуется еще одна проверка. IIS не изменяет ответ, если модуль переопределил сущность ответа своим собственным описанием ошибки. Она может содержать ценные сведения. ASP.NET является хорошим примером. Сущность ответа об ошибке ASP.NET может содержать стек исключений и собственное описание ошибки. Подробная ошибка создается только в том случае, если тело сущности ответа пусто.

Конфигурация <httpErrors>

Ниже приведен пользовательский раздел ошибок IIS, полученный при чистой установке:

<httpErrors>
    <error statusCode="401" prefixLanguageFilePath="c:\inetpub\custerr" path="401.htm" />
    <error statusCode="403" prefixLanguageFilePath="c:\inetpub\custerr" path="403.htm" />
    <error statusCode="404" prefixLanguageFilePath="c:\inetpub\custerr" path="404.htm" />
    <error statusCode="405" prefixLanguageFilePath="c:\inetpub\custerr" path="405.htm" />
    <error statusCode="406" prefixLanguageFilePath="c:\inetpub\custerr" path="406.htm" />
    <error statusCode="412" prefixLanguageFilePath="c:\inetpub\custerr" path="412.htm" />
    <error statusCode="500" prefixLanguageFilePath="c:\inetpub\custerr" path="500.htm" />
    <error statusCode="501" prefixLanguageFilePath="c:\inetpub\custerr" path="501.htm" />
    <error statusCode="502" prefixLanguageFilePath="c:\inetpub\custerr" path="502.htm" />
</httpErrors>

Вы увидите, что если код состояния ответа равен 401, iis вернет файл с именем 401.htm.

Коды подстатуса

Многие ошибки HTTP имеют подстатус. Конфигурация пользовательских ошибок IIS по умолчанию не различает коды состояния на основе подстатусов. Он отправляет ту же страницу пользовательской ошибки, если ввести неправильные учетные данные (401.1), или если доступ запрещен на основе недопустимых прав доступа к файлу (401.3). Различные коды подстатуса можно увидеть в файлах журнала или через функцию Подробные ошибки. Ниже приведен список различных кодов вложенного состояния 404, создаваемых IIS:

Статус Описание
404.1 Не удалось найти сайт
404.2 Запрещено политикой. Программа обращения ISAPI или CGI не разрешена в списке ограничений.
404.3 Статический обработчик файлов не имеет файла в mimeMap и поэтому отклонил запрос.
404.4 Обработчик не найден для обслуживания запроса.
404.5 Модуль фильтрации запросов отклонил последовательность URL-адресов в запросе.
404.6 Модуль фильтрации запросов отрицал HTTP-команду запроса.
404.7 Модуль фильтрации запросов отклонил расширение файла запроса.
404.8 Модуль фильтрации запросов отклонил определенный сегмент URL (символы между двумя слэшами).
404.9 IIS отклонил запрос на обслуживание скрытого файла.
404.11 Модуль фильтрации запросов отклонил запрос, который был дважды экранирован.
404.12 Модуль фильтрации запросов отклонил запрос, содержащий большие битовые символы.
404.14 Модуль фильтрации запросов отклонил запрос с URL-адресом, слишком длинным.
404.15 Модуль фильтрации запросов отклонил запрос с слишком длинной строкой запроса.
413.1 Модуль фильтрации запросов отклонил запрос, слишком длинный (запрос + текст сущности).
431 Модуль фильтрации запросов отклонил заголовок, который был слишком длинным.

Вы можете настроить раздел httpErrors, чтобы отобразить пользовательскую ошибку для определённых кодов состояния. Если добавить следующую строку в раздел конфигурации httpErrors, IIS возвращает 404_3.htm, если запрашивается файл с расширением, которое не включено в раздел конфигурации MimeMap IIS (<staticContent> configuration section).

<error statusCode="404" subStatusCode="3" prefixLanguageFilePath="c:\inetpub\custerr" path="404_3.htm" />

Вот как заставить пример работать:

  1. Добавьте запись выше в раздел конфигурации httpErrors.
  2. Создайте файл с именем 404_3.htm в каталоге c:\inetpub\custerr\en-us .
  3. Создайте файл с именем test.yy в c:\inetpub\wwwroot каталоге.
  4. Теперь выполните запрос http://localhost/test.yyy.

Расширение .yyy не является частью IIS MimeMap, а обработчик статических файлов не будет обслуживать его.

Новые функции в IIS: языково-специфичные пользовательские ошибки

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

Accept-Language: en-us

Синтаксис и реестр принятых языков указывается в RFC1766.

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

Параметр конфигурации prefixLanguageFilePath (например c:\inetpub\custerr)+
заголовок Accept-Language, отправленный клиентом (например, en-us) +
Параметр конфигурации пути (например, 404.htm)

Пример:

Если браузер отправляет запрос на не существующий ресурс, а заголовок Accept-Language имеет значение "en-us", будет возвращен c:\inetpub\custerr\en-us\404.htmфайл.

Например, если вы находитесь из Германии, вы хотите, чтобы сообщения об ошибках были на немецком языке. Для этого необходимо установить языковой пакет Windows Vista для немецкого языка. Это создает c:\inetpub\custerr\de-DE каталог с пользовательскими файлами ошибок. Теперь, если браузер отправляет заголовок Accept-Language со значением "de-DE", будет возвращен файл c:\inetpub\custerr\de-DE\404.htm.

IIS всегда переходит на системный язык, если каталог "de-DE" не существует.

Замечание

Internet Explorer позволяет настроить заголовок Accept-Language. Перейдите на вкладку "Сервис" — "Интернет-параметр", перейдите на вкладку "Общие" и нажмите кнопку "Языки".

Настраиваемые параметры ошибок

В приведенных выше примерах IIS отправляет содержимое файла как пользовательский ответ об ошибке. IIS имеет два других способа реагирования на ошибку: выполнив URL-адрес или перенаправив запрос.

ExecuteUrl

Если вы хотите расширить функциональность пользовательской ошибки, например, отправить электронное письмо или журналировать ошибку в базу данных, вы можете обработать URL-адрес. Это позволяет выполнять динамическое содержимое, например страницу ASP.NET. Пример ниже заменяет стандартную страницу ошибки 404. Теперь IIS выполняет /404.aspx всякий раз, когда возникает ошибка 404.

<httpErrors>
<!-- default custom error for 401 errors -->
<!-- <error statusCode="404" prefixLanguageFilePath="c:\inetpub\custerr" path="404.htm" />-->

<!-- ExecuteURL replaces default file response mode -->
<error statusCode="404" path=/404.aspx" responseMode="ExecuteURL"/>        
<error statusCode="403" prefixLanguageFilePath="c:\inetpub\custerr" path="403.htm" />
<error statusCode="404" prefixLanguageFilePath="c:\inetpub\custerr" path="404.htm" />
<error statusCode="405" prefixLanguageFilePath="c:\inetpub\custerr" path="405.htm" />
<error statusCode="406" prefixLanguageFilePath="c:\inetpub\custerr" path="406.htm" />
<error statusCode="412" prefixLanguageFilePath="c:\inetpub\custerr" path="412.htm" />
<error statusCode="500" prefixLanguageFilePath="c:\inetpub\custerr" path="500.htm" />
<error statusCode="501" prefixLanguageFilePath="c:\inetpub\custerr" path="501.htm" />
<error statusCode="502" prefixLanguageFilePath="c:\inetpub\custerr" path="502.htm" />

</httpErrors>

Соображения безопасности

Слово предостережения: по архитектурным причинам IIS может выполнять URL-адрес только если он находится в одном пуле приложений. Используйте функцию перенаправления для выполнения пользовательской ошибки в другом пуле приложений.

IIS также может возвращать перенаправление 302 в браузер при возникновении определенной ошибки. Перенаправление хорошо, если у вас есть ферма серверов. Например, вы можете перенаправить все ошибки в централизованное место, которое вы внимательно мониторите.

Однако существует риск: responseMode="File" (по умолчанию) позволяет указать каждый файл на диске. Это не будет работать, если вы очень озабочены безопасностью.

Рабочий сценарий может включать только делегирование параметра errorMode. Это позволяет разработчику получать подробные ошибки для своего приложения, даже если он использует удаленный клиент. Всё, что нужно сделать, — это установить параметр errorMode="Detailed". Вот как настроить этот сценарий:

Разрешить делегирование раздела httpErrors:

<section name="httpErrors" overrideModeDefault="Allow" />

Во-вторых, перейдите к разделу <httpErrors> в applicationHost.config и измените его так, чтобы делегировался только errorMode.

<httpErrors lockAllAttributesExcept="errorMode" lockElements="error">
    <error statusCode="404" prefixLanguageFilePath="E:\inetpub\custerr" path="404.htm" />
    <error statusCode="401" prefixLanguageFilePath="E:\inetpub\custerr" path="401.htm" />
    <error statusCode="403" prefixLanguageFilePath="E:\inetpub\custerr" path="403.htm" />
    <error statusCode="405" prefixLanguageFilePath="E:\inetpub\custerr" path="405.htm" />
    <error statusCode="406" prefixLanguageFilePath="E:\inetpub\custerr" path="406.htm" />
    <error statusCode="412" prefixLanguageFilePath="E:\inetpub\custerr" path="412.htm" />
    <error statusCode="500" prefixLanguageFilePath="E:\inetpub\custerr" path="500.htm" />
    <error statusCode="501" prefixLanguageFilePath="E:\inetpub\custerr" path="501.htm" />
    <error statusCode="502" prefixLanguageFilePath="E:\inetpub\custerr" path="502.htm" />
</httpErrors>

Сводка

В IIS мощными функциями являются пользовательские и детализированные ошибки. Они помогают устранять неполадки без ущерба для безопасности сервера IIS. Многие параметры конфигурации помогают настроить взаимодействие пользователей. Самое главное: экспериментирование с ним весело.

См. также