Nginx:如何仅将主域与 server_name 匹配

Posted

技术标签:

【中文标题】Nginx:如何仅将主域与 server_name 匹配【英文标题】:Nginx: How to match ONLY the main domain with server_name 【发布时间】:2021-02-20 18:57:05 【问题描述】:

我的目标是将example.com 重定向到www.example.com,而不将any 子域重定向到www

这就是我所拥有的:

server 
  listen 443;
  server_name example.com;
  return 301 https://www.$server_name$request_uri;

使用这种配置,每个子域(例如:foo.example.com)都会被重定向到www.example.com,而不仅仅是没有子域的主域(example.com),正如我所愿。

我尝试清理缓存(也可以从其他浏览器执行),结果相同。

编辑:

server_name 与子域匹配的证据是,如果我将重定向 url 更改为:https://www.$host$request_uri,则:

foo.example.com 被重定向到 www.foo.example.com

【问题讨论】:

此服务器块也是处理任何与任何 server_name 不匹配的请求的默认服务器块。见how nginx processes a request。您需要定义一个包罗万象的服务器。见this answer。 【参考方案1】:

其实example.com确实只匹配主域。

但如果hostname 不匹配任何server_name(在您的示例中,您的子域不匹配,因为主域只有一个服务器规则),默认服务器将被使用,if you didn't specify it with the default_server tag in the listen parameter, it uses by default the first server,在您的情况下,它是主域的重定向规则。

TD;TR

您的子域不匹配任何规则,因此它们被回调到您设置的唯一规则,即重定向。

您需要为子域制定特定规则:

server 
  listen 443;
  server_name *.example.com;
  # do something, or leave it blank for default nginx page

这将阻止子域使用默认服务器,因此被重定向到www,但它们没有配置为什么都不做,因此将显示默认的 nginx 页面。我建议直接为每个子域指定您想要的行为,或者将注释替换为所有子域的实际预期行为。

【讨论】:

【参考方案2】:

尝试使用多个server_name 指令:

server 
  listen 443;
  server_name example.com;
  return 301 https://www.$server_name$request_uri;


server 
  listen 443;
  server_name ~^(?<name>\w+)\.example\.com$;
  
  ... # insert your directives (location etc.)

nginx documentation 上指定:

按名称搜索虚拟服务器时,如果名称匹配更多 比指定的变体之一,例如通配符名称和 正则表达式匹配,将选择第一个匹配的变体, 按以下优先顺序:

    确切名称 以星号开头的最长通配符名称,例如“*.example.org” 以星号结尾的最长通配符名称,例如“邮件。*” 第一个匹配的正则表达式(按配置文件中出现的顺序)

【讨论】:

将 foo.example.com 重定向到 foo.example.com 对我来说似乎有点奇怪 正如我所料,这会导致重定向循环。 如果删除 foo.example.org 的 return 会发生什么? 好的。我需要子域的特定规则。 您的更新解决方案可能有效,但我认为最好使用 * 作为通配符而不是正则表达式。这很有帮助,所以为您的方法 +1。

以上是关于Nginx:如何仅将主域与 server_name 匹配的主要内容,如果未能解决你的问题,请参考以下文章

Windows Server2008主域与备域搭建

将插件域与主域完全分离的最佳实践?

PHP:将主域重定向到https:// www,子域重定向到https://(不带www)

.htaccess:将主域重定向到https:// www,子域重定向到https://(不带www)

CMake 是不是将包含的标头中的所有内容编译到可执行文件中,还是仅将主类中使用的部分编译为可执行文件?

nginx如何配置多IP的HTTP正向代理?