【问题标题】:dynamic ssl certificate with nginx使用 nginx 的动态 ssl 证书
【发布时间】:2020-08-16 22:13:32
【问题描述】:

我有一个类似 Shopify 的应用程序。所以,我的客户在创建商店时会获得子域(即customer1.myShopify.com)。

用 nginx 处理这种动态子域的情况:

server {
    listen 443 ssl;
    server_name admin.myapp.com;

    ssl_certificate /etc/letsencrypt/live/myapp/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/myapp/privkey.pem;

    location / {
        proxy_pass http://admin-front-end:80/;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;
    }
}


server {
    listen 443 ssl;
    server_name *.myapp.com;

    ssl_certificate /etc/letsencrypt/live/myapp/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/myapp/privkey.pem;

    location / {
        proxy_pass http://app-front-end:80/;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;
    }
}

这很好,所以如果您访问 admin.myapp.com,您将看到管理应用程序,如果您访问任何 xxx.myapp.com,您将看到商店前端应用程序。

问题

我想让我的客户连接他们自己的域。所以我告诉他们联系CNAMEA Record

A Record => @ => 12.12.12.3(my root nginx ip)

CNAME => WWW => thier.myapp.com

并非对customer.com 的每个请求都会由我的 nginx 解决。

所以我将此配置添加到我的 nginx 中,以捕获所有其他 server_name 请求:

server {
        listen  80;
        server_name  server_name ~^.*$;
        location / {
            proxy_pass http://app-front-end:80/;
            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
        }
}

而且效果很好。

但是对于这种情况,我该如何处理SSL?因为它可以是任何域名。我不知道客户域名是什么。

我怎样才能让他们能够自动添加 SSL 证书而无需手动创建?

【问题讨论】:

  • 嘿,你知道了吗?我发现了第三个这样的问题,但没有得到解答。

标签: docker ssl nginx devops


【解决方案1】:

这个服务器块应该可以工作,因为ssl_certificatessl_certificate_key 指令支持变量名。

server {
    listen  443;
    server_name  server_name ~^.*$;

    map "$host" $domain_name { ~(.*)\.(.*)\.(.*)$ $2.$3; }

    ssl_certificate /path/to/cert/files/$domain_name.crt;
    ssl_certificate_key /path/to/cert/keys/$domain_name.key;

    location / {
        proxy_pass http://app-front-end:80/;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;
    }
}

P.S.使用变量名会影响性能,因为现在 nginx 会在每次 ssl 握手时加载文件。

参考:https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate

【讨论】:

    【解决方案2】:

    在我看来,与其牺牲 nginx 性能,不如使用一个 cron 作业,比如letsencrypt bot,它将根据用户请求的域获取证书,您可以在 nginx conf 中添加证书,然后重新启动服务器。

    奖金:

    我使用了 traefik,它是基于 kubernetes 的解决方案,它们无需重启即可即时加载配置。

    【讨论】:

      【解决方案3】:

      VM 中,您可以使用 certbot 来管理 SSL/TLS 证书。

      现在,如果您使用HTTP-01 方法来验证您的域,您将无法获得通配符域名。

      我建议在cert-bot中使用DNS-01方法进行域验证,您可以获得通配符证书并使用它。

      使用以下命令将证书添加到 Nginx 配置中:

      ssl_certificate /path/to/cert/files/tls.crt;
      ssl_certificate_key /path/to/cert/keys/tls.key;
      

      如果您使用的是certbot,它还会自动注入 SSL 配置并将上述行添加到配置文件中。

      对于不同的域,您也可以使用HTTP-01 方法运行作业或certbot,您将获得证书。

      如果您在 Kubernetes 上,则可以使用 cert-manager,它将管理 SSL/TLS 证书。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-24
        • 1970-01-01
        • 2014-12-18
        • 2020-10-06
        • 2021-07-30
        • 2019-10-04
        • 1970-01-01
        • 2016-01-04
        相关资源
        最近更新 更多