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


2 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