Я также натолкнулся на этот вопрос, прибегая к помощи по поиску динамического резервного файла apache2, и ответ Люка мне очень помог в решении моей проблемы, но я все еще хочу показать, что я сделал для достижения своих целей, главным образом потому, что это включало некоторые дополнительные работы и потому, что я думаю, что это может быть полезным для любых будущих гуглеров ...
Мои цели
- динамический хостинг для всех доменов и поддоменов, указывающих на мой VPS
foo.com
должен обслуживать тот же контент, что и www.foo.com
- запасной вариант для неизвестных доменов по умолчанию
- откат для неизвестных поддоменов
foo.com
до, www.foo.com
если www
он недоступен, вместо этого откат к умолчанию
DNS
У меня есть пара доменов (и всех их поддоменов), указывающих на мой VPS, например:
- foo.com
- bar.com
- foobar.com
Файловая система
У меня есть следующие каталоги, домены содержат каталоги с именами доступных поддоменов, требуется каталог www, но конфигурация должна быть в состоянии справиться с ситуацией, когда ее нет. Localhost используется как запасной вариант по умолчанию:
/var
/www
/localhost
/foo.com
/www
/bar
/bar.com
/foo
тесты
Перевод моих целей в проверяемые случаи:
- foo.com должен быть подан с foo.com/www
- www.foo.com должен быть подан с foo.com/www
- bar.foo.com должен быть подан с foo.com/bar
- foo.foo.com должен быть подан с foo.com/www (foo.com/foo не существует)
- bar.com должен обслуживаться с localhost (bar.com/www не существует)
- www.bar.com должен обслуживаться с localhost (bar.com/www не существует)
- foo.bar.com должен быть подан с bar.com/foo
- bar.bar.com должен обслуживаться с localhost (bar.com/bar не существует)
- foobar.com должен обслуживаться с локального хоста (foobar.com не существует)
- www.foobar.com должен обслуживаться с localhost (foobar.com не существует)
- foo.foobar.com должен обслуживаться с локального хоста (foobar.com не существует)
Решение
Это использование: mod_rewrite
, mod_proxy_http
и конечно mod_vhost_alias
.
ServerName my.domain
ServerAdmin admin@my.domain
<VirtualHost *:80>
ServerName localhost
VirtualDocumentRoot /var/www/localhost
</VirtualHost>
<VirtualHost *:80>
ServerName sub.domain
ServerAlias *.*.*
VirtualDocumentRoot /var/www/%-2.0.%-1.0/%-3
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.*)\.(.*)\.(.*)$ [NC]
RewriteCond /var/www/%2.%3 !-d
RewriteRule (.*) http://localhost/$1 [P]
RewriteCond %{HTTP_HOST} ^(.*)\.(.*)\.(.*)$ [NC]
RewriteCond /var/www/%2.%3/%1 !-d
RewriteCond /var/www/%2.%3/www !-d
RewriteRule (.*) http://localhost/$1 [P]
RewriteCond %{HTTP_HOST} ^(.*)\.(.*)\.(.*)$ [NC]
RewriteCond /var/www/%2.%3/%1 !-d
RewriteRule (.*) http://%2.%3/$1 [P]
</VirtualHost>
<VirtualHost *:80>
ServerName bare.domain
ServerAlias *.*
VirtualDocumentRoot /var/www/%-2.0.%-1.0/www
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.*)\.(.*)$ [NC]
RewriteCond /var/www/%1.%2 !-d [OR]
RewriteCond /var/www/%1.%2/www !-d
RewriteRule (.*) http://localhost/$1 [P]
</VirtualHost>
Как это работает? Определены три виртуальных хоста:
локальный
Localhost служит по умолчанию. Все неразрешимые запросы обслуживаются localhost. Настройка символической ссылки с localhost на любой из ваших доменов аналогична настройке этого сайта по умолчанию.
sub.domain
Sub.domain vhost принимает все запросы в форме *.*.*
. По умолчанию все запросы обслуживаются /domain.com/sub
как определено VirtualDocumentRoot /var/www/%-2.0.%-1.0/%-3
.
отступать:
Первый RewriteRule
заботится о неизвестных доменах, например. domain.com
Каталог не существует, путем прокси на сайте localhost.
Второй RewriteRule
также проксирует localhost, когда domain.com/sub
и domain.com/www
каталоги, и каталоги отсутствуют.
Третий RewriteRule
прокси, domain.com
когда domain.com/sub
не существует. Мы знаем, domain.com/www
что существует из-за второго блока перезаписи.
bare.domain
Хостинг bare.domain принимает *.*
запросы и обслуживает их./domain.com/www
Здесь RewriteRule
будет прокси для localhost, когда domain.com
или domain.com/www
не существует.
^ $%. * !!!
У меня были некоторые проблемы с тем, чтобы обернуть голову вокруг всех этих знаков $
и %
знаков, RewriteCond
и RewriteRule
поэтому я объясню о них здесь:
ServerAlias *.*.*
VirtualDocumentRoot /var/www/%-2.0.%-1.0/%-3
RewriteCond %{HTTP_HOST} ^(.*)\.(.*)\.(.*)$ [NC]
RewriteCond /var/www/%2.%3/%1 !-d
RewriteRule (.*) http://%2.%3/$1 [P]
*
В ServerAlias
только подстановочные.
%n
В VirtualDocumentRoot
это от имени документа интерполяции .
- Во
%n
втором RewriteCond
относятся к выборам (.*)
из первого RewriteCond
, например. части запрашиваемого домена.
%n
В RewriteRule
тоже.
$1
В RewriteRule
относится к выбору (.*)
в начале RewriteRule
. Который захватывает все от домена до ?
URL-адреса в запросе. Любая строка запроса автоматически добавляется в URL mod_proxy
.