将所有请求重定向到 HTTPS,但一个子目录除外

将所有请求重定向到 HTTPS,但一个子目录除外

我正在尝试将我的 nginx 网络服务器上的自签名证书转移到 Let's Encrypt 证书。

目前,我将所有请求重定向http/80https/443,它使用我之前创建的自签名证书。

现在 - 据我所知,Let's Encrypt 向端口 80 发出请求(因为我使用的是 选项webrootcertbot。这些请求被重定向,导致证书生成失败。

我尝试使用以下服务器块来实现这一点,监听端口 80:

server {
        listen  80;     
        server_name     sub.domain.tld;
        server_tokens   off;


        location /.well-known {
                root /var/www/letsencrypt;
        }

        location / {
                return 301 https://$host$request_uri;
        }
}

但无论如何,请求都会/.well-known被重定向到。https/443

我如何才能将除到 的请求之外的所有请求重定向http/80到?https/443/.well-known/

答案1

尝试这个:

server {
    listen  80;     
    server_name     sub.domain.tld;
    server_tokens   off;

    root /var/www/letsencrypt;

    location /.well-known {
        try_files $uri $uri/ =404;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

由于您的虚拟服务器中没有try_files条目,它不知道如何处理发往的请求/.well-known

答案2

我遇到了同样的问题,但需要稍微不同的解决方案。

以下是我的服务器块的样子

server {
    listen 80;
    server_name example.com www.example.com;

    location /.well-known/acme-challenge/ {
        root /usr/share/nginx/html;
        try_files $uri =404;
    }

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

事实证明,这是一个“陷阱” NGINX 称之为return上下文不正确

return 指令仅适用于其定义的最顶层上下文。在此示例中:

server {
   location /a/ {
       try_files test.html =404;
   }

   return 301 http://example.org;
}

请求/a/test.html将返回 301。为了使其按预期工作,将第二个块包装在里面location /

server {
   location /a/ {
       try_files test.html =404;
   }

   location / {
       return 301 http://example.org;
   }
}

我理解他们的意思,但措辞有点令人困惑。我更愿意将这种行为描述为

return指令优先于location同一上下文中定义的所有块。

按照建议,将其包装return在一个块中,解决了这个问题。location /

相关内容