1

The Mozilla SSL Configuration Generator omits the server_name directive whenever generating config for NGINX (e.g., see the one for NGINX 1.22.1 & OpenSSL 3.0.2).

After reading through a couple of related docs and threads (see at the bottom), I've come to the conclusion that this is probably because the configuration is provided assuming that only one site is going to be served.

I intend to do just that: serve one site through HTTPS. So if I copied that configuration, the server_name would resolve to an empty string in each of the server blocks. Did I misinterpret something?

Isn't omitting the server_name insecure somehow or, the very least, a bad practice?


toraritte
  • 200
  • 10
  • 2
    Why not experiment a little in non-prod environment?) – alexus Aug 08 '23 at 18:41
  • 3
    The `server_name` is optional and offers no security. Nginx will choose a `server` block to process a request even if the `server_name` does not match. This is called the default server. And if there is only one server block - it is by definition, also the default server. – Richard Smith Aug 09 '23 at 07:08

1 Answers1

2

A simplified flowchart for processing NGINX configurations when listening on ports only:

flowchart for processing NGINX configurations

This could easily be generalized for listen <IP_ADDRESS>:<PORT> declarations though; see quote from the NGINX docs at the bottom of this answer.

Examples

1. NGINX config generated by the Mozilla SSL Configuration Generator

The gist of the config cited in the question:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # ... instructions ...
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    # ... instructions ...
}

As Richard Smith says in his comment, both server blocks are the default ones for requests coming in ports 80 and 443, respectively, accepting any domain; if there were server_name declarations in the blocks, they wouldn't matter.

For example, an HTTPS request on port 443 will skip the first block entirely as the default_server declaration only applies for requests coming on port 80.

2. Redirect all HTTP requests for a domain to HTTPS

From this Server Fault thread:

#############
# CATCH-ALL #
#############
server {
   listen 80 default_server; 
   server_name _;

   return 404;
}

##########################
# HTTP-to-HTTPS redirect #
##########################
server {
    listen 80;
    server_name ourdomain.com;

    return 301 https://ourdomain.com$request_uri;
}

#########
# HTTPS #
#########
server {
    listen 443 default_server ssl http2;

    # ... instructions ...
}

Example requests:

  • http://ourdomain.com/about

    NGINX will look at the server_name directive after seeing that there are two blocks for handling port 80, and will match the second one.

  • http://random-domain.org/ where, for some reason, the domain name still resolves to the IP address where NGINX server with the above config is running

    None of the server blocks listening on port 80 will match, so the default one will simply return 404.

    NOTE For the catch-all server block to work,

    1. it has to declare server_name _;, and

    2. it has to be the default server for that port (either implicitly, by being the first one appearing for that port, or explicitly, by using listen ... default_server ...;).

    See Server names article in the NGINX docs.

In either cases above, server_name can be omitted in the server block that handles HTTPS, as it is the only one block listening on 443.


Note to self: listen's default_server parameter can be used multiple times in the same configuration file. From the docs:

The default_server parameter, if present, will cause the server to become the default server for the specified address:port pair. - link to paragraph

The sample config above could be written as below (based on an example in this Server Fault thread):

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # ... instructions ...
}

server {
    listen 443 default_server ssl http2;
    listen [::]:443 default_server ssl http2;

    # ... instructions ...
}
toraritte
  • 200
  • 10
  • Relevant thread: [Is server_name really needed for default_server? (Nginx) - Server Fault](https://serverfault.com/questions/1062957/is-server-name-really-needed-for-default-server-nginx/1141328#1141328) – toraritte Aug 11 '23 at 15:11