Nginx不应该转发到另一个服务器块

时间:2015-02-17 03:56:25

标签: nginx configuration server

我的nginx服务器上有3个不同的站点,每个站点都有自己的服务器块。为了安全起见,我将使用domain1.com,domain2.com和domain3.com而不是真正的域名。 Domain3仍在等待转让给我的所有权,因此它根本无法正常运行。

问题是每当你去domain1.com时,它都会转发给domain2.com。据我所知,没有任何迹象表明domain1.com应该转发到domain2.com。我清除了DNS缓存以及所有浏览器缓存和cookie。

这是domain1.com的server_block配置

#This is for redirecting everyone from www.domain.com to domain.com
server {
    listen   80; ## listen for ipv4; this line is default and implied
    #listen   [::]:80 default_server ipv6only=on; ## listen for ipv6

    server_name www.domain1.com;

    return 301 https://domain1.com$request_uri;
}

server {
    #listen 80 default_server;
    #listen [::]:80 default_server ipv6only=on;

    listen 443;

    server_name domain1.com;

    #keepalive_timeout 70;

    root /var/www/domain1.com/html;
    index index.php index.html index.htm;

    ssl on;
        ssl_certificate /etc/nginx/ssl/domain1.com/ssl.crt;
        ssl_certificate_key /etc/nginx/ssl/domain1.com/ssl.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
        # Uncomment to enable naxsi on this location
        # include /etc/nginx/naxsi.rules
    }

    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /var/www/domain1.com/html;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }

    # Only for nginx-naxsi used with nginx-naxsi-ui : process denied requests
    #location /RequestDenied {
    #   proxy_pass http://127.0.0.1:8080;    
    #}

    #error_page 404 /404.html;

    # redirect server error pages to the static page /50x.html
    #
    #error_page 500 502 503 504 /50x.html;
    #location = /50x.html {
    #   root /usr/share/nginx/html;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
    #   # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
    #
    #   # With php5-cgi alone:
    #   fastcgi_pass 127.0.0.1:9000;
    #   # With php5-fpm:
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #   deny all;
    #}
}

domain2.com配置如下:

#This is for redirecting everyone from www.domain.com to domain.com
server {
    listen   80; ## listen for ipv4; this line is default and implied
    #listen   [::]:80  ipv6only=on; ## listen for ipv6

    server_name www.domain2.com;

    return 301 https://domain2.com$request_uri;
}
server {
    #listen 80;
    #listen [::]:80  ipv6only=on;

    listen 443;
    server_name domain2.com;

    ssl on;
    ssl_certificate /etc/nginx/ssl/domain2.com/ssl.crt;
    ssl_certificate_key /etc/nginx/ssl/domain2.com/ssl.key;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    ssl_ciphers HIGH:!aNULL:!MD5;

    ssl_prefer_server_ciphers on;

    root /var/www/domain2.com/html;
    index index.php index.html index.htm;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
        # Uncomment to enable naxsi on this location
        # include /etc/nginx/naxsi.rules
    }

    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /var/www/domain2.com/html;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }

    # Only for nginx-naxsi used with nginx-naxsi-ui : process denied requests
    #location /RequestDenied {
    #   proxy_pass http://127.0.0.1:8080;    
    #}

    #error_page 404 /404.html;

    # redirect server error pages to the static page /50x.html
    #
    #error_page 500 502 503 504 /50x.html;
    #location = /50x.html {
    #   root /usr/share/nginx/html;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
    #   # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
    #
    #   # With php5-cgi alone:
    #   fastcgi_pass 127.0.0.1:9000;
    #   # With php5-fpm:
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #   deny all;
    #}
}

根据nginx -t,没有配置问题。任何帮助将不胜感激!

access.log

2 个答案:

答案 0 :(得分:2)

警告:

您可能知道的一个问题是使用TLS为多个网站提供服务。 TLS握手实际上是在发送HTTP请求之前完成的,而HTTP请求是包含主机名的部分。这意味着nginx必须选择一个TLS证书用于握手,如果它不知道要选择哪个证书,它就不会总是使用正确的证书。 This is documented here。这通常通过using different IPs for each website或使用SNImore on SNI in nginx here)来解决。我总是在nginx上与SNI斗争,但也许你可以让它发挥作用。如果SNI已经为你服务,那么这就忽略了这个答案的这一部分。


问题:

问题似乎是你只在端口80(HTTP)上监听www.*主机名。如果客户端尝试连接到domain1.com:80(HTTP)(请注意缺少www.),则表示您没有服务器侦听domain1.com的端口80(HTTP)。 nginx will use the first server in its configuration to handle unknown/unmatched hostnames

