php - 配置问题:来自 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://sandro-keil.de/blog/openresty-nginx-with-auto-generated-ssl-certificate-from-lets-encrypt/
我已成功完成以下操作:
- 在服务器上安装 build-essential
- 安装 OpenResty(自带 Nginx 和 OpenSSL)
- 安装 LuaRocks
- 安装 lua-resty-auto-ssl
为resty auto ssl创建目录
sudo mkdir /etc/resty-auto-ssl sudo chown -R ubuntu /etc/resty-auto-ssl sudo chown -R www-data /etc/resty-auto-ssl chmod -R 777 /etc/resty-auto-ssl/
创建后备自签名证书,有效期为 3600 天
这是我的入门配置文件(/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()
}
}
}
}
我面临多个问题,例如:
不能在 nginx 配置中提及用户 - 没有它仍然可以工作
- 试图在第一行配置文件中提及用户会给我错误。
- 所以我把它评论了出来,并试图继续坚持
脱水失败但已创建证书
- 在我的日志中不断收到以下错误:
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
- 它不会给我这样的错误。
- 在我的日志中不断收到以下错误:
找不到 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
- 我的日志中不断出现以下错误:
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)
创建证书失败
- 有时,此错误之后会出现上述第 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"
当试图访问 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 记录的
我有以下困惑:
我应该为 myapp.com 获得一份正确的(付费)通配符正 ssl 证书吗?(并将其用作后备)
- 这涵盖了我所有的子域,我不必通过letsencrypt处理子域的限制。
- 这样,我只需要对 customer1.com 等自定义域使用让加密
我不确定我的用户和权限是否设置正确 - 任何指针都会有所帮助
我希望我的最终 nginx 配置能够满足以下需求
- 将http://myapp.com和http://www.myapp.com重定向到 -> https://myapp.com
- 将https://www.myapp.com重定向到 -> https://myapp.com
- 将http://customer1.com和http://www.customer1.com重定向到 -> https://customer1.com
- 然后在我的 acutal ssl 服务器块上 - 编写自动 ssl 生成的所有逻辑
解决方案
回答所有这些问题有点困难,所以我将尝试回答 5 和 6 的一部分。我已经在 prod 环境中设置了 open resty,请参阅链接。
- 我遇到了这个 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
希望这会有所帮助。
推荐阅读
- winforms - 使用 selenium 抓取和保存 SVG 文件 - C# Selenium chromedriver WinForm
- html - React - 如何使滚动条透明,
- node.js - 如何在 Reactjs 中从另一个组件更新组件后加载组件的新数据
- javascript - 我的程序按预期解决了数独难题,但返回未定义
- laravel - 使用 Laravel Echo Server 和 Nginx 和 HTTPS 无法让 socket.io 在生产环境中工作
- javascript - Discord.js 等待消息错误,如何解决?
- ruby-on-rails - 由于缺少 Mime JSON,rake 任务无法启动
- android - Flutter - 当键盘出现在android上时文本字段不显示
- eclipse - Eclipse 重构(重命名)抛出 NullpoinerException 导致的 ExecutionException
- javascript - 传递给`selectId`实现的实体返回未定义