Server blocks: listen and server_name

NGINX · Essentials · 10 min

Picking the wrong server block is the classic reason a site shows another site's content.

A server block is a virtual server. NGINX chooses one for each request in two steps:

  • First by address and port: only servers whose listen matches the connection are candidates.
  • Then by the Host header compared with server_name.

server_name accepts several forms, checked in this priority order:

  • exact names: example.com www.example.com
  • the longest wildcard starting with *: *.example.com
  • the longest wildcard ending with *: mail.*
  • the first matching regular expression, in file order: ~^(?<sub>.+)\.example\.com$

If no name matches, the request goes to the default server for that address and port: the one marked listen 80 default_server, or otherwise simply the first server block defined for it. That's why requests for unknown hosts, or for a bare IP address, sometimes land on a random site.

A good practice is an explicit catch-all that rejects unknown hosts. return 444 is an NGINX-specific code that closes the connection without a response.

The special name .example.com matches both example.com and all its subdomains.

Example

server {
    listen 80 default_server;        # catch-all for unknown Host headers
    server_name _;
    return 444;                      # close the connection, send nothing
}

server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example;
}

server {
    listen 80;
    server_name *.shop.example.com;   # any subdomain of shop.example.com
    root /var/www/shop;
}
# curl -H 'Host: www.example.com' http://127.0.0.1/  -> /var/www/example
# curl -H 'Host: other.org' http://127.0.0.1/        -> connection closed

Remember

  • Servers are matched by listen address/port, then by server_name
  • Exact names beat wildcards, which beat regexes
  • No match goes to default_server, or the first server for that port

Watch out for

  • Relying on file order for the default server; mark it explicitly with default_server.

Check yourself

  1. No server_name matches the Host header and no server is marked default_server. Which block handles the request?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: nginx.org/en/docs/http/request_processing.html