Как стать автором
Обновить

Комментарии 50

есть мысль обойтись одной регуляркой и ифом. Как бы задать такое условие?
if ($host ~* "^(не www)\.example\.com$") {
rewrite…
}
тоже о таком думал, но не смог составить простую регулярку, которая бы это делала.

Поэтому остановился на таком костыле, который позволяет обойти ограничение, что нельзя использовать логический оператор «и» и вложенные if в nginx
Логику вложенных if можно сделать установкой переменных.

if условие {
set a «a»;
}

if условие2 {
set $aa «a»;
}

if $a==«aa» {
и т. д.
}
я так и сделал вообще-то

set $uid «www»;

if ($host ~* "^(([a-z0-9_\-]+)\.example\.com)$") {
set $uid $2;
}

if ($uid !~ "^(www)$") {
rewrite ^(.*)$ /users/$uid$1 break;
}
if ($host ~* "([a-z0-9\-]+)(?<!^www)\.example\.com$") {
    rewrite
}
птичку забыл вначале ^([a-z0-9\-]+)(?<!^www)\.example\.com$
Спасибо, добавил в израбнное на будущее.
Спасибо, сейчас стоит такая задача — подыскиваю наиболее подходящий вариант решения.
Это же достаточно элементарно. А вот про минусы не понял :/, вы раньше апачем напрямую всё отдавали?
Я нет, но есть проекты, где только апач без проксирующего nginx.

Я не спорю что это элементарно, но решения в таком виде нагуглить не удалось, поэтому решил оставить на будущее — вдруг кому пригодится.
Т.е для вас это плюс, а вы пишите минус? :)
Для меня это не минус и не плюс, а просто использование возможностей того ПО, которое у меня есть.

Для кого-то это может оказаться минусом, потому что придется устанавливать и конфигурировать доп. ПО
собственно, мое решение основано на этой статье, только там не решена проблема с www — там делается редирект, а я предложил способ, как сохранить работоспособность www

Про нижнее подчеркивание — исправил регулярку в статье
можете аргументированно пояснить, почему нельзя?
Ответ из старого топика из обсуждений

«Интересные имена со знаком „_“ :) Особенно в поддоменах. IE не берет с такого домена куки, а опера ругается, что введенный урл не соответствет стандартам (потому что не соответствует) и не грузит страницу совсем. „

Сейчас попробовал набрать
www_123.ya.ru/
www-123.ya.ru/

По первому адресу 400 Bad Request
По второму — 404
С яндексом пример некорректен. Что касается утверждения выше, то видно, что вы самостоятельно его не проверяли.

Есть много работающих ресуров, где с указанными браузерами описанных проблем не наблюдается. Например, модуль субдоменов для движка Livestreet установлен на множестве сайтов, ни от кого не поступало таких жалоб да и тестирование также не выявило никаких проблем кроме эпизода с написанием доменов в разных регистрах (сафари).

Я не знаю, о каких «стандартах» говорил тот хабраюзер, но если открыть RFC1738 (Uniform Resource Locators), то можно прочесть следующее:
Thus, only alphanumerics, the special characters "$-_.+!*'(),", and
reserved characters used for their reserved purposes may be used
unencoded within a URL.

Вы можете указать, какой конкретно стандарт запрещает использовать символ "_" для субдоменов?
Не путайте URL и Domain Names. В URL "_" допустим, в доменном имени — нет. Конкретно стандарт RFC1035, цитирую:
2.3.1. Preferred name syntax
<domain> ::= <subdomain> | " "
<subdomain> ::= <label> | <subdomain> "." <label>
<label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
<let-dig-hyp> ::= <let-dig> | "-"
<let-dig> ::= <letter> | <digit>
<letter> ::= any one of the 52 alphabetic characters A through Z in upper case and a through z in lower case
<digit> ::= any one of the ten digits 0 through 9


The labels must follow the rules for ARPANET host names. They must
start with a letter, end with a letter or digit, and have as interior
characters only letters, digits, and hyphen
. There are also some
restrictions on the length. Labels must be 63 characters or less.


2.3.1. Preferred name syntax


