Nginx redirecting to wrong vhost

2019-03-15 01:25发布

问题:

I have around 1300vhosts in one nginx conf file. All with the following layout (they are listed after each other in the vhost file).

Now my problem is that sometimes my browser redirects site2 to site1. For some reason, while the domain names don't event match.

It looks like nginx is always redirecting to the first site in the vhosts file.

Somebody that know what this problem can be?

server {
    listen   80;

    server_name site1.com;
    rewrite ^(.*) http://www.site1.com$1 permanent;
}

server {
    listen   80;

    root /srv/www/site/public_html/src/public/;
    error_log /srv/www/site/logs/error.log;
    index index.php;

   server_name www.site1.com;

    location / {
        if (!-e $request_filename) {
            rewrite ^.*$ /index.php last;
        }
    }

    location ~ .(php|phtml)$ {
        try_files $uri $uri/ /index.php;
        fastcgi_param SCRIPT_FILENAME /srv/www/site/public_html/src/public$fastcgi_script_name;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
    }
}

server {
    listen   80;

    server_name site2.com;
    rewrite ^(.*) http://www.site2.com$1 permanent;
}

server {
    listen   80;

    root /srv/www/site/public_html/src/public/;
    error_log /srv/www/site/logs/error.log;
    index index.php;

   server_name www.site2.com;

    location / {
        if (!-e $request_filename) {
            rewrite ^.*$ /index.php last;
        }
    }

    location ~ .(php|phtml)$ {
        try_files $uri $uri/ /index.php;
        fastcgi_param SCRIPT_FILENAME /srv/www/site/public_html/src/public$fastcgi_script_name;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
    }
}

EDIT Maybe another thing to mention is that, I reload all this vhosts every 2 minutes with nginx -s reload.

On the first tests it looks like the redirection only happens when reloading... Going to do some more tests, but this could be helpful..

回答1:

Reference (how nginx handles request): http://nginx.org/en/docs/http/request_processing.html

In this configuration nginx tests only the request’s header field “Host” to determine which server the request should be routed to. If its value does not match any server name, or the request does not contain this header field at all, then nginx will route the request to the default server for this port.

the default server is the first one — which is nginx’s standard default behaviour

Could you check the host header of those bad requests?

Also you can create an explicit default server to catch all of these bad requests, and just log the request info (i.e, $http_host) into a different error log file for investigation.

server {
    listen       80  default_server;
    server_name  _;
    error_log /path/to/the/default_server_error.log;

    return       444;
}

[UPDATE] As you are doing nginx -s reload and you have so many domains in that nginx conf file, the following is possible:

A reload works like this

starting new worker processes with a new configuration, graceful shutdown of old worker processes

So old workers and new workers could co-exist for a while. For example, when you add a new server block (with new domain name) to your config file, during the reloading time, the new workers will have the new domain and the old one will not. When the request happens to be sent by the old worker process, it will be treated as unknown host and served by the default server.

You said that it's done every 2 minutes. Could you run

ps aux |grep nginx

and check how long each worker is running? If it's much more than 2 minutes, the reloading may not work as you expected.



标签: nginx