第一次发帖,所以请多包涵。
我对 Nginx 还比较陌生,但已经设法弄清楚我需要什么......直到现在。
Nginx v1.0.15 代理 PHP-FPM v.5.3.10,后者正在监听http://127.0.0.1:9000
。[敲木头] 就托管我们的 CMS 和许多网站而言,一切都运行顺利。
现在,我们已经开发了我们的 CMS 并配置了 Nginx,以便每个支持的网站都有一个预览 URL(例如http://[网站ID].ourcms.com/),您猜对了,在 DNS 还不能解析到我们的服务器的情况下,可以预览网站,等等。
具体来说,我们使用 Nginx 的 Map 模块(http://wiki.nginx.org/HttpMapModule) 和 CMSserver{ }
块的 server_name 中的正则表达式,以 1) 从网站的预览 URL 中查找网站的主域名,然后 2) 将请求转发到“匹配的”主域。
对应的Nginx配置:
map $host $h {
123.ourcms.com www.example1.com;
456.ourcms.com www.example2.com;
789.ourcms.com www.example3.com;
}
和
server {
listen [OurCMSIPAddress]:80;
listen [OurCMSIPAddress]:443 ssl;
root /var/www/ourcms.com;
server_name ~^(.*)\.ourcms\.com$;
ssl_certificate /etc/nginx/conf.d/ourcms.com.chained.crt;
ssl_certificate_key /etc/nginx/conf.d/ourcms.com.key;
location / {
proxy_pass http://127.0.0.1/;
proxy_set_header Host $h;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
(注意:我确实意识到出于安全原因,server_name 中的正则表达式应该“更严格”,并且仅匹配网站 ID 的格式(即我们例子中的 UUID)。)
此配置适用于我们 99% 的站点……除了那些已安装 SSL 证书的专用 IP 地址的站点。这些站点会返回“502 Bad Gateway”,我不确定原因。
这就是我思考当前配置适用于任何与正则表达式匹配的请求(例如http://123.ourcms.com/):
- Nginx 从映射中查找网站的主域名,然后
- 作为该指令的结果
proxy_pass http://127.0.0.1
,将请求传递回 Nginx 本身, - 由于代理请求具有与网站主域名相对应的主机名,因此通过
proxy_set_header Host $h
指令,Nginx 会将该请求视为该主机名的直接请求。
请如果我的理解有误,请纠正我。
我应该代理这些网站的专用 IP 地址吗?我试过了,但似乎不起作用?代理模块中是否有我遗漏的设置?
谢谢您的帮助。
MB
答案1
除非那些拥有已安装 SSL 证书的专用 IP 地址的用户。
在我看来,您只监听一个 IP 地址。您还需要为 SSL 域的其他 IP 设置“监听”指令。除非您有通配符 SSL 证书,否则我认为您需要为每个主机设置一个 server{} 定义。
以下是我使用的相关模式,如果您尝试避免完全手动维护 SSL Nginx 域的配置,它可能会有所帮助:
我的 Nginx 配置的一部分作为模板存储在源代码管理下。Nginx 的“init”脚本已被修改,因此每次重新加载或重新启动 Nginx 时,都会调用一个 Perl 脚本,根据环境(alpha、beta、生产等)填充模板变量。写出一个新的纯文本文件,Nginx 将“渲染”模板作为包含文件包含。
这为自动化和 DRY 提供了新的可能性。也许这对您的情况有帮助。
答案2
对于任何可能偶然遇到此问题的人,解决方案是以下 Nginx 配置:
# Map preview URLs to shared or dedicated IP addresses
map $host $i {
default [IP for Shared VHosts];
123.ourcms.com [Dedicated IP Address 1]; # www.example1.com;
456.ourcms.com [Dedicated IP Address 2]; # www.example2.com;
789.ourcms.com [Dedicated IP Address 3]; # www.example3.com;
}
# Map preview URLS to appropriate hostname
map $host $h {
123.ourcms.com www.example1.com;
456.ourcms.com www.example2.com;
789.ourcms.com www.example3.com;
}
...
# Configuration for "preview" server
server {
listen [OurCMSIPAddress]:80;
listen [OurCMSIPAddress]:443 ssl;
error_log /var/log/nginx/error-ourcms.com.log debug;
root /var/www/ourcms.com;
server_name ~^(.*)\.ourcms\.com$;
ssl_certificate /etc/nginx/conf.d/ourcms.com.chained.crt;
ssl_certificate_key /etc/nginx/conf.d/ourcms.com.key;
location / {
proxy_pass http://$i;
proxy_set_header Host $h;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
这个诀窍是查找主机名,我认为@MarkStosberg 暗示了这一点,但我不明白和预览网站的 IP 地址。此外,每个虚拟主机的服务器块必须包含listen [SharedIPForVhosts]:80
,而不仅仅是listen *:80
。