【问题标题】:ngnix www to no-www on config file generated by certbot由 certbot 生成的配置文件上的 nginx www 到非 www
【发布时间】:2018-10-16 09:55:45
【问题描述】:

我正在尝试获取对 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
}

【问题讨论】:

    标签: nginx lets-encrypt certbot


    【解决方案1】:

    打开括号以获得更清晰的方式。

    创建 2 个,而不是一个 443 监听器。与 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 本身也可以进行重定向。

    希望对您有所帮助,如有任何问题,请发表评论。

    【讨论】:

    • 对 Drupal 的观察很好,但我有一些非 Drupal 域,并且更喜欢类似的配置文件。你的建议奏效了,谢谢!但是一些需要微调的问题 - (1) 我是否需要两个 80 的听众,因为 example.com 和 www.example.com 都去 https://example.com - 大概是因为 if ($host = ...) 语句。 (2) 另外,我是否必须为 443 复制整个块,包括 rootindex 和所有 location 语句?还是我可以只保留一个 443 块和 if ($host = example.com ...) 似乎在 80 块中工作的语句?
    • 嗨,分隔块意味着清楚地了解 nginx 中发生的事情,使用“ifs”和其他条件,您甚至可以将所有域放在同一个服务器块中{}。实际上,是的,您可以在 2 个服务器块上加入两个域{},一个用于 80,另一个用于 443。443 块是“特殊的”。您不需要 www 块中的根目录或索引,因为您不会将其定向到您的应用程序,您只需要将该块重定向到非 www。您唯一需要的是证书(因为不安全的中间重定向意味着整个连接不安全)。
    • 所以你需要监听什么端口,监听什么域名,该域的证书,以及重定向到哪里,因为你不需要去你的应用程序搜索任何索引,也不需要放一个root 去哪里(因为 https 非 www 域是唯一一个将连接到应用程序的域)。至于为什么分隔块与尝试在同一行中执行整个脚本相同,它可以工作,它会工作,但是当你两个月后回来时,你会因为那样做而讨厌自己,并且不清楚和间隔。很高兴我帮助了:)
    • 知道了!说得通。应该听从你的明智建议:)
    【解决方案2】:

    它现在可以工作了,@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
    }
    

    【讨论】:

      猜你喜欢
      • 2021-08-17
      • 2018-12-12
      • 2015-02-13
      • 2011-12-18
      • 2018-01-07
      • 1970-01-01
      • 2020-03-11
      • 1970-01-01
      • 2014-05-12
      相关资源
      最近更新 更多