Nginx: How to match ONLY the main domain with server_name

こ雲淡風輕ζ 提交于 2021-02-10 16:55:46

问题


My goal is to redirect example.com into www.example.com without redirecting any subdomain to www.

This is what I have:

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

With this configuration every subdomain (ex: foo.example.com) gets redirected into www.example.com, not just the main one without subdomain (example.com), as I would like.

I tried cleaning cache (and also doing it from other browsers) with same results.

Edit:

The proof that the server_name is matching subdomains is that if I change the redirection url to: https://www.$host$request_uri then:

foo.example.com gets redirected to www.foo.example.com.


回答1:


Try using several server_name directives:

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.)
}

As specified on the nginx documentation:

When searching for a virtual server by name, if name matches more than one of the specified variants, e.g. both wildcard name and regular expression match, the first matching variant will be chosen, in the following order of precedence:

  1. exact name
  2. longest wildcard name starting with an asterisk, e.g. “*.example.org”
  3. longest wildcard name ending with an asterisk, e.g. “mail.*”
  4. first matching regular expression (in order of appearance in a configuration file)



回答2:


Actually, example.com does only match the main domain.

But if the hostname doesn't match any server_name (and in your example, your subdomains do not as there is only one server rule for the main domain), the default server will be used, which, if you didn't specify it with the default_server tag in the listen parameter, it uses by default the first server, which, in your case, is the redirection rule for the main domain.

TD;TR

Your subdomains aren't matching any rule, so they are being called back to the only rule you setted, the redirection.

You need to have a specific rule for subdomains:

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

This will prevent the subdomains from using the default server and so, being redirected to www, but they are not configured for doing nothing, so a default nginx page will show. I would recomend to directly specify the behaviour you want for each of the subdomains, or replacing the comment with the actual expected behaviour for all of them.



来源:https://stackoverflow.com/questions/64741768/nginx-how-to-match-only-the-main-domain-with-server-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!