0

I want nginx/0.7.6 (on debian, i.e. with config files in /etc/nginx/sites-enabled/) to serve a site on exactly one subdomain (indicated by the Host header) and nothing on all others. But it staunchly ignores my server_name settings?!

In sites-enabled/sub.domain:

server {
  listen 80;
  server_name sub.domain;
  location / { … }
}

Adding a sites-enabled/00-default with

server {
  listen 80;
  return 444;
}

Does nothing (I guess it just matches requests with no Host?)

server {
  listen 80;
  server_name *.domain;
  return 444;
}

Does prevent Host: domain requests from giving results for Host: sub.domain, but still treats Host: arbitrary as Host: sub-domain.

The, to my eyes, obvious solution isn't accepted:

server {
  listen 80;
  server_name *;
  return 444;
}

Neither is

server {
  listen 80 default_server;
  return 444;
}

Since order seems to be important: renaming 00-default to zz-default, which, if sorted, places it last, doesn't change anything. But debian's main config just includes *, so I guess they could be included in some arbitrary file-system defined order?


This returns no content when Host: is not sub.domain as expected, but still returns the content when Host is completely missing. I thought the first block should handle exactly that case!? Is it because it's the first block?

server {
  listen 80;
  return 444;
}
server {
  listen 80;
  server_name ~^.*$;
  return 444;
}

3 Answers 3

1

The way to define a default server in nginx is by setting the default_server flag (in 0.7, it's just default) on the server's listen statement. server_name _; doesn't mean anything special. nginx also does not sort globbed filenames, so the files aren't guaranteed to be included in any specific order.

server {
  listen 80 default;
  return 444;
}
2

Using this as the first block matches all request not matched by any following server_name: sub.domain block. No Idea why _ doesn't work, using a regex seems hackish.

server {
  listen 80;
  server_name ~^.*$ "";
  return 444;
}

i.e. ~^.*$ matches all Host: headers, "" matches no Host: header being sent.

2
  • 1
    Because you're running an antique 0.7 version of nginx. That hasn't been supported in years. If you insist on using debian, please do yourself a favor and use the dotdeb repositories. Sep 10, 2012 at 4:00
  • yeah, I knew debian was slow, but I just didn't expect a "stable" release from 2012 to come with a version from 2008… (I have to rely on debian & backports though, since my virtual server has an ancient kernel current libc-releases don't even support anymore…)
    – pascal
    Sep 10, 2012 at 16:47
-1

The default virtual host should contain:

server_name _;

This is a catch-all that will match any host name not specified in any other server_name directive.

You are also correct when you note that when server_name is missing, the block matches only requests without a Host: header.

Note that this probably won't work on nginx 0.7.x, which is antique and horribly out of date, and for which many things have changed. If you insist on using debian, please do yourself a favor and use the dotdeb repositories to keep current with software such as nginx, MySQL, and PHP, for which it's critical to update much more rapidly than Debian does.

5
  • With server{listen 80; return 444;} server{listen 80; server_name _; return 444} it still answers for no Host:, Host: arbitrary and Host: wrong.domain, just not for Host: domain.
    – pascal
    Sep 10, 2012 at 3:21
  • Do you have a server block defined for domain? You never mentioned creating one. Sep 10, 2012 at 3:28
  • no, just sub.domain, I thought I could create a true catch-all block and then just supply server blocks for the (sub)domains I'm actually trying to serve. (Success, see my answer)
    – pascal
    Sep 10, 2012 at 3:31
  • I'm just realizing that my Debian Stable version of nginx is 0.7, I just assumed it was recent enough to skip the historic blocks in the manual m(
    – pascal
    Sep 10, 2012 at 3:39
  • server_name _ doesn't define a default server. From the documentation you linked: "There is nothing special about this name, it is just one of a myriad of invalid domain names which never intersect with any real name. Other invalid names like “--” and “!@#” may equally be used."
    – kolbyjack
    Sep 10, 2012 at 12:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .