безопасность


htaccess как средство ограничения доступа

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

Возникнет вопрос: «Существуют ли варианты?» Да, конечно. Нельзя оставить без внимания возможности языка PHP с его механизмом авторизации. Говоря вкратце, этот механизм таков. При обращении к защищенной зоне браузер пользователя получает с сервера заголовок (header) WWW-AUTHENTICATE, после приема которого выдает окно для ввода логина и пароля. Две новые переменные — $PHP_AUTH_USER и $PHP_AUTH_PW соответственно — передаются обратно на сервер и проверяются на достоверность. В дальнейшем же они могут быть задействованы и в других PHP- сценариях. Вообще рассказ об авторизации посредством PHP заслуживает отдельной статьи, но сегодня на ней (PHP-авторизации) останавливаться не будем. К тому же, в запасе имеется неплохой вариант — использование штатных средств виртуального сервера Apache. Таким образом, назначив на определенную директорию пароль, вы обеспечите конфиденциальность информации: не зная «ключа», посторонние о ней ничего не узнают. Вместе с тем, эти данные будут доступны владельцу и по надобности некоторым другим пользователям — стоит лишь занести их в список приближенных и указать определенный пароль. Итак, начнем по порядку.

Файл htaccess

Многим читателям, полагаю, уже известны некоторые свойства .htaccess. Это один из конфигурационных файлов Apache, т.н. файл управления доступом. Действия его директив распространяются на каталоги и подкаталоги, в которых он находится. По умолчанию именно такое имя — с точкой в начале — .htaccess (определено директивой <AccessFileName> файла httpd.conf), но при желании администратор сервера может переназначить название на любое другое или вообще исключить файл из числа конфигурационных (<AllowOverride> со значением none) либо ограничить действие отдельных директив. Мы рассматриваем вариант, когда .htaccess работает, или, правильней сказать, директивы .htaccess «в силе». В файл нужно внести несколько команд, которые в дальнейшем распознает и обработает Apache.

AuthType Basic
AuthName "Protected realm"
AuthUserFile /home/localhost/.htpasswd
AuthGroupFile /home/localhost/group
Require valid-user
Require group Group1

По определенному настроенная, каждая директива требует пояснений:

. <AuthType> Basic — самый простой и распространенный тип аутентификации. Механизм ее работы во многом схож с упомянутым выше примером PHP- авторизации, а именно: при попытке доступа к защищенной директории на сервере браузер получает заголовок 401 authentication required, после чего появляется окно ввода комбинации login/password. Введенные данные отсылаются на сервер, где Apache сверяет, достоверные они или нет. Если да, то пользователь получает доступ к защищенной зоне плюс специальное имя-переменную в распоряжение — область действия. В противном случае доступ к защищенной области, разумеется, не откроется.

. Имя защищенной зоны (<AuthName>) — оно отображается в заголовке окна для ввода логина/пароля. Заголовку желательно давать английское наименование, поскольку русское из-за проблем с кодировками в браузерах не всегда отображается корректно.

. Директива <AuthUserFile> указывает на полный (абсолютный) путь к файлу паролей относительно корня сервера. Именно сервера, а не сайта. Неправильно прописывать путь расположения файла относительно каталогов /htdocs, /www. Замечу: в этом частая ошибка многих новичков. Как же выяснить правильный путь для директивы? Вот вам верный и простой способ. Создайте в текстовом редакторе PHP-файл с запросом “<? phpinfo() ?>” (кавычки убираются) и запустите его на хосте. Браузер отобразит таблицу с различными переменными и их значениями. В столбце Variable найдите строку DOCUMENT_ROOT или _SERVER["DOCUMENT_ROOT"]. Напротив, во втором столбце, будет указан полный путь от сервера к домашней директории.

. <AuthGroupFile> — по надобности. Когда доступом к приватной зоне обладает большое количество посетителей, удобно распределить их по группам, например: пользователи, модераторы и т.д. Структура файла групп должна быть такой:

Group1: user1 user2 user3
Group2: user1 user2 user3

GroupN здесь — название группы, а userN — имя посетителя.

. Команда Require определяет тех пользователей (или ту группу), которым (которой) предоставляется вход в защищенную зону. Опцией valid-user разрешается доступ всем, кто в списке auth-файла. Если вы хотите организовать доступ к ресурсу лишь нескольким лицам из списка, укажите Require user test1 test2, ..., где test1, test2 и т. д. — имена разрешенных пользователей. Предоставление доступа группам — соответственно Require Group1 (Group1 — группа).