Я не увидел здесь прямого запрета, а вы? Предпочтительный синтаксис не означает строгого следования этим правилам. С документом ошибся, вы правы.
Ок, есть еще RFC1123 «Requirements for Internet Hosts». Читаем:
2.1 Host Names and Numbers
The syntax of a legal Internet host name was specified in RFC-952 [DNS:4].
Открываем RFC-952:
ASSUMPTIONS
1. A «name» (Net, Host, Gateway, or Domain name) is a text string up
to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus
sign (-), and period (.)
. Note that periods are only allowed when
they serve to delimit components of «domain style names». (See
RFC-921, «Domain Name System Implementation Schedule», for
background). No blank or space characters are permitted as part of a
name. No distinction is made between upper and lower case. The first
character must be an alpha character. The last character must not be
a minus sign or period.

Достаточно или еще гуглом для вас поработать? ;)

Все эти стандарты в некотором смысле рекомендательные, т.е. нет службы полицаев, которые посадят или оштрафуют за то, что вы им не следуете. Так что всегда находятся люди, которые вертели на стержне все эти RFC и рекомендации как делать предпочтительно, им пофиг, у них своё видение как всё должно работать. Слава богу их меньшинство, иначе интернета могло бы и вовсе не быть в том виде, в котором мы его знаем, а были бы кучки разрозненных анклавов.
Спасибо за потраченное время, но документы 1985 года в наши дни выглядят несколько архаично. Не исключено даже, что есть какие-то более новые документы, регулириующие эти вопросы. Я попробую вечером их найти.

Исходя из ваших слов, их на стержне вертит даже ICANN, что доказывает вот этот домен, который серьёзно превышает лимит в 24 символа: thelongestlistofthelongeststuffatthelongestdomainnameatlonglast.com
В том же RFC1035 указано не 24 символа для имени а 63 для сегмента (label), т.е. этот лимит расширили. Это прям в моем предыдущем комментарии написано. Так что ICANN никого не вертит.
Сегменты с вхождением "_" обнаружить нетрудно:

$ dig beta._domainkey.google.com TXT
$ dig beta._domainkey.google.com TXT
$ dig beta._domainkey.google.com TXT
$ dig _spf-a.microsoft.com TXT
$ dig _domainkey.cern.ch TXT


Получается, вертят крупнейшие игроки IT? Да, это не записи типа A, но всё же полноправные labels.

$ dig _domainkey.ebay.com TXT
$ dig _domainkey.yahoo.com TXT
$ dig _domainkey.yandex.ru TXT
Вот и стандарт от 2000 года нашёлся, который это дело разрешает: www.ietf.org/rfc/rfc2782.txt
Я не конца понял о чем этот стандарт, но судя по смыслу в нем предлагается использовать _ для специальных целей, что скорее даже подчеркивает тот факт, что _ нельзя использовать просто так от балды. Тут как бы сразу два нарушения — сам факт использования подчерка и расположение его на первом месте, где может быть только буква или цифра. Т.е. с таким же успехом они могли взять $, который тоже не разрешен в именах доменов или % и это бы не означало, что его теперь можно использовать где угодно.
Мутная тема ;)
Я привёл это в качестве развенчания мифа, что "_" нельзя использовать в сегментах (узлах) DNS. Как видно, он широко используется в Sender Policy Framework.
В общем мне очень понравилась наша с вами дискуссия, весьма конструктивная я считаю. Можно немного подытожить:

1. Нифига не понятно :)
2. Есть рекомендации по синтаксису доменных имен, в них "_" не рекомендован, во избежание проблем с клиентским софтом (так сказано в RFC1035)
3. Есть старые документы, прямо запрещающие использование "_" в именах хостов, доментов и т.п.
4. Есть более новые документы, разрешающие "_" в строго определенной позиции(первым символом) и в специальных DNS-записях, т.е. это алиасы на сервисы.
5. Есть чисто прикладные проблемы связанные в "_". Насколько я помню, squid, например, возможно не во всех версиях, попросту не пропускает через себя клиентов с запросами на такие домены. Админы на работе с этим сталкивались, это реальный случай.

Итого, не знаю как вы, но я сделал вывод, что все таки "_" лучше не использовать, и кстати я не вижу никаких проблем, чем дефис хуже подчерка, непонятно.

Спасибо вам за интересную беседу ;)

