为了帮助解释我的问题,让我创建一个类似的,但是虚构 背景故事。
假设我有一个朋友 Sarah,她通过网络摄像头谋生。假设她的收入来源是抚养 Sarah 4 岁的女儿 Lisa。
我认识 Sarah 是因为她与我签约,让我为她写一个定制的成人网络摄像头网站。她还把我介绍给了 Lisa 的幼儿园,该幼儿园也与我签约,让我为他们的网站写代码。
为了省钱,我通过 Nginx 使用同一台服务器托管两个网站。
我兴奋地在学校网站上告知我取得的所有进展!但我当时不知道的是,我提供服务的节点进程
lisas-preschool.com
已经宕机了。
经过一次尴尬的电话交谈后,我发现有时 Nginx 会为访问的网站提供错误的内容。
这显然不可能发生,永远不可能发生!所以,我如何确保这一点
sarahs-site.com
并且lisas-preschool.com
永远不会被交叉服务?
作为参考,以下是站点的配置:
lisas-preschool.com:
这是一个 node.js 站点:
upstream lisas_preschool {
server 127.0.0.1:3000;
}
# HTTP Server
server {
listen 0.0.0.0:80;
server_name www.lisas-preschool.com lisas-preschool.com;
access_log /var/log/nginx/lisas-preschool.access;
location / {
proxy_pass http://lisas-preschool.com;
proxy_http_version 1.1;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
}
}
sarahs-site.com
这是一个 WordPress 网站:
server {
listen 80;
listen [::]:80;
server_name sarahs-site.com www.sarahs-site.com;
index index.php index.html index.htm;
root /var/www/sarahs-site.com/html;
location / {
try_files $uri $uri/ /index.php;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/site-b.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;
}
}
答案1
处理这种情况的最可靠方法是保证仅在明确请求该主机名时才提供服务。当请求一个站点时可以提供另一个站点的唯一情况是,当 Nginx 无法(出于某种原因)找到请求的站点而改为提供默认站点时。默认站点将是第一个server
定义的站点或server
指定为默认站点的站点。
通过设置在任何情况下都是安全的默认server
块(如下面的例子),您可以确定它将在最坏的情况下得到服务。
server {
listen 80 default_server;
server_name _;
return 444;
}
server {
listen 80;
server_name example1.com;
}
server {
listen 80;
server_name example2.com;
}
如果使用 SSL,请确保您有一个server
SSL 默认块(可以是单独的块,也可以与非 SSL 块相同)。您还可以通过为两个站点设置不同的专用 IP 地址来增加分离度。
答案2
您在“服务器”块中使用了不同的listen
指令格式。这意味着虚拟主机会为自己获取不同的监听套接字,并且对于某些协议/接口组合,您可能会获得意外的请求结果。
我建议您listen 80;
在两个虚拟主机上使用,这样 nginx 就会在 IPv4 和 IPv6 套接字上监听端口 80。或者,如果您只需要 IPv4 套接字,请使用listen 0.0.0.0:80;
。
另外,我将创建一个默认服务器,直接断开对任何其他虚拟主机的所有请求:
server {
listen 80 default_server;
return 444;
}