nginx子域名不正常地行为通配符?

我有一个nginx子域的问题。 首先,我的configuration:

server { listen 443 ssl; server_name secure.example.com; ssl_certificate example.crt; ssl_certificate_key example.key; keepalive_timeout 70; location / { fastcgi_pass 127.0.0.1:8000; ... } } server { listen 80; server_name example.com www.example.com; location / { fastcgi_pass 127.0.0.1:8000; ... } } 

这个想法是我有一个安全的域, secure.example.com和一个正常的域example.com 。 实际上,我可以去https://example.comhttp://secure.example.com 。 我用中介服务器解决了第二个问题:

 server { listen 80; server_name secure.example.com; rewrite ^(.*) https://secure.example.com$1 permanent; } 

但这不是一个最佳的解决scheme,我不得不创build另一个redirect到tld的https到子域。 如果我需要像这样的多个服务器,我觉得我一定在做错事。 为什么https://example.com在443服务器没有监听的时候工作? 难道它不能连接? 我很困惑。

为什么https://example.com在443服务器没有监听的时候工作? 难道它不能连接?

在80 / tcp(HTTP)或443 / tcp(HTTPS)连接build立之后,将评估server_name (或者更准确地说HTTP / 1.1主机头)。 这意味着,如果secure.example.comexample.com具有相同的A资源logging(它们指向相同的IP地址),则无法确定客户端在连接build立之前想要查看哪个虚拟主机,以及HTTP / 1.1主机头已经发送。

更确切地说,TCP / IP与IP地址(IP部分)和端口(TCP部分)一起工作。 所以如果你绑定一个进程(例如nginx)到一个特定的IP地址和端口,它总是会在这个套接字上回答,而TCP / IP不知道什么关于HTTP / 1.1和它的主机头。

如果你想简化你的nginxconfiguration,你可以写下面的内容:

 server { listen 443 ssl; listen 80; server_name secure.example.com; ssl_certificate example.crt; ssl_certificate_key example.key; keepalive_timeout 70; if ($scheme = http) { rewrite ^(.+)$ https://example.com$1 redirect; } location / { fastcgi_pass 127.0.0.1:8000; # ... } } server { listen 80; server_name example.com www.example.com; location / { fastcgi_pass 127.0.0.1:8000; # ... } } 

看看Nginx的server_name文档 。 它说,如果你的虚拟主机列表中没有任何匹配的话,nginx将会使用第一个带匹配listen指令的服务器块。

如果您想要强制用户使用https的 secure.example.com主机,则可以采取相同的解决方法。