14

Using nginx, I want to redirect all subdomains of example.com to www.example.com.

I have seen redirects here to redirect non-www to www or vise versa, but I also want www2.site.com blabla.site.com to be redirected. I have a wildcard dns for the domain.

For apache this can be done easily with following:

RewriteCond %{HTTP_HOST} !www.example.com [NC]
RewriteRule (.*) http://www.example.com%{REQUEST_URI} [R=301,L]

The below seem to work, but it is not recommended according to the ifisevil page.

if ($http_host !~ "www.site.com"){
    rewrite ^(.*)$ http://www.example.com$request_uri redirect;
}
Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
user2143308
  • 141
  • 1
  • 1
  • 4

2 Answers2

23

The best way to do this in nginx is with a combination of two server blocks:

server {
  server_name *.example.org;
  return 301 $scheme://example.org$request_uri;
}

server {
  server_name www.example.org;

  #add in further directives to serve your content
}

I have tested this on my laptop, since you reported it not working. I get the following result locally (after adding www2.test.localhost and www.test.localhost to my /etc/hosts, along with the nginx config bit, and reloading nginx):

$ curl --head www2.test.localhost
HTTP/1.1 301 Moved Permanently
Server: nginx/1.2.6
Date: Thu, 07 Mar 2013 12:29:32 GMT
Content-Type: text/html
Content-Length: 184
Connection: keep-alive
Location: http://www.test.localhost/

So yes, this definitely works.

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
cobaco
  • 10,224
  • 6
  • 36
  • 33
  • 3
    Please, do not use `rewrite ^ permanent` instead of simple `return`. Executing regular expression (even so simple one `^`) is just wasting of CPU in this case. – VBart Mar 07 '13 at 10:28
  • good point, changed that – cobaco Mar 07 '13 at 10:40
  • tried this, it does't work, doesn't send a 301 header not does it redirect to www.site.com actually it redirects to a different site on the server but leaver subdomain.site.com in the adressbar – user2143308 Mar 07 '13 at 12:08
  • anybody actually tried this, or are the codes just theory? – user2143308 Mar 07 '13 at 12:11
  • in the first server block it should say return 301 $scheme://www.example.org$request_uri; i guess, but seeing all the answers everywhere, i'm beginning to suspect it is in the virtualmin itself the server is running Centos6 with Virtualmins nginx's plugin i have posted the same quesion on virtualmin's forum – user2143308 Mar 07 '13 at 12:54
  • It's not theory. It's how it works everyday on my site (try http://any_word_here.vbart.info ), and it's actually how it supposed to work. – VBart Mar 07 '13 at 14:01
  • this is a little different than my question though, yours strips every subdomain, i want all subdomains togo to www.site.com – user2143308 Mar 07 '13 at 14:16
  • 4
    well no: you have a *wildcard* serverblock for `*.example.com` and serverblock with an *exact match* for `www.example.com`. Consequently www.example.com will not be rewritten, as it is handled in the 2nd block not the first. The matching order for server_name is: 1 - exact name, 2 - longest match starting with *, 3 - longest match ending with a *, 4 - first regex match (as explained at http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) – cobaco Mar 07 '13 at 14:54
  • maybe `server_name www.example.org;` block should be in the first place if it needs to redirects? – Gediminas Šukys Mar 31 '16 at 05:43
13
server {
    server_name .example.com;
    return 301 http://www.example.com$request_uri;
}

server {
    server_name www.example.com;
    [...]
}

References:

Daniël W. Crompton
  • 3,448
  • 25
  • 26
VBart
  • 14,714
  • 4
  • 45
  • 49
  • tried this, it does't work, doesn't send a 301 header nor does it redirect to www.site.com actually it redirects to a different site on the server but leaves subdomain.site.com in the adressbar – user2143308 Mar 07 '13 at 12:10
  • problem is maybe that `site.com` does not match `*.site.com` (not dot). – regilero Mar 07 '13 at 12:44
  • 2
    i tried .site.com wich catches both *.site.com and site.com according to the manual – user2143308 Mar 07 '13 at 13:31