Маленькие настройки большого веб-сервера
Представьте, что вы заказали виртуальный хостинг для своего веб-сайта. Все услуги активированы, вы получили реквизиты для ftp-доступа, что делать дальше? Если ваш веб-сайт представляет собой набор статических html-страниц, остается только залить их на предоставленный сервер, после чего веб-сайт станет доступен всем желающим. Но, помимо статических html-страниц, у вас могут быть и динамические скрипты, которые желательно замаскировать, чтобы не портить адресную строку браузера посетителя ссылками вида http://www.pupkin.com/cgi-bin/super-script.cgi?action=list&mode=4 . Или, может быть, вы желаете ограничить доступ к определенным частям веб-сайта, каким-либо нестандартным образом оформить ссылочную инфраструктуру, позаботиться об удобстве тех, кто будет часто посещать ваш веб-сайт? Во всех этих случаях вам необходима дополнительная конфигурация веб-сервера.
Вероятнее всего, сервер фирмы, предоставившей вам виртуальный хостинг, будет работать под управлением одной из многочисленного семейства *nix-систем. В этом случае на нем наверняка будет установлен широко распространенный веб-сервер Apache - о его конфигурации и пойдет речь в данной статье. Настройкой веб-сервера на хостинге занимаются системные администраторы, имеющие необходимые знания и опыт. В то же время каждый отдельный пользователь располагает неким набором директив, с помощью которых он может произвести дополнительную настройку именно своего веб-сайта, не затрагивая при этом интересы других клиентов. Осуществляется это очень просто: в любом каталоге вашего веб-сайта может находиться файл с именем .htaccess (обратите внимание на точку в начале имени файла), в который записываются директивы Apache, влияющие на свойства данного каталога и всех его подкаталогов.
В данной статье вкратце описываются только наиболее популярные директивы конфигурации вашего веб-сайта, за полным же перечнем всех допустимых директив лучше обратиться к документации по веб-серверу Apache. Некоторые из приведенных ниже директив требуют определенных настроек самого веб-сервера, поэтому, если какие-то из директив не работают, не стесняйтесь обращаться в службу технической поддержки вашего хостера.
Действие директив, описанных в файле .htaccess , обычно распространяется на весь каталог, в котором расположен данный файл, а также на все его подкаталоги. Однако при необходимости можно выделить отдельную группу файлов, к которым будут относиться заданные настройки, с помощью директивы FilesMatch , в которой указывается регулярное выражение. Например:
<FilesMatch ".(gif|jpe?g)$">
# директивы, относящиеся только к файлам с расширениями gif, jpg и jpeg
...
# все, что расположено после символа '#', считается комментарием
</FilesMatch>
В регулярном выражении можно использовать любые печатные символы и пробел, но часть символов имеет особое значение:
- Круглые скобки () используются для выделения групп символов
- Символ ^ обозначает начало строки
- Символ $ обозначает конец строки
- Символ . обозначает любой символ
- Символ | обозначает альтернативу. Например, выражения " A|B " и " (ABC|DEF) " означают " A или B " и " ABC или DEF " соответственно
- Символ ? ставится после символа (или группы символов), который может как присутствовать, так и отсутствовать. Например, выражению " jpe?g " подойдет и строка " jpg ", и строка " jpeg ". Пример выражения с группой символов: " super-(puper-)?site "
- Символ * ставится после символа (или группы символов), который может отсутствовать или присутствовать неограниченное число раз подряд. Например, выражению " jpe*g " подойдут строки " jpg ", " jpeg " и " jpeeeeeeg "
- Символ + действует аналогично символу * с той лишь разницей, что предшествующий ему символ обязательно должен присутствовать хотя бы один раз. Например, выражению " jpe+g " подойдут строки " jpeg " и " jpeeeeg ", но не " jpg "
- Квадратные скобки [] используются для перечисления допустимых символов. Например, выражение " [abc] " равносильно выражению " a|b|c ", но вариант с квадратными скобками обычно является более оптимальным по быстродействию. Внутри скобок можно использовать диапазоны: например, выражение " [0-9] " равносильно выражению " [0123456789] ". Если символы внутри квадратных скобок начинаются с символа ^ , это означает любой символ, кроме перечисленных в скобках. Например, выражение " [^0-9]+ " означает строку из любых символов, кроме цифр
- Символ ставится перед спецсимволами, если они нужны в своем первозданном виде. Например, выражению " jpe+g " соответствует только одна строка " jpe+g "
В среде веб-дизайнеров считается хорошим тоном вместо стандартных сообщений об ошибках выдавать специальные странички, выполненные в дизайне веб-сайта. Для этого служит директива ErrorDocument , которая позволяет для любого существующего кода ошибки задать либо веб-страницу, либо альтернативное текстовое сообщение. Например:
# в случае ошибки "SERVER ERROR" показывается страница с другого веб-сайта
ErrorDocument 500 http://foo.example.com/cgi-bin/tester
# в случае ошибки "NOT FOUND" показывается страница с того же веб-сайта
ErrorDocument 404 /cgi-bin/bad_urls.pl
# в случае ошибки "FORBIDDEN" показывается текстовое сообщение, которое обязательно должно начинаться с кавычки (кавычка в сообщении не выводится)
ErrorDocument 403 "Sorry can't allow you access today
Директива Options позволяет задать ряд общих параметров, из которых наиболее популярны следующие: ExecCGI (разрешить выполнение CGI-скриптов), FollowSymLinks (обрабатывать симлинки), Includes (разрешить SSI ), IncludesNOEXEC (разрешить SSI без запуска скриптов), Indexes (показывать посетителю список файлов, если в выбранном каталоге нет файла index.html или его аналога). Параметры записываются через пробел и могут иметь в начале знаки + или - , которые управляют наследованием. Например:
# включает только параметр Includes
Options Includes
# включает параметр Includes и выключает параметр Indexes, а все остальные параметры имеют значения, заданные в глобальных установках веб-сервера
Options +Includes -Indexes
Когда посетитель запрашивает ссылку на каталог (например, http://pupkin.com/docs/ ), и такой каталог существует, то веб-сервер отдает из данного каталога файл index.html , а при его отсутствии - либо содержимое каталога (если включена опция Indexes ), либо ошибку 403 (FORBIDDEN). Если ваш веб-сайт построен на скриптах, то в качестве индексных могут использоваться файлы с другими расширениями - указать эти файлы можно с помощью директивы DirectoryIndex . Например:
DirectoryIndex index.html index.shtml index.pl index.cgi
Если вашим динамическим скриптам нужны какие-то особенные переменные окружения (environment), их можно задать при помощи следующих директив: PassEnv (передать скриптам данную переменную окружения), SetEnv (установить переменную окружения), UnsetEnv (снять переменную окружения). Перед применением этих директив лучше проконсультироваться со службой технической поддержки - весьма вероятно, что они не будут вам доступны по соображениям безопасности. Примеры:
# передать скриптам значение переменной окружения LANG
PassEnv LANG
# задать переменную окружения PERL5LIB
SetEnv PERL5LIB /home/pupkin/lib/perl
Вполне может случиться так, что ваши динамические скрипты будут иметь нестандартные расширения - в этом случае вам может понадобиться директива AddHandler . Например, если ваши скрипты написаны на perl, то не помешает добавить в .htaccess следующие строки:
Options +ExecCGI
AddHandler cgi-script .pl
Допустим, что вы желаете ограничить доступ к определенной части вашего веб-сайта - это можно легко организовать при помощи системы паролей. Если посетитель попробует зайти в закрытую часть веб-сайта, то его браузер откроет окно, в котором посетитель должен будет ввести свои логин и пароль. Настройка системы паролей заключается в следующем: в отдельный текстовый файл с помощью утилиты htpasswd , входящей в состав Apache , записываются нужные логины и пароли, после чего можно ограничить доступ к любой части веб-сайта при помощи следующих директив:
# название области ограниченного доступа
AuthName "Top secret"
# тип авторизации (возможны только два варианта: Basic и Digest, но второй может не поддерживаться некоторыми браузерами, поэтому пользоваться им не рекомендуется)
AuthType Basic
# имя файла с логинами и паролями (желательно поместить этот файл вне иерархии вашего веб-сайта)
AuthUserFile /home/pupkin/.www-users
# разрешение доступа только тем пользователям, кто введет правильные логин и пароль
Require valid-user
# другой вариант директивы Require: разрешение доступа только перечисленным пользователям
# Require user ivanoff petroff
Пользователей можно объединять в группы, что позволяет ограничивать доступ на более высоком уровне. Синтаксис файла с описанием групп очень простой:
# группа: логин1 логин2
masters: pupkin
losers: ivanoff petroff sidoroff
Ограничение доступа на базе группы задается примерно так (добавляем директиву AuthGroupFile и изменяем директиву Require ):
AuthName "Top secret"
AuthType Basic
AuthUserFile /home/pupkin/.www-users
AuthGroupFile /home/pupkin/.www-groups
Require group masters
Следует помнить, что при таком ограничении доступа пароли передаются по каналам связи в открытом виде и могут быть перехвачены злоумышленниками. Поэтому в целях безопасности рекомендуется организовывать доступ к закрытым областям веб-сайта через защищенное SSL-соединение.
Если вас волнует судьба частых посетителей вашего веб-сайта, использующих медленные каналы связи, можно несколько облегчить им жизнь при помощи директив ExpiresActive , ExpiresDefault и ExpiresByType (но не забудьте предварительно выяснить в службе технической поддержки, входит ли в состав вашего веб-сервера модуль mod_expires ). Идея данного подхода заключается в следующем: если на вашем веб-сайте есть объекты, которые изменяются очень редко (обычно это изображения), то можно настроить Apache таким образом, чтобы вместе с этими объектами он отдавал http-заголовок expires . В таком случае после загрузки изображения оно сохраняется в кеше браузера посетителя и будет находиться в нем вплоть до наступления указанного в http-заголовке времени. Примеры:
# включить установку http-заголовков expires
ExpiresActive on
# по умолчанию для всех элементов устанавливается дата на 1 день позднее времени запроса
# ExpiresDefault "access plus 1 days"
# альтернативная запись, разница во времени указывается в секундах (86400 секунд равны одному дню)
# ExpiresDefault A86400
# можно отсчитывать время от момента последнего изменения запрашиваемого объекта
# ExpiresDefault "modification plus 1 weeks"
# ExpiresDefault M604800
# можно задавать время отдельно для различных типов объектов
# для html-страниц
ExpiresByType text/html "access plus 10 minutes"
# для текстовых файлов
ExpiresByType text/plain "access plus 10 minutes"
# для изображений
ExpiresByType image/gif "modification plus 1 days"
ExpiresByType image/jpeg "modification plus 1 days"
Ну, и напоследок стоит упомянуть директиву AddDefaultCharset , в которой указывается кодировка вашего веб-сайта. Отсутствие этой директивы или неправильное указание кодировки приведет к тому, что некоторым посетителям придется задавать кодировку вручную в своих браузерах, а это им вряд ли понравится. Пример:
AddDefaultCharset windows-1251
Как вы, наверное, уже заметили, в данном описании не были затронуты директивы для настройки редиректов и преобразований http-ссылок ( Redirect , RedirectMatch , RewriteEngine , RewriteRule , RewriteCond ). Дело в том, что эти директивы применяются настолько часто и обладают настолько широкими возможностями, что о них следует написать отдельную статью.