Nginx 中的行顺序重要吗?

Nginx 中的行顺序重要吗?

我有一个像这样的服务器文件

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

return 301 https://$server_name$request_uri;

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

现在当我尝试时sudo letsencrypt renew。它会抛出错误并说找不到.well-known/acme-challenge。但是当我评论该return 301行时,服务器重新启动并且它工作了。

现在我想重新测试它,把位置放在第一位,不注释返回 301 语句,但它说certificate not due for renewal。所以问题是读取文件的顺序是否重要?并且由于这个原因它不会自动更新,那些进行更新的人如何处理这种情况?

答案1

在这种情况下,排序并不是那么重要(关于如何评估位置和正则表达式的一个很好的解释可以在这里找到:https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms)。

对于位置块之类的事情,简短的版本是最佳匹配获胜,而不是第一场比赛获胜。

但是,对于你的情况,顺序很重要,因为你使用了return。每https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return

停止处理并向客户端返回指定代码。非标准代码 444 关闭连接而不发送响应标头。

这里的关键是return立即停止处理/评估,因此发生的情况是 nginx 没有查看下面的任何内容return

因此您只需将该子句移到return您的位置块下方即可。

至于测试,我会尝试添加--test-cert到您的命令行(请参阅https://certbot.eff.org/docs/using.html#certbot-command-line-options)。

这应该可以避免您在尝试使用其生产服务器时遇到的“问题”,该服务器报告您有一个有效的证书并且现在不需要新的证书。

答案2

您应该将您的return指令包含在一个location块中,然后location使用正常的块匹配规则:

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

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

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

答案3

answering for the idea of line orders in nginx config files

是的,它确实如此,并且完全取决于 Nginx 支持的不同上下文中指定的不同指令。通俗地说,nginx 会保留一堆要做的事情,并根据这些事情分别应用某些算法best match

Nginx 用于selection algorithm根据上下文做出决策server;主要基于两个指令,即listenserver_name

可以定义多个位置上下文,每个位置用于处理某种类型的客户端请求,并且通过将位置定义与客户端请求进行匹配来选择每个位置selection algorithm

上下文默认upstream用于round-robin确定将请求交给哪个特定服务器。

相关内容