Назад | Перейти на главную страницу

От Apache к Nginx: сложные перезаписи с поддоменами с подстановочными знаками

Я перехожу с Apache на Nginx и пытаюсь понять, как заставить работать правила перезаписи моего поддомена.

Apache

Конфигурация Apache, которая у меня есть, в основном перемещает весь трафик на HTTPS и меняет домены .net и .org на основной домен .com. Некоторые из наших пользователей по-прежнему считают, что каждый URL-адрес должен начинаться с «www», поэтому программа установки удаляет его, если есть еще один поддомен. URL-адреса без поддомена перенаправляются на https://www.example.com что не обязательно является обязательным для работы сайта.

# HTTP
<VirtualHost *:80>
    RewriteEngine on

    # Redirect http://example.tld -> https://www.example.com
    RewriteCond %{SERVER_PORT} !^443$
    RewriteCond %{HTTP_HOST} ^example\.(com|net|org)
    RewriteRule ^(.*)$ https://www.example.com$1

    # Redirect http://www.subdomain.example.tld -> https://subdomain.example.com
    RewriteCond %{SERVER_PORT} !^443$
    RewriteCond %{HTTP_HOST} ^www.([^\.]+)\.example\.(com|net|org)
    RewriteRule ^(.*)$ https://%1.example.com$1

    # Redirect http://subdomain.example.tld -> https://subdomain.example.com
    RewriteCond %{SERVER_PORT} !^443$
    RewriteCond %{HTTP_HOST} ^([^\.]+)\.example\.(com|net|org)
    RewriteRule ^(.*)$ https://%1.example.com$1 [NC,R,L]

    # ...

</VirtualHost>

# HTTPS
<VirtualHost *:443>
    RewriteEngine on

    # Redirect https://example.tld -> https://www.example.com
    RewriteCond %{HTTP_HOST} ^example\.(com|net|org)
    RewriteRule ^(.*)$ https://www.example.com$1

    # Redirect https://www.subdomain.example.tld -> https://subdomain.example.com
    RewriteCond %{HTTP_HOST} ^www.([^\.]+)\.example\.(com|net|org)
    RewriteRule ^(.*)$ https://%1.example.com$1

    # Redirect https://subdomain.example.(net|org) -> https://subdomain.example.com
    RewriteCond %{HTTP_HOST} ^([^\.]+)\.example\.(net|org)
    RewriteRule ^(.*)$ https://%1.example.com$1 [NC,R,L]

    # Otherwise serve https://subdomain.example.com

    # ...

</VirtualHost>

Nginx

Конфигурация Nginx, которая у меня есть до сих пор, работает в большинстве случаев, но я не знаю, как удалить «www», если URL-адрес имеет вид http (s): //www.subdomain.example.tld. В соответствии с https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#server-name-if "if is evil", поэтому я старался не допускать их использования в наиболее распространенных случаях.

# Redirect http://subdomain.example.com -> https://subdomain.example.com
# Redirect http://example.com -> https://example.com
server {
    listen       80;
    server_name  .example.com;
    return       301 https://$host$request_uri;
}

# Redirect https://subdomain.example.(net|org) -> https://subdomain.example.com
server {
    listen       80;
    server_name  .example.net .example.org;
    if ($host ~* "^([^.]+(\.[^.]+)*)\.example\.(net|org)$") {
            set $subdomain $1;
            rewrite ^(.*)$ https://$subdomain.example.com$1 permanent;
            break;
    }
    return 301 https://www.example.com;
}

# Otherwise serve https://subdomain.example.com
server {
    listen       443 ssl;
    server_name  .example.com;

    # ...
}

Итак, мой вопрос: как мне удалить часть «www», когда есть другой субдомен, который уже представляет правильный способ Nginx? В оптимальном случае конфигурация Nginx должна работать так же, как моя старая конфигурация Apache. Есть много вопросов и ответов, которые относятся к простым случаям, когда поддомены могут быть указаны вручную в файле конфигурации. Для меня это не вариант.

Поняв, что server_name также может быть регулярным выражением это то, что у меня есть сейчас. Еще одним положительным сюрпризом стало то, что такой же server блок может обрабатывать случаи HTTP и HTTPS. Мне просто нужно было прокомментировать ssl on; линия от моего ssl.inc файл конфигурации. Насколько я могу судить, эта настройка работает как моя старая конфигурация Apache.

# Redirect http://example.tld -> https://www.example.com
server {
    listen       80;
    server_name  www.example.com www.example.net www.example.org;
    return       301 https://www.example.com$request_uri;
}

# Redirect http(s)://example.tld -> https://www.example.com
server {
    listen       80;
    listen       443 ssl;
    server_name  example.com example.net example.org;
    return       301 https://www.example.com$request_uri;

    include conf.d/ssl.inc;
}

# Serve https://subdomain.example.com
server {
    listen       443 ssl;
    server_name  ~^[^\.]+\.example\.com$;

    include conf.d/ssl.inc;
    include conf.d/common.inc;
}

# Redirect http(s)://www.whatever.subdomain.example.tld -> https://subdomain.example.com
server {
    listen       80;
    listen       443 ssl;
    server_name  ~\.(?<subdomain>[^\.]+)\.example\.(com|net|org)$  ~^(?<subdomain>[^\.]+)\.example\.(net|org)$;
    return       301 https://$subdomain.example.com$request_uri;

    include conf.d/ssl.inc;
}