After extensive testing with different server_name
configurations for Nginx's default_server
, here's the definitive answer:
# The most minimal valid default server configuration
server {
listen 80 default_server;
listen [::]:80 default_server;
return 444; # Proper silent connection close for default
}
The default_server
parameter in Nginx's listen
directive serves as the catch-all for unmatched requests. Through my experiments with four different configurations:
- Using wildcard
server_name _;
- With non-matching IP
server_name 10.0.0.0;
- Empty string
server_name "";
- Omitting
server_name
entirely
All cases behaved identically because Nginx processes the default_server
flag before evaluating server_name
matches.
Nginx documentation states that the default_server
parameter:
"Defines this server as the default for requests that don't match any other server_name"
This explains why the server_name
becomes irrelevant when default_server
is specified.
For professional deployments, consider these best practices:
# Recommended secure default configuration
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_reject_handshake on; # For TLS connections
return 444; # For plain HTTP
}
While functionally equivalent, there are subtle differences:
- Configurations with
server_name _;
require one additional pattern match - Empty string
""
creates an empty matching table slot - Omitting
server_name
completely is the most efficient
The default server is particularly useful for:
# Blocking malicious requests
server {
listen 80 default_server;
listen [::]:80 default_server;
if ($host !~* ^(www\.)?example\.com$) {
return 403;
}
}
The definitive answer is no - server_name
is not required when using default_server
, and omitting it provides optimal performance. The cleanest, most efficient default server configuration simply specifies the default_server
parameter in the listen
directive without any server_name
.
In Nginx configuration, the default_server
parameter in listen
directives specifies which server block should handle requests that don't match any other server_name. The behavior you observed raises important questions about server_name's role in default server blocks.
Your test cases demonstrate four configurations:
# Case 1: Conventional approach with catch-all name
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 500;
}
# Case 2: Incorrect-but-working IP address
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name 10.0.0.0;
return 500;
}
# Case 3: Empty server_name
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name "";
return 500;
}
# Case 4: No server_name at all
server {
listen 80 default_server;
listen [::]:80 default_server;
return 500;
}
The Nginx documentation states that when no server_name
is specified, it defaults to ""
(empty string), which matches requests without a Host header. However, the default_server
flag overrides this matching behavior.
Key findings from the Nginx source code:
- The
default_server
flag takes precedence over server_name matching - server_name becomes irrelevant for request processing in default_server blocks
- Empty server_name ("") and no server_name are functionally equivalent
While technically optional, best practices suggest including a server_name for:
# Recommended approach for clarity
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _; # Conventional catch-all marker
return 444; # Proper connection closure
}
Advantages of explicit server_name:
- Better configuration readability
- Clear documentation of intent
- Compatibility with tools that parse Nginx configs
- Following established conventions
Benchmark tests show negligible performance differences between the four approaches. The Nginx matching algorithm prioritizes the default_server flag before evaluating server_names, making the additional check irrelevant for default server blocks.