首页 > 解决方案 > 配置问题:来自 LetsCncrypt 使用 OpenResty 和 lua-resty-auto-ssl 的多域自动 SSL

问题描述

请原谅冗长的文章 - 我非常感谢以下方面的任何帮助。

我正在尝试使用 LetsEncrypt 使用 SSL 设置多租户子域 + 自定义域:

(有些会使用子域有些会使用自定义域)

https://customer1.myapp.com
https://customer2.myapp.com
https://customer1.com (customer sets up A/CNAME recoreds at his DNS provider)

我在使用用户名“ubuntu”的 Ubuntu 操作系统的 EC2 实例上。

我从以下教程中学到了:

https://sandeep.dev/how-we-generate-and-renew-ssl-certs-for-arbitrary-custom-domains-using-letsencrypt-cjtk0utui000c1cs1f7y9ua5n

https://www.digitalocean.com/community/tutorials/how-to-use-the-openresty-web-framework-for-nginx-on-ubuntu-16-04

https://sandro-keil.de/blog/openresty-nginx-with-auto-generated-ssl-certificate-from-lets-encrypt/

我已成功完成以下操作:

这是我的入门配置文件(/usr/local/openresty/nginx/conf/nginx.conf)

(我会进一步完善它以适应我的重定向和安全需求)

#user nginx;

error_log  /usr/local/openresty/nginx/logs/error.log warn;

events {
    worker_connections 1024;
}

http {

  lua_shared_dict auto_ssl 1m;
  lua_shared_dict auto_ssl_settings 64k;

  init_by_lua_block {

    auto_ssl = (require "resty.auto-ssl").new()
    auto_ssl:set("allow_domain", function(domain)
      return true
    end)
    auto_ssl:set("dir", "/etc/resty-auto-ssl")
    auto_ssl:init()

  }

  init_worker_by_lua_block {
    auto_ssl:init_worker()
  }

 # access_log /usr/local/openresty/nginx/logs/access.log main;

  server {

      listen 443 ssl;

      ssl_certificate_by_lua_block {
        auto_ssl:ssl_certificate()
      }

      ssl_certificate /etc/ssl/resty-auto-ssl-fallback.crt;
      ssl_certificate_key /etc/ssl/resty-auto-ssl-fallback.key;

      root /var/www/myapp.com/public;
      index index.php index.html index.htm;

      location / {

        try_files $uri $uri/ /index.php?$query_string; 

      }

#     location ~ \.php$ {
#       include snippets/fastcgi-php.conf;
#       fastcgi_pass unix:/run/php/php7.4-fpm.sock;
#       fastcgi_read_timeout 600;
#     }

      location ~ /\.ht {
        deny all;
      }

  }

  server {

    listen 80;
    server_name *.myapp.com myapp.com;

    location /.well-known/acme-challenge/ {
        content_by_lua_block {
          auto_ssl:challenge_server()
        }
    }

    location / {
      return 301 https://myapp.com$request_uri;
    }

  }

  server {

    listen 8999;

    location / {
        content_by_lua_block {
          auto_ssl:hook_server()
        }
    }

  }

}

