【问题标题】:Nginx - Only enable SSL if SSL Certificates ExistNginx - 仅当 SSL 证书存在时才启用 SSL
【发布时间】:2018-05-14 11:53:45
【问题描述】:

我有一个问题,我正在构建一个 nginx 反向代理,用于指向不同 url 路径的多个微服务。

该系统完全基于 docker,因此开发和生产使用相同的环境。这在安装 SSL 时给我带来了一个问题,因为 SSL 证书只能在生产中使用,所以当我使用 SSL 配置 NGINX 时,开发环境不再工作,因为 ssl 证书不存在。

这是我的 conf 文件的相关部分 -

server {
 listen 80;
 listen 443 default_server ssl;

 server_name          atvcap.server.com;
 ssl_certificate      /etc/nginx/certs/atvcap_cabundle.crt;
 ssl_certificate_key  /etc/nginx/certs/atvcap.key;
 ...
}

但是在开发模式下运行我的应用程序时会引发以下问题 -

nginx: [emerg] BIO_new_file("/etc/nginx/certs/atvcap_cabundle.crt") 失败 (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/etc/nginx/ certs/atvcap_cabundle.crt','r') error:2006D080:BIO routines:BIO_new_file:no such file)

是否可以只在“/etc/nginx/certs/atvcap_cabundle.crt”可用的情况下开启SSL?

我尝试过类似以下的方法 -

if (-f /etc/nginx/certs/atvcap_cabundle.crt) {
  ssl_certificate      /etc/nginx/certs/atvcap_cabundle.crt;
  ssl_certificate_key  /etc/nginx/certs/atvcap.key;
}

但这引发了以下错误 -

nginx:[emerg]“ssl_certificate”指令在此处不允许 /etc/nginx/conf.d/default.conf:7

有人对如何实现这样的目标有任何想法吗?

谢谢

【问题讨论】:

  • 作为一个临时解决方法,我现在刚刚创建了两个 nginx.conf 文件——一个用于开发,一个用于生产。当我们处于开发模式时,开发者会覆盖生产模式。理想情况下,我不想让 2 个文件做几乎相同的事情。
  • 我正在寻找相同的解决方案。

标签: ssl nginx https


【解决方案1】:

您可以创建一个附加文件 ssl.conf 并将 ssl configs 放在这里:

ssl_certificate      /etc/nginx/certs/atvcap_cabundle.crt;
ssl_certificate_key  /etc/nginx/certs/atvcap.key;

然后从主配置中包含:

server_name          atvcap.server.com;

include /somepath/ssl.conf*;

确保包含 * 符号 - 当文件在开发模式下不存在时,这不会中断。

【讨论】:

  • 不管这种技术有助于克服这个问题,但是如果有合适的.crt文件,有没有办法启用ssl文件?
【解决方案2】:

@super_p 的答案是正确的。但是要回答@AbdolHosein 评论,如果不清楚,我会在此处添加我的答案。

您需要在包含的文件中包含您的 ssl_certificate 指令。

# sample nginx config
http {
    server {
        listen 80 deferred;
        server_name _;

        include /ssl/ssl.conf*;

        client_body_timeout 5s;
        client_header_timeout 5s;

        root /code;
    }
}

然后在您的/ssl/ssl.conf 中,您可以做任何您想做的事情,例如启用 HTTPS:

# this is the /ssl/ssl.conf file
listen 443 ssl http2;
listen [::]:443 ssl http2;

ssl_certificate /ssl/cert.cer;
ssl_certificate_key /ssl/key.key;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

诀窍是我们不查看证书是否存在,而是检查/ssl/ssl.conf 是否存在。这要感谢@super_p 所述的include /ssl/ssl.conf*; 目录中的*

【讨论】:

  • 看起来这已经不可能了 :-( 在 nginx/1.18.0 我得到:nginx: [emerg] "listen" directive is not allowed herenginx.org/en/docs/ngx_core_module.html#include 说:“包含的文件应该包含语法正确的指令和块。”
  • 我不这么认为。可能您只是将listen 放在错误的部分。根据文档,include 可以在 any 上下文中使用。
  • 我打开了一个问题:trac.nginx.org/nginx/ticket/2244
猜你喜欢
  • 1970-01-01
  • 2021-09-24
  • 1970-01-01
  • 1970-01-01
  • 2012-05-02
  • 2016-10-25
  • 1970-01-01
  • 2016-01-04
  • 2021-07-30
相关资源
最近更新 更多