46

I have an Nginx with a number of enabled server blocks. Each server answers to 1 canonical domain and may forward 1 or more to that canonical URL. I have at least one server (haven't checked all of them yet) where, if I type in a non-existent domain that points to this box, Nginx displays a site of its choosing (always the same site, but not one that I'm after).

I've poked around the config file for the site I always land on, but don't see anything obvious that would identify it as any kind of default site and yet there it is, always showing up when I fat finger a URL.

Any thoughts on what I should be looking for to track this down?

0

2 Answers 2

40

Add default_server to your listen directive in the server that you want to act as the default.

6
  • 2
    well, that's the thing. i really don't want a default, but I seem to have one. I'd rather have nginx just throw whatever error it throws if what i type doesn't exactly match something. Jul 19, 2013 at 17:36
  • @RobWilkerson You mean the error it throws when you request a resource that doesn't exist? That's a lot different than a hostname that doesn't match a server, but you can configure it to get the same effect: create a default server block with nothing but the listen with default_server, and try_files =404;. Jul 19, 2013 at 18:01
  • 2
    Let me ask the question a different way. What makes Nginx load site X when a non-matching domain is called? Why site X and not site Y? Why doesn't it just throw an error? Jul 19, 2013 at 19:41
  • 1
    @RobWilkerson It always selects a default server for every IP:port listening pair, and serves it for any request that doesn't match a server block. I didn't write it so I can't tell you the reason for this behavior, but I'd say probably because it's a lot more user friendly and easy to troubleshoot "I got the wrong content" versus "404? Huh?". The behavior you want is very easily achieved, so why is this a problem? Jul 19, 2013 at 19:45
  • I don't know that it's a problem, per se. Just learning my something new for the day. :-) Jul 19, 2013 at 20:10
52

Why is nginx doing this?

The reason for this is simple. Very old or broken clients do not send the Host HTTP header field in their requests and if you are using name based server blocks (name based virtual hosts in Apache terms) nginx is not able to determine which of the servers you configured is meant by the client. The same problem is true for any other web server that supports this name based system. This problem would not arise if you would be using an IP based system for each domain (which also means that you have several network interfaces).

More on this topic? How nginx processes a request


Which is the first?

nginx will select the server that comes first if no default flag was set on any listen directive:

server {
  server_name server1.com;
}

server {
  server_name server2.com;
}

server1.com will be default.

If you automatically include the symbolic links from sites-enabled (default config) the file that comes first in the directory will be your first server.


What can I do to prevent this?

Good question and you should prevent it. There is no reason to support these old clients and absolutely no reason to support broken clients. The problem is easily solved by creating a default catch all server config. The following example is from one of my projects and targeted towards the current dev version of nginx (1.5.2 - but should work with older versions as well):

# /etc/nginx/sites-enabled/_.conf

# Default server for clients who do not send correct Host header.
# The underline in the file name makes sure that this file comes first in the dir.
server {
  server_name _;
  listen *:80 default_server deferred;
  return 444;
}

Configuration is trimmed, more nginx configuration stuff.

5
  • 5
    Be careful of cached 301 redirects (in browser) when setting this up. I was freaking out in Chrome, not understanding why my return 444; wasn't working until I opened up Dev Tools inside an Incognito window and realized everything was working just fine. Aug 21, 2017 at 22:10
  • Thanks for this explanation @Fleshgrinder , it was a creative solution if you don't want to have a default server, among your real servers.
    – xarlymg89
    Mar 26, 2018 at 8:09
  • so if default server isn't available Nginx will return on a "first match" pattern behavior ?
    – DiaJos
    Sep 18, 2018 at 16:52
  • @Webwoman If I understand it right it is not "first match" but "first". The actual first server directive in first config file (alphabetically I guess) in /etc/nginx/sites-enabled/.
    – kub1x
    Oct 23, 2019 at 9:40
  • 1
    how to achieve this with https? When I listen 443 and return 444 I only get a security error page even though I added my wildcard cert
    – br4nnigan
    Jan 5, 2022 at 22:02

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