Reputation: 47
My nginx server has 3 different sites on it, each with its own server block. For security I'll just be using domain1.com, domain2.com and domain3.com instead of the real domains. Domain3 is still pending transfer to my ownership so its not functioning at all yet.
The problems is that whenever you go to domain1.com, it forwards me to domain2.com. As far as I can tell there isn't anything saying that domain1.com should forward to domain2.com. I cleared my DNS cache and all of my browser cache and cookies.
Here is the server_block configuration of domain1.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 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;
#}
}
The domain2.com configuration is as follows:
#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;
#}
}
According to nginx -t
there are no configuration problems. Any help would be much appreciated!
Upvotes: 1
Views: 5898
Reputation: 38238
One problem, which you might be aware of, is serving multiple websites with TLS. The TLS handshake is actually done before the HTTP request is sent, and the HTTP request is the part that contains the hostname. This means nginx must pick a TLS certificate to use for the handshake, and if it doesn't know which certificate to pick, it won't always use the right one. This is documented here. This is usually solved with using different IPs for each website, or using SNI (more on SNI in nginx here). I've always struggled with SNI on nginx, but perhaps you can get it to work. If SNI is working for you already, this just ignore this part of this answer.
The problem, it seems, is that you only listen on port 80 (HTTP) for the www.*
hostnames. If a client tries to connect to domain1.com:80
(HTTP) (note the lack of www.
), you don't have a server listening on port 80 (HTTP) for domain1.com
. nginx will use the first server in its configuration to handle unknown/unmatched hostnames.
Try the following in your terminal:
curl -v http://www.domain1.com
curl -v https://domain1.com
curl -v http://domain1.com
curl -v https://www.domain1.com
That will show you the HTTP request and response headers. You will see that the first two, http://www.domain1.com
(port 80) and https://domain1.com
(port 443), work as expected. However, the last two, http://domain1.com
(port 80) and https://www.domain1.com
(port 443), do not work as expected, as they don't match any server block (wrong port/hostname).
To go into the problem in more detail, the following commands should output the following:
$ curl -v http://www.domain1.com
[...]
< HTTP/1.1 301 Moved Permanently
[...]
< Location: https://domain1.com/
[...]
This is good. You have a server listening for www.domain1.com
on port 80 (HTTP). This matches your redirecting server configuration. As you can see, the server's HTTP response headers return HTTP 301 and points to the new location https://domain1.com/
. This is correct, and matches what you ask your redirecting server to do.
$ curl -v https://domain1.com
[...]
< HTTP/1.1 200 OK
[...]
This is good. You have a server listening for domain1.com
on port 443 (HTTPS). This matches your main server configuration for domain1.com
. As you can see, the server's HTTP response headers return HTTP 200, and the server returns the HTML page requested. This is correct, and matches what you ask your main server configuration to do for domain1.com
.
$ curl -v http://domain1.com
[...]
< HTTP/1.1 301 Moved Permanently
[...]
< Location: https://domain2.com/
[...]
This is bad. You do not have a server listening for domain1.com
on port 80 (HTTP). This doesn't match any of your server configurations. Since this request doesn't match any of your servers, nginx doesn't do what you want it to. nginx simply defaults to using the first server configuration it sees, which unfortunately isn't the one you want. It seems to use the redirecting server for domain2.com
, since it returns a 301 redirect to domain2.com
.
This can be fixed by making your redirecting server for domain1.com
also listen for port 80 (HTTP) connections to domain1.com
(not just www.domain1.com
, as it currently does). If you don't do this, nginx doesn't know which server to use for this request, and it ends up returning the wrong thing.
$ curl -v https://www.domain1.com
This is bad. You do not have a server listening for www.domain1.com
on port 443 (HTTPS) (you currently only have one on port 80 (HTTP)). This doesn't match any of your server configurations. Since this request doesn't match any of your servers, nginx doesn't do what you want it to. nginx simply defaults to using the first server configuration it sees, which unfortunately isn't the one you want.
This can be fixed by making your redirecting server for domain1.com
also listen for port 443 (HTTPS) connections to www.domain1.com
(not just port 80 (HTTP) www.domain1.com
connections, as it currently does). If you don't do this, nginx doesn't know which server to use for this request, and it ends up returning the wrong thing.
You need to change your domain1.com
configuration to this:
# 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 ...
}
And your domain2.com
configuration to this:
# 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 ...
}
Upvotes: 2
Reputation: 47
I actually found it...
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;
}
Essentially what needed to happen was that for either an incoming www or no-www request it needs to rewrite it and not do a forward. After this I just specify the listen 443 ssl;
as so and the standard domain name and it works!
Upvotes: 0