Перенаправление субдомена с регулярным выражением в nginx

В документации nginx говорится, что директива server_name поддерживает регулярные выражения. Я бился головой о стену, пытаясь заставить работать даже тривиальное регулярное выражение.

Я хочу, чтобы http://subdomain.mydomain.com/ перенаправлял на http://mydomain.com/subdomain

Вот мой код

server {
  server_name "~^subdomain\.mydomain\.com$";
  rewrite ^ http://mydomain.com/subdomain;
}

Также потенциально заслуживает внимания. Далее в конфигурационном файле nginx есть правило:

server {
  server_name *.mydomain.com
  ...
}

Что я делаю неправильно?

ОБНОВИТЬ:

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

server {
  server_name "~^.*(cvg|cincinnati)\.fakeairport(app)?\.(org|com)$";
  rewrite ^ http://fakeairport.com/cincinnati;
}

server {
  server_name "~^.*(lex|lexington)\.fakeairport(app)?\.(org|com)$";
  rewrite ^ http://fakeairport.com/lexington;
}

Так что было бы предпочтительнее использовать регулярные выражения.

5 ответов

Решение

Чтобы ответить на старый вопрос, чтобы помочь другим

используя nginx 1.1.19 вы можете сделать следующее:

server {
    server_name     ~^(?<subdomain>\w+)\.domainA\.com$;

    location / {
            rewrite ^ https://$subdomain.domainB.com$request_uri permanent;
    }
}

Субдомен до domainA.com сопоставляется и сохраняется в переменной $subdomain, которую затем можно использовать при перезаписи. Это переписывает URL как xxx.domainA.com в xxx.domainB.com только с одной директивой сервера.

Должен любить регулярные выражения с NGINX!

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

В этом случае я решил это с помощью следующего регулярного выражения:

server {
    listen 80;
    server_name ~^((?<subdomain>.*)\.)(?<domain>[^.]+)\.(?<tld>[^.]+)$;
    return 301 $scheme://${domain}.${tld};
}

Это делает следующее: каждый subdomain.domain-name.tld который указывает на этот сервер (IP-адрес) автоматически перенаправляется на domain-name.tld,

Так, например, www.myexampledomain.com перенаправлен на myexampledomain.com,

Чтобы ответить на вопрос, вы также можете сделать следующее:

server {
    listen 80;
    server_name ~^((?<subdomain>.*)\.)(?<domain>[^.]+)\.(?<tld>[^.]+)$;
    return 301 $scheme://${domain}.${tld}/${subdomain};
}

Сейчас mysubdomain.myexampledomain.com превращается в myexampledomain.com/mysubdomain,

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

Если вы прочитаете правила сопоставления имя_сервера, то увидите, что префикс и суффикс имя_сервера проверяются перед именами регулярных выражений, но после точных имен узлов. Поскольку *.mydomain.com совпадает, регулярное выражение не проверяется. Тот факт, что он указан ранее в конфигурации, не имеет значения. Поскольку вы просто пытаетесь сопоставить одно имя хоста с вашим регулярным выражением, просто:

server {
  server_name subdomain.mydomain.com;
  rewrite ^ http://mydomain.com/subdomain$request_uri?;
}

server {
  server_name *.mydomain.com;

  # stuff
}

будет работать на вас.

Я знаю, что все говорят, является ли зло в конфигурационных файлах nginx, но иногда вы не можете обойтись иначе.

server {
      server_name .mydomain.com;

      if ( $host ~ subdomain.mydomain.com ) {
                rewrite ^(.*) http://mydomain.com/subdomain$1;
      }
}

Просто в качестве комментария. Если вы хотите перенаправить все уровни поддоменов на первый уровень поддоменов, например, когда вы используете подстановочный SSL-сертификат, вы можете использовать:

server {
    listen 80;
    server_name ~^(.*)\.(?<subdomain>\w+).mydomain\.com$;
    return          301 https://$subdomain.mydomain.com$request_uri; 
}

server {
    listen 80;
    server_name ~^(?<subdomain>\w+).mydomain\.com$;
    return          301 https://$subdomain.mydomain.com$request_uri;
}

Первый предназначен для перенаправления многоуровневого субдомена http на первый уровень субдомена в https. И следующий - для перенаправления субдомена первого уровня в http на тот же субдомен в https.

Другие вопросы по тегам