ngnix с www на no-www в конфигурационном файле, сгенерированном certbot

Я пытаюсь получить запросы к example.com, а также к www.example.com, чтобы перейти на https://example.com в файле конфигурации, показанном ниже. Файл точно такой же, как созданный certbot.

Изменение двух операторов return 301 на

return 301 https://example.com$request_uri;

не работает, так как https://www.example.com по-прежнему ведет на https://www.example.com, а не нужный https://example.com

Был бы признателен, если бы кто-нибудь мог указать точные изменения, необходимые для получения желаемого результата. Упрощенные инструкции были бы бонусом, так как я новичок как в nginx, так и в certbot. Спасибо.

server {
    root /var/www/html/drupal;
    index  index.php index.html index.htm;
    server_name example.com www.example.com;

    location / {
        try_files $uri /index.php?$query_string;        
    }

    location @rewrite {
        rewrite ^/(.*)$ /index.php?q=$1;
    }

    location ~ [^/]\.php(/|$) {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ ^/sites/.*/files/styles/ {
        try_files $uri @rewrite;
    }

    location ~ ^(/[a-z\-]+)?/system/files/ {
        try_files $uri /index.php?$query_string;
    }

    listen [::]:443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


}
server {
    if ($host = www.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 404; # managed by Certbot
}

person dmdip    schedule 16.10.2018    source источник


Ответы (2)


Раскройте скобки для более ясного пути.

Вместо одного слушателя 443 создайте 2. То же самое с 80.

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

server {
    listen 80;
    listen [::]:80;
    server_name  www.example.com; #this will only listen to http://www.example.com
    location / {        
       return 301 https://example.com$request_uri; #and will upgrade to https
    }
       #we don't want that many redirects, so this will go directly to example.com
 }

server {
    listen 80;
    listen [::]:80;
    server_name  example.com; #this will only listen to http://example.com
    location / {        
       return 301 https://$host$request_uri; #and will upgrade to https
    }
 }
server {
server_name  www.example.com;

location / {
    return 301 https://example.com$request_uri #this redirects to non-www
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server{
#same server configuration as your first server bracket, only accepting     https://example.com and not www.
}

Я вижу, что вы отправляете поступающее соединение на Drupal, поэтому подумайте, что у Drupal есть переменная $base_url, которая делает любое перенаправление, которое он делает, на этот хост, поэтому, если он установлен на www.example.com, это не имеет значения вы nginx conf, так как сам Drupal также может делать редиректы.

Надеюсь, что это помогло, комментарий для любого вопроса.

person flaixman    schedule 16.10.2018
comment
Отличное замечание о Drupal, но у меня есть несколько доменов, отличных от Drupal, и я бы предпочел похожие файлы конфигурации. Ваше предложение сработало, спасибо! Но некоторые вопросы для тонкой настройки: (1) Нужно ли мне два слушателя для 80, так как example.com и www.example.com оба переходят на https: //example.com - предположительно из-за операторов if ($host = ...). (2) Кроме того, нужно ли будет копировать весь блок для 443, включая root, index и все операторы location? Или я могу оставить только один блок 443 с операторами if ($host = example.com ...), которые, похоже, работают в блоке 80? - person dmdip; 17.10.2018
comment
Привет, Разделение блоков означает четкое видение того, что происходит в вашем nginx, с помощью ifs и других условий вы даже можете поместить все домены в один и тот же серверный блок {} . На самом деле, да, вы можете объединить оба домена в блок из 2 серверов{}, один для 80, а другой для 443. Блок 443 особенный. Вам не нужен ни корень, ни индекс в блоке www, так как вы не собираетесь направлять его в свое приложение, вам понадобится только этот блок для перенаправления на не-www. Единственное, что вам нужно, это сертификат (поскольку незащищенное среднее перенаправление означает, что все соединение не является безопасным). - person flaixman; 17.10.2018
comment
Таким образом, вам нужно, какой порт слушать, какое доменное имя слушать, сертификат этого домена и куда перенаправлять, так как вам не нужно будет обращаться к своему приложению для поиска по любому индексу или помещать корень, куда идти (как https домен без www — единственный, который обеспечит подключение к приложению). А почему разделение блоков это то же самое, что пытаться сделать весь скрипт в одной строке, это может работать, это будет работать, но когда вы вернетесь через 2 месяца, вы будете ненавидеть себя за то, что так делаете, и непонятно и разнесены. Рад, что помог :) - person flaixman; 17.10.2018
comment
Понятно! Имеет смысл. Последую вашему мудрому совету :) - person dmdip; 17.10.2018

Теперь все работает, @flaixman. Я сделал одно изменение по сравнению с вашим предложением - сделать только один блок для 80, так как они оба делали одно и то же. Итак, вот окончательный вариант: (Надеюсь, я не напортачил что-то, что позже может вызвать проблемы.)

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    location / {
        return 301 https://example.com$request_uri;
    }
}

server {
    server_name www.example.com;
    location / {
        return 301 https://example.com$request_uri;
    }
    listen [::]:443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server{
    root /var/www/html/d8;
    index index.php index.html index.htm;
    server_name example.com;

    location / {
        try_files $uri /index.php?$query_string;        
    }

    location @rewrite {
        rewrite ^/(.*)$ /index.php?q=$1;
    }

    location ~ [^/]\.php(/|$) {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ ^/sites/.*/files/styles/ {
        try_files $uri @rewrite;
    }

    location ~ ^(/[a-z\-]+)?/system/files/ {
        try_files $uri /index.php?$query_string;
    }

    listen [::]:443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
person dmdip    schedule 18.10.2018