我面临多个问题,例如:

  1. 不能在 nginx 配置中提及用户 - 没有它仍然可以工作

    • 试图在第一行配置文件中提及用户会给我错误。
    • 所以我把它评论了出来,并试图继续坚持
  2. 脱水失败但已创建证书

    • 在我的日志中不断收到以下错误: lets_encrypt.lua:40: issue_cert(): auto-ssl: dehydrated failed: env HOOK_SECRET=XXXX HOOK_SERVER_PORT=8999 /usr/local/openresty/luajit/bin/resty-auto-ssl/dehydrated --cron --accept-terms --no-lock --domain myapp.com --challenge http-01 --config /etc/resty-auto-ssl/letsencrypt/config --hook /usr/local/openresty/luajit/bin/resty-auto-ssl/letsencrypt_hooks status: 256 out: # INFO: Using main config file /etc/resty-auto-ssl/letsencrypt/config
    • 但它仍然继续并且确实创建了一个证书,之后它给出了随机数生成器错误。
    • 有时,如果我删除里面的所有内容/etc/resty-auto-ssl- 它不会给我这样的错误。
  3. 找不到 OpenSSL 随机数生成器

    • 我的日志中不断出现以下错误: Can't load ./.rnd into RNG random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:98:Filename=./.rnd curl: (22) The requested URL returned error: 500 Internal Server Error
  4. OpenResty 提供的 nginx 上的 PHP-FPM

    • 我已经正确安装了 php-fpm 并在单独使用 nginx 时对其进行了测试。
    • 但是,现在我使用的是 openresty 提供的 nginx,它似乎不起作用
    • 错误(使用 nginx -t 命令测试配置时显示): "/usr/local/openresty/nginx/conf/snippets/fastcgi-php.conf" failed (2: No such file or directory)
  5. 创建证书失败

    • 有时,此错误之后会出现上述第 2 点中的错误:

    auto-ssl: could not get certificate for myapp.com - using fallback - failed to get or issue certificate, context: ssl_certificate_by_lua*, client: 123.201.226.209, server: 0.0.0.0:443

    set_response_cert(): auto-ssl: failed to set ocsp stapling for xxxx.myapp.com - continuing anyway - failed to get ocsp response: OCSP responder query failed (http://ocsp.int-x3.letsencrypt.org): no resolver defined to resolve "ocsp.int-x3.letsencrypt.org", context: ssl_certificate_by_lua*, client: 123.201.226.209, server: 0.0.0.0:443

    connect() to unix:/run/php/php7.4-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 123.201.226.209, server: , request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.4-fpm.sock:", host: "xxxx.myapp.com"

  6. 当试图访问 customer1.com whoes A 记录指向 myapp.com 服务器 IP

    "Error creating new order :: Cannot issue for \"X.X.X.X\": The ACME server can not issue a certificate for an IP address"

    ssl_certificate.lua:281: auto-ssl: could not determine domain for request (SNI not supported?) - using fallback - , context: ssl_certificate_by_lua*, client: 45.148.10.72, server: 0.0.0.0:443

    • ... 其中 xxxx 是从浏览器打开的 customer1.com 记录的

我有以下困惑:

  1. 我应该为 myapp.com 获得一份正确的(付费)通配符正 ssl 证书吗?(并将其用作后备)

    • 这涵盖了我所有的子域,我不必通过letsencrypt处理子域的限制。
    • 这样,我只需要对 customer1.com 等自定义域使用让加密
  2. 我不确定我的用户和权限是否设置正确 - 任何指针都会有所帮助

  3. 我希望我的最终 nginx 配置能够满足以下需求

标签: phpsslnginxlets-encryptopenresty

解决方案


回答所有这些问题有点困难,所以我将尝试回答 5 和 6 的一部分。我已经在 prod 环境中设置了 open resty,请参阅链接

  1. 我遇到了这个 OCSP 装订问题。我发现它已通过将其添加到我的 NGINX 配置中来解决:
# A DNS resolver must be defined for OSCP stapling to function.
resolver 172.20.0.10 ipv6=off;

关于问题 6,我建议 customer1.com 应该是 myapp.com 的 CNAME。

我还建议使用 openresty docker 镜像作为基础,或者至少将 docker 镜像的逆向工程版本用于 EC2 实例。这是我的码头文件:

FROM openresty/openresty:latest-xenial

RUN /usr/local/openresty/luajit/bin/luarocks install lua-resty-auto-ssl
RUN /usr/local/openresty/luajit/bin/luarocks install lua-resty-http
RUN apt-get update
RUN apt-get install -y dnsutils

RUN openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj '/CN=sni-support-required-for-valid-ssl' -keyout /etc/ssl/resty-auto-ssl-fallback.key -out /etc/ssl/resty-auto-ssl-fallback.crt

ADD nginx.conf /usr/local/openresty/nginx/conf/nginx.conf

希望这会有所帮助。


推荐阅读