在终端中尝试以下操作:

curl -v http://www.domain1.com
curl -v https://domain1.com
curl -v http://domain1.com
curl -v https://www.domain1.com

这将显示HTTP请求和响应标头。您将看到前两个http://www.domain1.com(端口80)和https://domain1.com(端口443)按预期工作。但是,最后两个http://domain1.com(端口80)和https://www.domain1.com(端口443)不能按预期工作,因为它们不匹配任何服务器块(错误的端口/主机名)。


要更详细地讨论该问题,以下命令应输出以下内容:


$ curl -v http://www.domain1.com
[...]
< HTTP/1.1 301 Moved Permanently
[...]
< Location: https://domain1.com/
[...]

这很好。您有一台服务器在端口80(HTTP)上侦听www.domain1.com。这与您的重定向服务器配置相匹配。如您所见,服务器的HTTP响应标头返回HTTP 301并指向新位置https://domain1.com/。这是正确的,并且与您要求重定向服务器执行的操作相匹配。


$ curl -v https://domain1.com
[...]
< HTTP/1.1 200 OK
[...]

这很好。您有一台服务器在端口443(HTTPS)上侦听domain1.com。这与domain1.com的主服务器配置相匹配。如您所见,服务器的HTTP响应头返回HTTP 200,服务器返回请求的HTML页面。这是正确的,并且与您要求主服务器配置对domain1.com进行匹配。


$ curl -v http://domain1.com
[...]
< HTTP/1.1 301 Moved Permanently
[...]
< Location: https://domain2.com/
[...]

这很糟糕。您没有服务器在端口80(HTTP)上侦听domain1.com。这与您的任何服务器配置都不匹配。由于此请求与您的任何服务器都不匹配,因此nginx无法执行您想要的操作。 nginx只是默认使用它看到的第一个服务器配置,遗憾的是它不是你想要的那个。它似乎使用重定向服务器domain2.com,因为它返回301重定向到domain2.com

这可以通过使domain1.com的重定向服务器也监听到domain1.com(不仅仅是www.domain1.com的端口80(HTTP)连接来修复,就像它当前那样。如果你不这样做,nginx不知道哪个服务器用于这个请求,它最终会返回错误的东西。


$ curl -v https://www.domain1.com

这很糟糕。您没有服务器在端口443(HTTPS)上侦听www.domain1.com(您当前在端口80(HTTP)上只有一个服务器)。这与您的任何服务器配置都不匹配。由于此请求与您的任何服务器都不匹配,因此nginx无法执行您想要的操作。 nginx只是默认使用它看到的第一个服务器配置,遗憾的是它不是你想要的那个。

这可以通过使domain1.com的重定向服务器也侦听到www.domain1.com的端口443(HTTPS)连接(而不仅仅是端口80(HTTP)www.domain1.com连接来解决。目前确实)。如果你不这样做,nginx不知道哪个服务器用于这个请求,它最终会返回错误的东西。

解决方案:

您需要将domain1.com配置更改为:

# For forwarding HTTP (port 80) connections to your website:
server {
    listen 80;
    server_name domain1.com www.domain1.com;
    return 301 https://domain1.com$request_uri;
}

# For forwarding HTTPS (port 443) connections to www.domain1.com:
server {
    listen 443 ssl;
    ... add the other SSL configuration options ...
    server_name www.domain1.com;
    return 301 https://domain1.com$request_uri;
}

# Your main server configuration:
server {
    ... keep it as you currently have it for your domain1.com server ...
}

您的domain2.com配置:

# For forwarding HTTP (port 80) connections to your website:
server {
    listen 80;
    server_name domain2.com www.domain2.com;
    return 301 https://domain2.com$request_uri;
}

# For forwarding HTTPS (port 443) connections to www.domain2.com:
server {
    listen 443 ssl;
    ... add the other SSL configuration options ...
    server_name www.domain2.com;
    return 301 https://domain2.com$request_uri;
}

# Your main server configuration:
server {
    ... keep it as you currently have it for your domain2.com server ...
}

答案 1 :(得分:0)

我实际上找到了它......

server {
    server_name domain2.com  www.domain2.com;
    rewrite ^(.*) https://domain2.com$1 permanent;
}

server {
    server_name domain1.com www.domain1.com;
    rewrite ^(.*) https://domain1.com$1 permanent;
}

基本上需要发生的是,对于传入的www或no-www请求,它需要重写它而不是前进。在此之后,我只需指定listen 443 ssl;,因此标准域名就可以了!