我如何为指向我的服务器的域动态创建新的 LetsEncrypt/Certbot SSL 证书?

How can i dynamically create new LetsEncrypt/Certbot SSL certificates for domains pointing to my server?

我正在构建一个网络应用程序(示例:www.mywebapp.example),允许用户将他们的域 - www.xyz.example - 指向 www.mywebapp.example。当用户转到 www.xyz.example 时,他们的内容将改为从 www.mywebapp.example 提供。用户将被告知如何在他们的域提供商 DNS 设置中更新他们的 @www A records 以将 www.xyz.example 连接到 www.mywebapp.example

我可以使用 ./certbot-auto -d <domain-name> 为每个域手动创建新的 SSL 证书。我还设置了一个 cron 作业来测试更新。

但是,我想通过 运行ning 一个 PHP 脚本来自动执行此过程,该脚本由 JavaScript 函数触发,每次用户将他们的域连接到 www.mywebapp.example.我的问题是:

  1. 我应该使用 exec()/shell_exec() 命令从 PHP 执行 ./certbot-auto 命令吗?我应该写一个单独的 bash 脚本和 运行 bash 脚本吗?

  2. 我应该使用 LetsEncrypt 推荐的 ACME PHP 库吗 - https://letsencrypt.org/docs/client-options/

  3. 我为域 www.xyz2.example 手动创建了一个新的 SSL 证书,它成功指向了 www.mywebapp.example。但是,这破坏了对所有现有域的 SSL 支持 - *.mywebapp.example, mywebapp.example, www.xyz.example。我是否需要为每个指向 www.mywebapp.example 的域创建虚拟主机?

  4. 我是否需要编辑 /etc/httpd/conf.d/ssl.conf 来添加新的虚拟主机?多个域可以使用相同的 DocumentRoot 路径吗?

我已经通读了以下所有链接,但仍然很困惑:

非常感谢任何帮助。如果需要更多信息,请告诉我。

我的服务器设置是:

你有很多问题。

Should I execute the ./certbot-auto command from PHP using the exec()/shell_exec() command? Should I write a separate bash script and run the bash script instead?

在一般情况下:没有。

PHP 一旦到达网页就会执行,因此它存在于当前的 HTTP 会话中,另一端的浏览器将在某种有限的时间内等待某种响应(如果用户没有看到出现的东西,他们会生气 "fast")。

如果您执行某些操作,您有两个选择:

  1. 您等待外部程序完成:问题,这可能会在 "undefinite" 时间之后,因此如果不考虑这一点,用户将永远不会在浏览器中看到任何返回内容
  2. 你在后台启动它,你不等待它完成:问题,你不需要它是否成功,所以即使你可以回复 "something" 到浏览器, 你将如何处理失败?

这种情况的通用解决方案是:

  1. HTTP访问触发的动作只是记录请求,就像在数据库里什么的
  2. 一个进程单独轮询数据库以查找要执行的任务并执行它们;这完全独立于任何网络服务器;当作业完成(成功或失败)时,数据库将以相同的方式更新
  3. 1) 处的进程可以定期轮询数据库以查看状态(待定或已完成或失败)并向用户显示一条消息,例如在其访问期间,带有某种自动刷新,and/or提供一个特定的单独页面,用户可以在其中跟踪其操作状态

Should I use an ACME PHP library recommended by LetsEncrypt - https://letsencrypt.org/docs/client-options/

您可以使用任何正确实现 ACME 协议的语言的任何库。

Let's Encrypt 只推荐一款软件:certbot。该页面中列出的所有其他内容都是预期可以正常工作的客户端 libraries/programs 的示例。

Do I need to create virtual hosts for each domain pointing to www.mywebapp.example?

是的,特别是如果他们每个人都使用一个特定的证书,否则网络服务器将无法在 TLS 握手开始时根据浏览器的主机名识别正确的证书 return给出(在 TLS 握手开始时使用的 SNI 扩展中)

或者你可以使用海量虚拟主机的一些Apache特性,比如https://httpd.apache.org/docs/2.4/mod/mod_vhost_alias.html 然而,这可能意味着添加了所有名称的单个证书,这在技术上可以工作直到一定数量的名称,但会产生非技术问题(比如看到所有名称等)

当然其他软件,比如Nging/HAProxy可以提供更高级的功能,你不需要为每个虚拟主机配置虚拟主机,即使有不同的证书,你只需要用特定的命名就可以了网络服务器将根据需要匹配内容。

Do I need to edit /etc/httpd/conf.d/ssl.conf to add the new virtual hosts?

是,或者任何其他文件,只要您使用 Include 或类似文件即可。

如果您管理许多不同且独立的网站,每个网站有一个配置文件可能会更简单,包括其证书路径等,许多 Linux 发行版以您拥有的方式安装 Apache /etc/httpd/sites-enabled/ 该功能。如果没有,你也可以自己做。

Can multiple domains use the same DocumentRoot path?

当然可以。

PS:请不要再说SSL了,这个协议叫TLS,20年前发明的。 SSL 早已不复存在,目前的建议是 运行 TLS 1.2,除非有充分的理由也允许具有漏洞的 1.1 和 1.0。没有 "SSL certificate" 要么是因为这个原因,要么是因为它们用词不当。 TLS 可以在没有证书的情况下工作,并且这些证书可以在 TLS 之外使用,例如 S/MIME。它们是 X.509 证书。