RewriteCond %{HTTP_HOST} !^(www\.)?domain.ru$
RewriteCond %{HTTP_HOST} ^([a-zA-Z0-9-]+)\.domain.ru$
RewriteRule .? - [E=siteName:%1]
# папка поддомена существует, домен, значит, тоже.
RewriteCond /home/domain.ru/public_html/%{ENV:siteName} -d
RewriteCond %{QUERY_STRING} !&' # запрос ещё не был перезаписан.
# перезаписываем:
RewriteRule ^/?(.*)$ %{ENV:siteName}/$1?&' [L,QSA]
# такого домена нет, даём 410 gone.
RewriteCond %{HTTP_HOST} !^(www\.)?domain.ru$
RewriteCond /home/domain.ru/public_html/%{ENV:siteName} !-d
RewriteCond %{QUERY_STRING} !&'
RewriteRule .? - [G,L]
ErrorDocument 410 http://www.domain.ru/410
mod_rewrite - доступность поддоменов по пути
С DNS gроблем нет, трудности с подстановкой путей. Я сделал это через mod_rewrite и всё работает, но есть пара мелочей, например, при запросе папки без последнего слэша апач перенаправляет на тот же путь, добавляя слеш, а к нему добавляется ещё &'.
Да и в целом решение кажется не очень надёжным.
Вот .htaccess:
Код:
При таком подходе есть папка public_html, в которой основной движок сайта перемешан с папками поддоменов. Например, можно запросить папку движка (типа images), которая не является форумом.
Я пробовал сделать другую структуру:
* public_html/www - основной движок;
* public_html/name, ... - папки поддоменов.
Однако постоянно натыкаюсь на зацикливание подзапросов (в первом (работающем) варианте для этого использую &' в query string).
Какие есть идеи по этому вопросу?
p.s: вообще, mod_rewrite очень сложно отлаживать, т.к. не понятно, что он запрашивает. Может есть какая-то настройка чтоб было проще с ним работать?
Но для этого нужно перезапускать сервер при каждой регистрации, чего делать не хочется.
Структура папок стала нормальной, то есть public_html/www для основного домена и public/html/subdomain, sub2, и т.д. для прочих.
Может кому пригодится моё решение (объяснено ниже):
Код:
server {
listen 1.1.1.1:80;
server_name domain.ru *.domain.ru;
location ~ ^(.*)$ {
set $Path $1;
set $Subdomain www;
if ($host ~* ^([\w\d-]+).domain.ru$) {
set $Subdomain $1;
}
proxy_pass http://1.1.1.1:81/$Subdomain$Path;
proxy_redirect http://domain.ru/ /^;
proxy_set_header Host domain.ru;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
if ($host ~* ^(www.)?domain.ru$) {
rewrite ^/?\^([^/]+)(/.*)?$ http://$1.domain.ru$2;
}
}
listen 1.1.1.1:80;
server_name domain.ru *.domain.ru;
location ~ ^(.*)$ {
set $Path $1;
set $Subdomain www;
if ($host ~* ^([\w\d-]+).domain.ru$) {
set $Subdomain $1;
}
proxy_pass http://1.1.1.1:81/$Subdomain$Path;
proxy_redirect http://domain.ru/ /^;
proxy_set_header Host domain.ru;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
if ($host ~* ^(www.)?domain.ru$) {
rewrite ^/?\^([^/]+)(/.*)?$ http://$1.domain.ru$2;
}
}
Эти директивы - обход proxy_redirect, который не поддерживает ни переменные, ни регулярки в первом параметре (пробовал default, но nginx ругался на синтаксис).
Поэтому сделал вариант, когда по запросу пути, начинающегося с ^ на главном домене domain.ru он будет перенаправляться на поддомен.