Можно использовать для сайтов NSFW. За пример со сквидом спасибо, изучу этот вопрос
Если узнаете что-нибудь новое — дайте знать
К тому же есть практическая сторона. Rucenter не позволит вам зарегистриовать доменное имя с "_" и если попробуете проверить такое доменное имя на свободность, выдаст ошибку:
Название домена должно состоять более чем из одного символа, начинаться и заканчиваться буквой латинского алфавита или цифрой. Промежуточными символами могут быть буквы латинского алфавита, цифры или дефис.
Т.е. для регистратора это правило очевидно (если знаете какого нибудь регистратора, который позволяет — напишите). Понятное дело, что домен второго уровня ничем принципиально от третьего (четвертого, пятого...) не отличается и правила должны быть едиными.
Мы сейчас говорим о субдоменах, то есть о сегментах четвёртого уровня в иерархии DNS. Контролируя домен второго уровня, вы можете создать произвольный субдомен без участия регистратора.
Регистрацию доменов в зоне .ru регулирует регламент, который запрещает всё, кроме a-z,0-9,-
Регалмент может быть основан на стандартах, но он никоим образом не может диктовать владельцу домена, какие ему создавать и поддерживать субдомены.
Вы хотите сказать что по чистой случайности этот регламент совпадает с «предпочтениями» в RFC1035? ;)
Ни в коем случае ;)

Неясно лишь, почему нельзя использовать то, что на самом деле успешно работает.
ISPmanager нормально работает с nginx и без там это делается в 2 клика:

Выбираем нужный домен — добавить запись-

Имя: *
Тип: A
Адрес: Ip адрес сайта

На мастерхосте в админке помнится тоже делалось аналогично, создавался поддомен *.example.com, указывающий на основную папку домена.

Остальное — работа самой CMS, правила в .htaccess.

И будет хоть username.example.com, хоть username.users.example.com, хоть super-article.news.example.com
как раз правила в .htaccess это самое интересное, dns прописать дело 2 минут
Смотря как CMS сделана, и для чего требуются динамические поддомены. .htaccess и тот не всегда будет нужен — можно обойтись и вообще без его изменения. Только с CMS немного повозиться, что бы ссылки автоматом заменяла и соображала что показывать на главной странице поддомена, когда больше никаких параметров в url не задано.
НЛО прилетело и опубликовало эту надпись здесь
Ну я имею в виду что добавление A записи *.example.com — дело 2 минут, а вот наладить сервер чтобы работали все рерайты как надо для поддоменов — уже сложнее (особенно если надо не просто рерайтить поддомен в папку а для поддомена сделать чтобы были работоспособны все человеко-понятные адреса страниц, которые уже есть на сайте, т.е. сделать рерайт вида username.example.com => example.com/users/username => example.com/users.php?page=about&name=username)

Мое решение позволило мне вынести на поддомен довольно большое количетсво страниц (страница с контактами, анкета, еще несколько), приэтом не переписывая заново все рерайты в .htaccess а просто добавив несколько строк в конфиг nginx
Дописали, бы в статье своей что нужно еще сделать для того чтоб username.example.com работал без указания всех возможных доменов в конфиге веб-сервера.
Статья как делать НЕ НАДО — if,rewrite это зло.

Правильное решение:

server {
    server_name   www.example.com;

    location / {
         proxy_pass 11.22.33.44:8080;
    }
}

server {
    server_name   ~^(?<user>[a-z0-9\-]+)\.example.com$;

    location / {
        proxy_pass 11.22.33.44:8080/users/$user$uri$is_args$args;
    }
}
Спасибо, за совет, завтра с утра проверю ваш вариант.
Этот вариант работает и он правильный. А за использование вашего надо бить по рукам ;)
ну я первый раз в жизни конфигурировал nginx :)

Настроил так, как смог, поэтому и опубликовал топик, расчитывая на то, что подскажут как сделать то же самое, но лучше.

Топик обновил.
А просто example.com как обработать?
думаю как-то так
server {
server_name www.example.com, example.com;
либо отдельно
Теперь в избранное.
Спасибо.
А вас не беспокоит, что, к примеру, у вас остаются рабочими обе ссылки:
example.com/user
и
user.example.com/

И для них URL для ссылок, стилей и скриптов могут указывать на разные файлы.
<a href="/contacts.html">контакты</a> — /var/www/contacts.html | /var/www/example.com/user/contacts.html

Не беспокоит, у меня настроен permanent redirect с example.com/user на user.example.com/
Дело в том, что у на нашем сайте выносить свой аккаунт на поддомен могут только платные пользователи, поэтому бесплатным доступен адрес example.com/user, а платные могут выбрать себе урл и получить адрес user.example.com/ с перманентным редиректом со старого адреса, чтобы сохранить все страницы в поиске.

Ссылки не волнуют, они генерируются автоматически, и являются не относительными, а абсолютными.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории