Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Nginx vhost从默认块继承ssl\u certificate*指令?_Ssl_Nginx_Virtualhost - Fatal编程技术网

Nginx vhost从默认块继承ssl\u certificate*指令?

Nginx vhost从默认块继承ssl\u certificate*指令?,ssl,nginx,virtualhost,Ssl,Nginx,Virtualhost,以下是我最终要做的,以供充分披露:我试图使用一个SNI证书在多个vhost上设置TLS:一个vhost用于apex,另一个用于单独的主机。也就是说,我想服务https://example.com和https://host.example.com使用相同的证书。两台主机解析为相同的IPv4地址 我很难理解Nginx如何处理ssl\u证书*指令。这些指令仅在默认服务器块中定义,但仍在另一个块中“拾取” 我从一个默认的服务器块开始到404 server { return 404; } 果然, $

以下是我最终要做的,以供充分披露:我试图使用一个SNI证书在多个vhost上设置TLS:一个vhost用于apex,另一个用于单独的主机。也就是说,我想服务
https://example.com
https://host.example.com
使用相同的证书。两台主机解析为相同的IPv4地址

我很难理解Nginx如何处理
ssl\u证书*
指令。这些指令仅在默认服务器块中定义,但仍在另一个块中“拾取”

我从一个默认的服务器块开始到404

server {
  return 404;
}
果然,

$ curl --head http://example.com
HTTP/1.1 404 Not Found
[...]
然后,我创建了第一个example.com块,将http重定向到apex上的https:

server {
  listen 80;
  server_name example.com;
  return 301 https://example.com;
}
server {
  listen 443 ssl;
  ssl_certificate [...];
  ssl_certificate_key [...];
  server_name example.com;
}
这也行得通:

$ curl --head http://example.com
HTTP/1.1 301 Moved Permanently
[...]
Location: https://example.com

$ curl --head http://host.example.com
HTTP/1.1 404 Not Found
[...]
然后我在apex上配置了TLS:

server {
  listen 80;
  server_name example.com;
  return 301 https://example.com;
}
server {
  listen 443 ssl;
  ssl_certificate [...];
  ssl_certificate_key [...];
  server_name example.com;
}
到目前为止,一切顺利:http重定向到https,https工作正常

$ curl --head http://example.com
HTTP/1.1 301 Moved Permanently
[...]
Location: https://example.com

$ openssl s_client -connect example.com:443
CONNECTED(00000003)
[...]
---
GET / HTTP/1.1
Host: example.com

HTTP/1.1 200 OK
然后我遇到了一个短暂的障碍。关于
host.example.com
,我还没有说过一句话,但当我尝试通过TLS连接时:

$ curl --head http://host.example.com
HTP/1.1 404 Not Found
[...]

$ openssl s_client -connect host.example.com:443
CONNECTED(00000003)
[...]
---
GET / HTTP/1.1
Host: host.example.com

HTTP/1.1 200 OK
[... content from example.com...]
默认块响应
http://host.example.com
,应该如此。但是
https://host.example.com
https://example.com

所以经过一番努力,我意识到我需要两个默认块:每个端口一个

server {
  listen 443 ssl;
  ssl_certificate [...];
  ssl_certificate_key [...];
  return 404;
}
确认这是我所需要的:

$ openssl s_client -connect host.example.com:443
CONNECTED(00000003)
[...]
---
GET / HTTP/1.1
Host: host.example.com

HTTP/1.1 404 Not Found
[...]
但后来我意识到了一些事情。这就是我困惑的开始。我不应该也不明白我为什么能够通过TLS连接到example.com:443(或host.example.com:443)

当我为端口443创建第二个默认服务器时,我删除了服务器块中的
ssl\u证书
ssl\u证书密钥
指令。它们仅在默认服务器块中定义

server {
  listen 443 ssl;
  ssl_certificate [...];
  ssl_certificate_key [...];
  return 404;
}

server {
  listen 443 ssl;
  server_name example.com;
  # No ssl_certificate* directives!
}
然而,不知何故,我在默认服务器块中定义的证书最终在我尝试连接到以下服务器时被使用:

我还确认访问url
https://example.com
在浏览器中提供实际页面

因此,的配置似乎是从默认块继承TLS的设置,但随后应用匹配的服务器块的其余设置。这就是发生的事吗?我试着搜索我能想到的大多数关键字矩阵:“nginx”、“tls”、“ssl”、“vhost”、“默认服务器块”、“继承”、“继承”;但我什么也找不到,文档似乎也没有。它可能写在什么地方,但我找的地方不对

增加:

完整配置,这是一个基本的Debian安装,与软件包默认值相比基本保持不变

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
# above line loads:
# ngx_http_auth_pam_module, ngx_http_geoip_module, ngx_http_image_filter_module, ngx_http_xslt_filter_module, ngx_mail_module, ngx_stream_module

events {
  worker_connections 768;
}

http {
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  keepalive_timeout 65;
  server_tokens off;
  include /etc/nginx/mime.types; # nothing unusual in here
  default_type application/octet-stream;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # drop SSLv3
  ssl_prefer_server_ciphers on;
  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log
  gzip on;
  gzip_disable "msie6";
  include /etc/nginx/conf.d/*.conf; # empty directory, includes nothing
  include /etc/nginx/sites-enabled/*; # includes single file which defines server blocks as above
}
基本上就是这样

再次编辑:

这是完整的服务器配置文件,全部放在一个地方

server {
  listen 80;
  return 404;
}

server {
  listen 443 ssl;
  ssl_certificate [...];
  ssl_certificate_key [...];
  return 404;
}

server {
  listen 80;
  server_name example.com;
  return 301 https://example.com;
}

server {
  listen 443 ssl;
  server_name example.com;
  root /srv/www/example.com;
  index index.html;
}

通过此配置,访问工作正常,并使用默认服务器块中配置的证书。为什么?

根据以下条件,这实际上是预期的行为:

SSL连接在浏览器发送HTTP之前建立 请求和nginx不知道请求服务器的名称。 因此,它可能只提供默认服务器的证书

解决办法是使用:

应该记住,由于HTTPS协议的限制 虚拟服务器应该侦听不同的IP地址,否则 将为第二个站点颁发第一个服务器的证书


你能发布今天的整个配置文件吗?很抱歉有这么多回复。我将nginx.conf的内容添加到了帖子的底部。它与Debian安装的默认配置基本相同。