nginx server_name 通配符或包罗万象

Posted

技术标签:

【中文标题】nginx server_name 通配符或包罗万象【英文标题】:nginx server_name wildcard or catch-all 【发布时间】:2012-03-16 07:41:44 【问题描述】:

我有一个正在运行的 nginx 实例,它为多个网站提供服务。第一个是关于服务器 IP 地址的状态消息。第二个是admin.domain.com 上的管理控制台。这些效果很好。现在我希望所有其他域请求都转到单个 index.php - 我有很多域和子域,在 nginx 配置中列出它们是不切实际的。

到目前为止,我已尝试将 server_name 设置为 *,但由于通配符无效而失败。 *.* 在我添加其他服务器块之前一直有效,然后我猜它会与它们冲突。

在定义了其他站点之后,有没有办法在 nginx 中运行一个包罗万象的服务器块?

注意我不是垃圾邮件发送者,这些是具有有用内容的真实网站,它们只是由数据库中的同一个 CMS 提供支持!

【问题讨论】:

最好将此作为主要来源nginx.org/en/docs/http/server_names.html 【参考方案1】:

在你的包罗万象的服务器块中将监听选项更改为此。 (添加default_server)这将占用您所有未定义的连接(在指定端口上)。

listen       80  default_server;

如果你想在文件或文件夹不存在的情况下将所有内容推送到 index.php;

try_files                       $uri /$uri /index.php;

每the docs、It can also be set explicitly which server should be default, with the **default_server** parameter in the listen directive

【讨论】:

完美运行 - 非常感谢。我不能使用server_name _; 作为IP 地址的状态页,我必须指定server_name x.x.x.x 但没关系! 添加 default_server 似乎不适用于 nginx 1.4.6,它目前是 Ubuntu 14.04 上的最新版本......当我添加它时,configtest 命令返回错误,并且重新启动服务器也不起作用。我已经使用 Debian jessie 在我的服务器上尝试了完全相同的配置,它具有 nginx 1.6.2,并且运行良好。因此,如果您使用的是 1.4.6,请尝试其他版本 ... HTTPS 的旁注:default_server 指令还设置将处理该端口上请求的 SSL 握手的服务器。因此,如果您希望服务器块 A 处理 SSL,但服务器 B 充当 HTTPS 的包罗万象,则解决方案是在服务器 B 上设置 server_name ~^(.+)$【参考方案2】:

作为约定,下划线用作默认服务器的服务器名称。

来自http://nginx.org/en/docs/http/server_names.html

在包罗万象的服务器示例中,可以看到奇怪的名称“_”:

server 
   listen       80  default_server;
   server_name  _;
   return       444;

这个名字没有什么特别之处,它只是无数的无效域名之一,永远不会与任何真实姓名相交。其他>无效名称,如“--”和“!@#”也可以同样使用。

请注意,仅server_name _;不够的。上面的示例仅适用于 listen 指令中的 default_server

【讨论】:

该链接仅供参考。上面的两行实际上是答案:简单地将下划线作为 server_name 的值将产生所需的“全部捕获”行为。 这个答案不正确。该参考资料清楚地表明,除非您的配置中还有 listen 80 default_server,否则这将不起作用。 另见this article。 也许我误解了文档,但是“这个名称没有什么特别之处,它只是无数与任何真实姓名不相交的无效域名之一。其他无效名称,如“-- ”和“!@#”同样可以使用。”。所以_ 只是一个无效名称? @Psylone 您可以省略 server_name 指令。在当前版本的 nginx 中,它将使用空名称 - 这将完美运行。无效的server_name 是旧时代的建议:如果在server 块中未指定server_name,则最高0.8.48 的nginx 版本使用您机器的主机名,这可能是不希望的。将其设置为无效的东西可以解决这个问题。【参考方案3】:

这将起作用:

server_name ~^(.+)$

【讨论】:

server_name ~. 似乎效率更高 这对我有用。无论出于何种原因,我无法让 default_server 工作,它覆盖了我所有的其他虚拟主机。【参考方案4】:

对我来说,以某种方式定义 default_server 不起作用。我解决了它

server_name ~^.*$

使用所有的正则表达式。

【讨论】:

尝试了所有投票率较高的选项,这是唯一有效的选项。注意:我正在尝试使用其 IP 地址与 URL 访问服务器。 在 nginx 1.20.2 中,它与 ;最后server_name ~^.*$;【参考方案5】:

只有 1 个server 指令

来自Nginx listen Docs

default_server 参数(如果存在)将导致服务器 成为指定地址:端口对的默认服务器。如果没有 的指令有 default_server 参数,然后是第一个 具有地址:端口对的服务器将是此服务器的默认服务器 对。

如果你只有 1 个 server 指令,它将处理所有请求,你不需要设置任何东西。


多个server 指令

如果你想匹配指定server指令的所有请求,只需将default_server参数添加到listen,Nginx将默认使用这个server指令。

server 
    listen 80 default_server;


关于server_name _;

来自Nginx Docs

在包罗万象的服务器示例中,可以看到奇怪的名称“_”:

server 
    listen       80  default_server;
    server_name  _;
    return       444;

这个名字没有什么特别之处,它只是无数个中的一个 永远不会与任何真实姓名相交的无效域名。 其他无效名称,如“--”和“!@#”也可以同样使用。

不管server_name你设置什么,它只是一个无效的域名

【讨论】:

【参考方案6】:

现在你可以使用掩码了:

server 
    listen       80;
    server_name  *.example.org;
    ...


server 
    listen       80;
    server_name  mail.*;
    ...

在此处查看更多信息:http://nginx.org/en/docs/http/server_names.html

【讨论】:

【参考方案7】:

如果您还想捕获带有空 Host 标头的请求(这在 HTTP/1.0 中是允许的),您可以同时使用正则表达式和空 server_name

server 
    listen      80;
    server_name ~. "";

【讨论】:

【参考方案8】:

试试$http_host

server 
    server_name $http_host;

【讨论】:

以上是关于nginx server_name 通配符或包罗万象的主要内容,如果未能解决你的问题,请参考以下文章

请求怎么匹配到nginx配置的servername

nginx配置注意事项

Nginx--server块配置

nginx 为通配符域配置不同的证书

Nginx---静态资源处理

nginx配置web服务器