После того как .htaccess создан, поместите его в ту директорию, которую вы планируете защитить от посторонних. Возможно, подобный файл уже существует — тогда просто допишите Auth-директивы в содержание .htaccess.

Составление аутентификационного файла

Разумеется, имена пользователей и их пароли должны храниться в скрытом от посторонних глаз файле. Путь к нему указывает директива
<AuthUserFile>. Распознав знакомую команду, Apache ищет аутентификационный файл (здесь и далее — .htpasswd, хотя могут быть какие угодно варианты) именно там, где вы указали. А располагать «ключи» лучше всего в директории, расположенной ниже уровня сайта. Так безопаснее. Размещая .htpasswd выше корня сайта, примите меры предосторожности: в каталог, где будет находиться файл с паролями, добавьте .htaccess такого содержания:

<Files .htpasswd>
deny from all
</Files>

Командой deny from all запрещается доступ к файлу .htpasswd каталога, а теги <> и </> определяют область действия директивы. Подробнее о Deny|Allow вы прочитаете ниже, а сейчас мы обратимся к главному — файлу паролей. Он должен иметь следующую структуру:

user:password
...
user:password

Создается файл аналогичной структуры в любом текстовом редакторе. Как уже было сказано, имя и расширение могут быть любыми, однако .htpasswd все же предпочтительнее. Дело в том, что главный конфиг Apache (httpd.conf) уже по умолчанию защищает файлы, названные по маске ^\.ht, от просмотра, поскольку считает их служебными. А дополнительная защита, конечно, не помешает. Кстати, согласитесь: хранить на чужом сервере пароли «в оригинале» несколько нерационально. Весьма желательно зашифровать их, например, в MD5. Уж если злоумышленник и узнает пароль в MD5-хэше (хэширование — преобразование входного массива данных в короткое число фиксированной длины (которое называется хэшем, или хэш-кодом) таким образом, чтобы, с одной стороны, это число было значительно короче исходных данных, а с другой — с большой вероятностью однозначно им соответствовало. //из Википедии (свободная многоязычная энциклопедия), ему придется потратить порядочно времени на расшифровку — зависит от длины, сложности исходного пароля, а также от мощности оборудования взломщика. Поэтому предлагаю вам создать именно зашифрованный аутентификационный файл. В этом направлении окажет помощь утилита Htpasswd, которую нетрудно отыскать в составе комплекса «Денвер» (denwer.ru) или на моем сайте (ilyuha.ho.com.ua) в разделе «Скачать». После запуска из командной строки (Cmd.exe) программа отображает справочную информацию — список команд и ключей — то, что, в принципе, дает полное представление о функциональности Htpasswd. Составление password-файла производится командой

htpasswd -c filename username

где filename — имя файла, username — логин пользователя, а –c — ключ, указывающий на создание нового файла. Когда вам будет нужно добавить в имеющийся список нового пользователя или поменять пароль, просто уберете параметр –c. Таким образом произойдет обновление содержания. После вышеназванной команды (с ключом или без) программа предложит ввести и подтвердить пароль для пользователя username. По умолчанию он (пароль) хэшируется в MD5 (ключ –m); как вариант также применимо и SHA-1-шифрование (ключ –s), благо оба формата без проблем распознаются «Апачем». Наконец, после сообщения «Adding password for…» зашифрованный .htpasswd готов к использованию. Остается едва ли не самое важное — проверить новосозданные файлы и защиту auth-зоны на правильную работу.

Тем, кто не привык работать с командной сторокой, могу посоветовать другую, более удобную, утилиту для создания аутентификационных файлов — Encode UNIX Password. Внимание: зашифрованные EUP-пароли действительны только на UNIX-платформах, но никак не на Windows-. Ссылка на архив программы: сайт

Тест на работоспособность

Поначалу вам понадобится «Денвер», или EasyPhp, или какой-либо другой виртуальный комплекс. Впрочем, как на локальном, так и на удаленном хосте работоспособность определяется одинаковыми методами. Если приватная зона действительно защищена — значит:
1) при переходе на адрес зоны (например, www.site/private/) появится окно с полями для ввода логина/пароля;
2) после ввода корректных данных открывается доступ к зоне, в противном случае — запрет и сообщение «Authorization Required».

