Nginx - 可以在服务器块级别安全地使用“if”吗?

Jos*_*aro 7 nginx web-server

Nginx 文档毫不含糊地警告说if 是邪恶的,应该尽可能避免,并且在互联网的长度和广度上散布着类似的警告。

然而,这些警告中的大多数都特别关注块中的if行为有多糟糕location。此外,Nginx 文档说:

如果在位置上下文中,可以在内部完成的唯一 100% 安全的事情是:

  • 返回 ...;

  • 重写……最后;

我的问题是:如果其中包含的唯一指令是 a,那么在块if级别server(而不是location块)使用 an 是否安全return?例如,以下 www-to-non-www 重定向:

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

    if ($http_host != example.com) {
        return 301 http://example.com$request_uri;
    }

    # more config
}
Run Code Online (Sandbox Code Playgroud)

次要问题:我知道做这种事情的推荐方法是使用两个server具有不同值的块server_name。如果这一个可以接受的用途if,是否有任何理由仍然使用两个单独的server块?

Ter*_*nen 2

nginx 收到请求时的第一步是评估 HTTPHost标头/TLS SNI 字段,并根据评估结果选择虚拟主机。

这意味着Host标头始终会被处理。

现在,如果您指定if重定向语句,则意味着Host将检查标头两次,首先选择虚拟主机,然后检查条件if。这是处理器工作量的两倍。

一个反驳的论点可能是单独服务器块的内存消耗。然而,在 nginx 进程的生命周期中,内存分配是相同的,而 header 的双重评估Host发生在每个请求上。