Fixing Nginx Domain Routing: When Multiple Sites Redirect to Wrong Server Block


23 views

When both domains load website1.com despite having separate server blocks, this typically indicates an issue with Nginx's server selection algorithm. Nginx uses the following priority rules:

1. Exact server_name match
2. Longest wildcard starting with *
3. Longest wildcard ending with *
4. First matching regular expression
5. First matching server block (catch-all)

First verify your configuration with:

sudo nginx -t

Then check which server blocks are active:

sudo nginx -T | grep "server_name"

The most likely culprit is a missing default_server directive. Here's how to properly configure it:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 444; # Close connection
}

For website1.com:

server {
    listen 80;
    listen [::]:80;
    server_name website1.com www.website1.com;
    root /var/www/website1.com/public;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

For website2.com:

server {
    listen 80;
    listen [::]:80;
    server_name website2.com www.website2.com;
    root /var/www/website2.com/public;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

To verify which server block Nginx selects:

curl -v http://website1.com
curl -v http://website2.com

Check the access logs to confirm which server handled the request:

tail -f /var/log/nginx/access.log

When configuring multiple websites on Nginx with separate server blocks, you might encounter situations where all domains unexpectedly serve content from the same site. This typically occurs when:

website1.com → loads website1 (correct)
website2.com → also loads website1 (incorrect)

Based on the configuration files provided, several potential issues emerge:

  • The default_server flag might be implicitly set on website1
  • DNS records may not be properly propagating
  • Browser cache could be interfering with requests
  • Nginx might not be loading the second configuration file

First, verify Nginx's configuration parsing:

sudo nginx -t
sudo nginx -T | grep server_name

Check active server blocks:

curl -I http://website1.com
curl -I http://website2.com

Modify the configurations to explicitly handle default cases:

# website1.com config
server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;
    server_name website1.com;
    ...
}

# website2.com config
server {
    listen 80;
    listen [::]:80 ipv6only=on;
    server_name website2.com;
    ...
}

If issues persist, consider these additional measures:

  1. Clear Nginx's server name hash table:
    sudo service nginx restart
  2. Verify symbolic links in sites-enabled:
    ls -l /etc/nginx/sites-enabled/
  3. Test with explicit IP binding:
    server {
        listen 192.0.2.1:80;
        server_name website2.com;
        ...
    }

For production environments, implement these safeguards:

# Global nginx.conf addition
server_names_hash_max_size 512;
server_names_hash_bucket_size 128;

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

This ensures any undefined domains won't accidentally route to your primary site.

After making changes, perform comprehensive testing:

sudo nginx -t && sudo service nginx reload
curl -H "Host: website1.com" http://localhost
curl -H "Host: website2.com" http://localhost