How to Force Nginx to Stop Responding to Original Domain After Changing server_name Directive


2 views

When modifying Nginx's server_name directive from example.com to different_name, the server continues responding to requests for the original domain. This occurs despite proper service restarts (Nginx/Gunicorn) and correct DNS resolution.

Nginx treats the first server block with a matching listen directive as the default when no server_name matches. Your original domain still works because:

# Without explicit default_server declaration
server {
    listen 80;  # Becomes implicit default
    server_name different_name;
}

Add an explicit catch-all server block that returns 444 (connection closed without response):

server {
    listen 80 default_server;
    server_name _;
    return 444;
}

server {
    listen 80;
    server_name different_name;
    # Your actual configuration
}

This configuration ensures only different_name receives responses:

upstream app_server {
    server 127.0.0.1:8002;
}

# Block all invalid host headers
server {
    listen 80 default_server;
    server_name _;
    return 444;
}

# Main application server
server {
    listen 80;
    server_name different_name;
    
    client_max_body_size 10M;
    keepalive_timeout 15;
    
    location / {
        proxy_pass http://app_server;
        include proxy_params;
    }
}

After implementing the solution:

  1. sudo nginx -t (test configuration)
  2. sudo systemctl reload nginx
  3. Test with:
    curl -H "Host: example.com" http://your_server_ip (should fail)
    curl -H "Host: different_name" http://your_server_ip (should work)

For production environments, consider:

# Prevent DNS rebinding attacks
server {
    listen 80 default_server;
    server_name "";
    return 444;
}

When working with Nginx configurations, developers often encounter situations where modifying the server_name directive doesn't immediately stop Nginx from responding to the old domain. This typically occurs when:

  1. The configuration isn't properly reloaded or tested
  2. There's a default server block catching unspecified domains
  3. DNS caching or browser caching interferes

Here's the definitive way to ensure Nginx stops responding to your old domain:

# Explicitly reject unwanted domain
server {
    listen 80;
    server_name example.com;
    return 444; # Special Nginx non-standard code to close connection
}

# Your actual server block
server {
    listen 80;
    server_name different_name;
    client_max_body_size 10M;
    keepalive_timeout 15;
    
    location / {
        proxy_pass http://domain;
    }
}

upstream domain {
    server 127.0.0.1:8002;
}

After making configuration changes:

# Test configuration syntax
sudo nginx -t

# Properly reload configuration
sudo systemctl reload nginx

# Verify using curl (from another machine if possible)
curl -I -H "Host: example.com" http://your_server_ip/
curl -I -H "Host: different_name" http://your_server_ip/

If the issue persists, consider these aspects:

  • Check for duplicate server blocks in included configuration files
  • Verify there's no wildcard server_name like server_name _;
  • Inspect browser cache and DNS TTL values
  • Review Nginx access logs for the actual Host header received

For production environments, this is the recommended approach:

# Default catch-all server block
server {
    listen 80 default_server;
    server_name _;
    return 444;
}

# Your specific domain configuration
server {
    listen 80;
    server_name different_name;
    # Rest of your configuration
}