Apache/Несколько сайтов на одном сервере
Содержание |
Эта инструкция основана на статье "Многоликий Apache" из журнала "Системный администратор" №12, 2005г. (http://samag.ru)
Установив, веб-сервер Apache и предоставив через него на всеобщее обозрение свой сайт, некоторые и не подозревают, каким мощным инструментом они владеют. С его помощью можно управлять сотнями сайтов с разными именами и уровнями доступа. Денежная стоимость и временные затраты на добавление каждого сайта минимальны.
Веб-сервер Apache, популярный благодаря своей прозрачности для программистов и администраторов и не в последнюю очередь благодаря бесплатности, реализован под все более-менее популярные операционные системы. Его настройки для всех ОС одинаковы, различаются только пути, где хранятся конфигурационные файлы. На одном сервере может быть запущено несколько экземпляров Apache, прослушивающих разные адреса и/или порты. Один экземпляр может обслуживать несколько сайтов (подробнее об этом ниже). Проект настолько популярен, что постоянно обрастает новой функциональностью. О степени популярности можно судить либо по статистике, что, на мой взгляд, довольно опрометчиво, либо по конкретным фактам. Фактов популярности Apache мы приведём два. Во-первых, его наличие в качестве веб-сервера по умолчанию в большинстве UNIX-подобных операционных систем. Во-вторых, такой гигант в области ИТ как компания Oracle приняла его в состав своего продукта Oracle Application Server 10g, где он играет одну из ключевых ролей.
Дано
- Компьютер с установленным пакетом Apache 1.3 или 2.0
- Адрес сервера в интернете: 10.0.10.15 и имя: teo.mynetwork.ru
- Адрес сервера в локальной сети: 192.168.100.18
- Несколько сайтов.
- Несколько имён для одного сайта
Задача
- Разместить все сайты на одном сервере
- Сделать доступ к каждому сайту по отдельному URL
- Ограничить доступ к некоторым сайтам
- Сделать перенаправление нескольких имён на один сайт
Решение
Создаём два сайта (виртуальные хосты)
Предположим, что у нас два различных сайта teo.mynetwork.ru и logos.mynetwork.ru. Эти имена должны быть доступны, т.е. держатель зоны mynetwork.ru должен прописать в ней узлы teo и logos
- Для каждого сайта создаём каталог в корневом каталоге документов Apache (teo и logos, соответственно). Для некоторых Linux по умолчанию /var/www/html, но чтобы убедиться, где он расположен на нашем сервере, смотрим значение директивы DocumentRoot в /etc/httpd/conf/httpd.conf. Итак, создаём:
# mkdir /var/www/html/teo /var/www/html/logos
- Мы будем разделять журналы для каждого сайта, поэтому создадим соответствующие каталоги:
# mkdir /var/log/httpd/teo /var/log/httpd/logos
- Если у нас уже был создан сайт, то всё его содержимое переносим в созданный для него каталог, т.е. из /var/www/html в /var/www/html/teo. Новый сайт logos.mynetwork.ru размещаем в /var/www/html/logos. Теперь настраиваем Apache. Добавляем в конец файла /etc/httpd/conf/httpd.conf (некоторые ОС создают для каждого виртуального хоста отдельный конфигурационный файл, тог):
NameVirtualHost 10.0.10.15 <VirtualHost teo.mynetwork.ru> DocumentRoot /var/www/html/teo ServerName teo.mynetwork.ru ErrorLog /var/log/httpd/teo/error_log CustomLog /var/log/httpd/teo/access_log combined </VirtualHost> <VirtualHost logos.mynetwork.ru> DocumentRoot /var/www/html/logos ServerName logos.mynetwork.ru ErrorLog /var/log/httpd/logos/error_log CustomLog /var/log/httpd/logos/access_log combined </VirtualHost>
Все настройки не заданные для сайта явным образом в директиве VirtualHost, наследуются от глобальных настроек Apache, указанных выше в этом же файле.
- Перезапускаем Apache:
# /etc/init.d/httpd restart
- Теперь, обращаясь по DNS именам, мы будем получать разные сайты. Если обратиться по IP адресу, то получим сайт teo.mynetwork.ru, т.к. он подключен первым.
Создаём ссылки с нескольких DNS адресов на один сайт
Это можно осуществить двумя способами: созданием синонимов, или перенаправлением всех обращений с другого сайта.
1) Синонимы задаются директивой ServerAlias, могут содержать маску, и разделяются пробелом. Вот несколько примеров создания синонимов:
ServerAlias www.teo.mynetwork.ru ServerAlias *.teo.mynetwork.ru ServerAlias www.teo.mynetwork.ru god.mynetwork.ru pantheon.ru
Синоним - это DNS-имя. Имена могут быть абсолютно любыми, в том числе и из разных доменов, но все они должны разрешаться в IP-адреса, то есть их предварительно нужно зарегистрировать в DNS.
2) Перенаправление задаётся директивой Redirect. Создаём новый пустой сайт pantheon.ru. Как и для предыдущих сайтов, это делается в три шага: создание каталога для документов, для журналов и добавление конфигурации в httpd.conf:
<VirtualHost pantheon.ru> DocumentRoot /var/www/html/pantheon ServerName pantheon.ru ErrorLog /var/log/httpd/pantheon/error_log CustomLog /var/log/httpd/pantheon/access_log combined Redirect / http://teo.mynetwork.ru </VirtualHost>
Можно перенаправлять не со всего сайта, а только с определённого каталога или даже документа:
Redirect /samag http://samag.ru Redirect /ftp/ ftp://citkit.ru/pub/ Redirect /find/ya.htm http://yandex.ru
При этом Apache воспринимает первый параметр директивы Redirect не как URL, а как набор символов, при совпадении с которым происходит перенаправление. Отсюда следует, что он НЕ проверяет наличие указанных каталогов и файлов, а ссылки /samag и /samag/ НЕ считает одинаковыми.
Перенаправление с помощью файла .htaccess выглядит так:
RewriteEngine On RewriteRule ^wiki/(.*)$ http://new.site.ru/wiki/$1 [R=permanent,L] RewriteRule ^(.*)$ http://new.site.ru/ [R=permanent,L]
- 1-я строка: включаем возможность менять URL
- 2-я строка: перенаправляем запрос к странице http://old.site.ru/wiki/Что-то на другой сайт, передавая параметры ($1)
- 3-я строка: любые другие запросы к старому сайту перенаправляем на новый.
Полезная ссылка:
Ограничиваем доступ к сайтам
Теперь, если пользователь обратится к нам по IP-адресу, либо по имени, на которые наш сервер откликается (см. Приложение), то Apache сначала определяет, не удовлетворяет ли запрос описанным директивами VirtualHost сайтам и если не находит ни один из них, то выдаёт сайт по умолчанию, который находится в каталоге, заданном глобальной директивой DocumentRoot, т.е. уровнем выше остальных. Таким образом, получается, что пользователь может попасть на любой из виртуальных сайтов не тем путём, какой мы для него приготовили, т.е. http://logos.mynetwork.ru/. Например, набрав в адресной строке браузера «http://192.168.100.18/logos/», он получит сайт logos.mynetwork.ru. Правда в этом случае документы, использующие ссылки на ресурсы этого же сайта, будут некорректно отображаться, потому что ссылки делаются относительно корня сайта и, если это была ссылка /img/picture.jpg, то во втором случае этот же файл уже нужно искать по ссылке /logos/img/picture.jpg, этого же браузер не знает. Таким образом, здесь все зависит от того, догадывается ли пользователь, в каких каталогах мы храним наши сайты. В принципе, в этом нет ничего плохого, ведь мы в любом случае выложили сайты, чтобы их посещали (правила по ограничению доступа к ресурсу всё равно будут действовать, о них мы поговорим чуть позже), но как-то это выглядит не красиво (для того и двери, чтоб в окна не лазить). Чтобы устранить эту некрасивость можно поместить сайт по умолчанию на тот же уровень, что и остальные сайты, т.е. создать каталог /var/www/html/default и указать его в двух директивах глобальных настроек (т.е. до описания виртуальных сайтов)
DocumentRoot "/var/www/html/default" ... # This should be changed to whatever you set DocumentRoot to. <Directory "/var/www/html/default">
Теперь перейдём непосредственно к раздаче прав доступа. Существует два способа указания прав доступа к каталогу веб-сайта средствами Apache:
1) поместить в каталог файл .htaccess,
2) использовать директиву <Directory> в файле конфигурации.
В обоих случаях правила распространяются и на вложенные каталоги. Мы рассмотрим оба способа и изменим права доступа к двум каталогам сайта logos.
файл .htaccess
Какие параметры можно переписать в файлах .htaccess определяется директивой AllowOverride. Для разрешения переопределения всех деректив нужно добавить в конфигурацию сайта строку:
AllowOverride All
Перечислим преимущества использования файла .htaccess:
- при его изменении не нужно перезапускать Apache;
- при одинаковом уровне доступа к разным ресурсам можно пользоваться ссылками на один файл .htaccess;
- можно предоставить пользователю право редактирования этого файла, что удобно, если у нас сервер с множеством клиентских сайтов.
Есть и недостатки:
- для того, чтобы ответить на вопрос: «какие ограничения доступа существуют на сайте?» - администратору необходимо помнить, в каких каталогах лежат эти файлы и ссылки;
- если сайт будет переноситься на другой сервер, и, что очень вероятно, будет размещён в другом каталоге, то для корректировки ссылок уйдёт много времени;
- повышается нагрузка сервера, т.к. при каждом запросе на ресурс он обращается к .htaccess в этом каталоге и всех верхних по иерархии, наследуя их настройки т.е. запрос на ресурс http://teo.mynetwork.ru/olimp/staff/zeus.htm инициирует проверку .htaccess файлов в каталогах
- ./
- ./olimp/
- ./olimp/staff/
Пример
Предоставим права с помощью файлов .htaccess, нужно создать соответственно файл /var/www/html/logos/info1/.htaccess:
Options +Indexes Order deny,allow Deny from all Allow from 192.168.100.11 Allow from 192.168.100.17
и файл /var/www/html/logos/info2/.htaccess:
AuthType Basic AuthName "Boss" AuthUserFile "/var/www/main_users" Require valid-user
директива <Directory>
Определяя настройки доступа к каталогам сайта с помощью директивы <Directory> в одном конфигурационном файле всего сайта, мы получим следующие преимущества:
- можно быть уверенным, что ничего не пропустим, если вдруг нужно изменить уровень доступа к какому-нибудь ресурсу;
- повышаем скорость реакции сервера на запросы, т.к. все настройки загружаются при старте Apache.
Ну а мириться придётся с тем, что для каждого каталога необходимо описывать права отдельно (помним, что для подкаталогов права наследуются), даже если они одинаковые. Правда, есть поддержка масок, например:
<Directory ~ "^/www/.*/[0-9]{3}">
будет соответствовать именам каталогов в /www/ состоящим из трёх цифр, но это не всегда может облегчить ситуацию.
Пример
Описываем те же права в главном конфигурационном файле Apache httpd.conf или в файле настройки виртуального хоста:
<VirtualHost logos.mynetwork.ru> DocumentRoot /var/www/html/logos ServerName logos.mynetwork.ru ErrorLog /var/log/httpd/logos/error_log CustomLog /var/log/httpd/logos/access_log combined <Directory /var/www/html/logos/info1> Options +Indexes Order deny,allow Deny from all Allow from 192.168.100.11 Allow from 192.168.100.17 </Directory> <Directory /var/www/html/logos/info2> AuthType Basic AuthName "Boss" AuthUserFile "/var/www/main_users" Require valid-user </Directory> </VirtualHost>
Итог
Оба варианта настройки равноправны и создают следующие ограничения:
Доступ к ресурсу http://logos.mynetwork.ru/info1/ смогут получить только два пользователя из локальной сети с указанными IP адресами (хотя такие ресурсы лучше хранить на внутренних веб-серверах), ещё мы дали разрешение Apache, в случае отсутствия в каталоге начальной страницы, генерировать html документ с содержимым каталога.
Для доступа к ресурсу http://logos.mynetwork.ru/info2/ будут запрошены имя пользователя и пароль, которые будут сверены с данными в файле /var/www/main_users. Создадим этот файл:
# touch /var/www/main_users # chown root.webmaster /var/www/main_users
Добавим в него пользователя chef:
# /usr/bin/htpasswd2 /var/www/main_users chef
В некоторых дистрибутивах команда может называться без цифры, т.е. htpasswd, находится она в пакете с утилитами Apache, в Debian это apache2-utils
Остальных пользователей добавляем аналогичным способом. Такие файлы создаём для каждой группы пользователей с одинаковыми правами доступа к ресурсу. Одни и те же группы можно использовать во всех сайтах.
Для удаления пользователя chef из списка, используем комманду:
# /usr/bin/htpasswd2 -D /var/www/main_users chef
- Если возникли проблемы, то смотрим в логах /var/log/apache2/error_log. Можно их сделать более детальными указав в /etc/httpd/conf/httpd.conf или в конфигурации определённого виртуального хоста:
LogLevel debug
Последние штрихи
В заключении можно для изящности выделить настройку каждого сайта в отдельный файл, и подключить их в httpd.conf:
Include /etc/httpd/conf/vhosts/teo.conf Include /etc/httpd/conf/vhosts/logos.conf Include /etc/httpd/conf/vhosts/pantheon.conf
Кроме изящности мы получаем удобство в быстром подключении и отключении сайта, путём добавления/снятия символа комментария “#” в начале строки. Это особенно актуально, когда настройка каждого сайта раздувается на несколько десятков строк.
Также нелишне будет настроить ротацию журналов с помощью logrotate.
Приложение
Особенности директив Listen и NameVirtualHost
Директива Listen имеет больший приоритет чем, NameVirtualHost. Она говорит, откуда принимать запросы. В то время как последняя определяет, как обрабатывать полученный запрос. Это значит, что если указано значение
Listen 80
то Apache будет прослушивать порт 80 на всех IP адресах и директива
NameVirtualHost 10.0.10.15
не ограничивает запросы, пришедшие на другие адреса, и они будут обрабатываться наравне с указанным адресом, а если указано значение
Listen 10.0.10.15:80
то
NameVirtualHost 192.168.100.18
не возымеет действия, и сайт будет не доступен из локальной сети.
См. также
- Apache - общие вопросы, небольшие заметки, работа над ошибками.