Допустим такой вариант: вы запустили виртуальный сервер, ввели адрес приватного раздела в браузере — и... не заработало, то есть браузер выдал сообщение об ошибке. Наиболее распространенная из них — Internal Server Error, т.е. внутренняя ошибка сервера. Причина ее появления — .htaccess содержит синтаксические огрехи, зачастую в наименованиях директив. Решение — еще раз проверьте правильность написания, посмотрите, поставлены ли кавычки в названии защищенной области <AuthName>. Весьма полезно ознакомиться с документом Error.log, который находится вне корневого каталога сайта; это актуально и для локального, и для удаленного сервера (вы должны узнать у хостера, предоставляет ли он возможность просмотра серверных log’ов). Apache регистрирует все происходящие на хосте ошибки и записывает их в Error.log во временном порядке.

Достаточно беглого просмотра — и вы, скорее всего, быстро распознаете злополучную ошибку. Возможна проблема иного рода: введя логин и пароль, вы не можете войти в защищенную зону — опять появляется окно ввода. Тогда одно из двух: либо пользовательских данных не содержится в «базе», либо Apache не нашел собственно «базы» — файла паролей. Решение проблемы — выше по тексту (см. описание директивы <AuthUserFile> и главу «Составление аутентификационного файла»). Добавлю, что, согласно синтаксиса, слэши в путях должны быть «/», а не «\». Не упускайте эту деталь, поскольку, не найдя .htpasswd, сервер выдаст ошибку «500». На localhost’е же направление слэша неважно. Разобравшись с аутентификацией на локальном, приступайте к тестированию на удаленном сервере, не забыв в .htaccess изменить путь расположения файла паролей.

Частные моменты

.htaccess — более гибкий в настройке конфигурационный файл, чем вы предполагали, читая о нем несколько выше. Чтобы убедиться в этом, советую ознакомиться с примерами настройки .htaccess из официальной документации сервера Apache.
1. Установка пароля только на файлы с расширением .zip:

<FilesMatch ".zip$">
AuthName "Some text"
AuthType Basic
AuthUserFile /home/localhost/.htpasswd
Require valid-user
</FilesMatch>

Директива <FilesMatch> «отсеивает» иные расширения и по маске ограничивает доступ к определенным файлам. Подобным образом устанавливается ограничение на несколько расширений сразу:

<FilesMatch "\.(gif|jpg|png)$">

2. Доступ к защищенной зоне разрешен только пользователям с определенными ip:

order deny,allow
deny from all
allow from <ip>
allow from …

Аналогично, но уже командой deny, осуществляется блокировка конкретных ip:

order allow deny
allow from all
deny from 192.255.255.111
deny from …

Кстати, кроме ip-адресов, Apache воспринимает и буквенные имена хостов (www.site.com и т. п.), например:

Allow|deny from localhost

Альтернативная авторизация

Рассмотренный тип авторизации — Basic — отличается простотой использования, но вместе с тем имеет существенный минус: данные, передаваемые на веб-сервер во время сеанса, не шифруются (правда, не считая изначальной кодировки base64), поэтому могут быть перехвачены. Для тех, кто всерьез обеспокоен этим фактом, разработчиками Apache был предусмотрен альтернативный вариант аутентификации — цифровой (Digest Authentication). Главное его достоинство — MD5-шифрование при передаче данных, когда вместо пароля серверу передается хэш-строка и некий одноразовый параметр. При таком подходе вычислить пользовательский пароль путем перехвата и анализа трафика практически невозможно. Судя по описанию — согласитесь, довольно интересное решение, однако здесь выявляются такие детали. Во-первых, Digest требует от сервера Apache модуля mod_auth_digest, который, в отличие от mod_auth, наличествует не у всех хостеров. Во-вторых, несмотря на то, что этот метод аутентификации уже давно поддерживается практически всеми браузерами, а сам модуль auth_digest не является экспериментальным — он закрепил сугубо специализированную направленность. Этим, пожалуй, и обусловлена малая распространенность метода аутентификации. Мне, к слову, так и не удалось увидеть аутентификацию «в действии» — по непонятным на то причинам.

Полезно посетить:
www.httpd.apache.org/docs/ — документация к серверу Apache.
www.ru.wikipedia.org — базовые сведения о SHA-1, MD5.
www.aspnetmania.com/Articles/Article.aspx?ID=30 — подробнее об алгоритме аутентификации Digest.



Илья Муравьев

© компьютерная газета