如何动态设置 ssl_certificate 的域名

我使用 openresty 中的 lua,并设置环境变量来动态设置域名。我有以下代码:

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 768;
}

env MYDOMAIN;

http {
    server {
        listen 80;
        listen 443 ssl;
        set_by_lua $MYDOMAIN 'return os.getenv("MYDOMAIN")';
        server_name $MYDOMAIN www.$MYDOMAIN;
        location / {
          proxy_pass http://127.0.0.1:5000;
          index  index.html index.htm;
        }
        ssl_certificate /etc/letsencrypt/live/$MYDOMAIN/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/$MYDOMAIN/privkey.pem;
    }
}

我得到了一个错误:

nginx: [emerg] BIO_new_file("/etc/letsencrypt/live/$MYDOMAIN/fullchain.pem") failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/etc/letsencrypt/live/$MYDOMAIN/fullchain.pem','r') error:2006D080:BIO routines:BIO_new_file:no such file)

设置 server_name 是没有问题的,但在 ssl_certificate 和 ssl_certificate_key 的情况下,它会直接采用 $MYDOMAIN 的值。

点赞
用户2060502
用户2060502

并非所有的 nginx 指令都支持嵌入变量。ssl_certificatessl_certificate_key 不支持。

但是你可以使用 ssl_certificate_by_lua_blockngx.ssl

主要流程如下:

  1. 在 nginx 配置中指定任何有效的虚拟证书。
  2. 按照 ngx.ssl 概述 的说明进行一些证书格式转换。使用 os.getenv("MYDOMAIN") 来构建要打开和读取证书文件内容的文件路径。
  3. 缓存转换后的密钥,以避免每个请求都要对同一域名进行文件读取和转换。

你可以随时使用像 lua-resty-lrucache 和/或 ngx_lua 这样的库和 API,来对 DER 格式的结果进行缓存,例如。

2018-06-25 20:28:41
用户2830850
用户2830850

正如您已经知道的那样,在nginx配置中不能解析环境变量,并且并非所有指令都支持变量。

我很久以前就写过一篇相关的文章

https://tarunlalwani.com/post/simple-parameterized-config-files-docker/

这个想法是在运行nginx之前更新配置文件。因此,您将拥有一个启动脚本

#!/bin/bash

envsubst < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
exec nginx "-g" "daemon off;"

这将使事情变得更加容易。更棘手的方法是使用 ssl_certificate_by_lua_block 动态加载证书。

https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md

2018-06-25 21:50:22
用户1592008
用户1592008

Nginx 版本 1.15.9 支持在 "ssl_certificate" 和 "ssl_certificate_key" 指令中使用变量。

2019-02-27 16:02:27
用户2547850
用户2547850

从文档中得知:从 OpenSSL 1.0.2 或更高版本开始,可以在文件名中使用变量。

例如:

ssl_certificate     $ssl_server_name.crt;
ssl_certificate_key $ssl_server_name.key;
2021-04-15 18:15:20