如何将 letsencrypt 更新从 apache2 迁移到 nginx

如何将 letsencrypt 更新从 apache2 迁移到 nginx

我从我目前工作的前员工(他离开去另一家公司)那里继承了一个非常新的 magento 配置。原始 Magento 的设置版本是 v2.1.8,但由于项目的需求/要求发生了变化,我不得不多次更新/升级安装。因此,我不一定拥有安装时的所有原始文件(我备份了一些,但经过多次更改后,我不得不减少备份的内容),并且不一定能问最初安装/配置它的人他做了什么。

最初的设置只是 apache2 上带有 https 的独立 magento-CE。部分问题在于我现在使用 Magento 建议,并将 apache 设置为在后台仅执行 http,使用 varnish 缓存和 nginx 处理实际的 https 内容。

第一个问题发生在 Apache 服务器在夜间神秘关闭时,没有任何动静。错误日志中只收到一条 SIGTERM 消息,表明有东西正在关闭它。我将其追溯到一个 cron 作业,该作业正在运行 letsencrypt 的续订脚本,该脚本试图通过 apache2(不再执行 https 或通过端口 443 通信)验证证书

我现在需要的是有关如何完成迁移设置的信息,以便续订脚本可以与 nginx 而不是 apache2 配合使用。我找到的所有有关设置 letsencrypt 的说明似乎都假设您尚未执行任何操作并且尚未获得证书。但我确实有证书,只是没有正确运行续订所需的 nginx 和 letsencrypt。

我修改了 /etc/letsencrypt/renewal/myhost.conf,使用 nginx 而不是 apache 作为身份验证器。(我还修改了“安装程序”行,但不确定是否需要这样做,因为它是在 apache2 下安装的)

我在服务器根目录中重新创建了一个 .well-known/acme-challenge/test 文件,并添加了目录和位置问题,并确认它可以从 http 端口 8080 上的 apache 服务器以及通过 https 端口 443 上的 nginx 上的缓存访问。(返回“成功”作为内容)

但是当我运行 certbot 来测试续订时(根据我在各个说明页面中看到的建议)它失败了:

# certbot renew --pre-hook "service nginx stop" -
-post-hook "service nginx start"
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/www.mydomain.com.conf
-------------------------------------------------------------------------------
Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator nginx, Installer nginx
Running pre-hook command: service nginx stop
Renewing an existing certificate
Performing the following challenges:
tls-sni-01 challenge for www.mydomain.com
tls-sni-01 challenge for mydomain.com
nginx: [error] open() "/run/nginx.pid" failed (2: No such file or directory)
Waiting for verification...
Cleaning up challenges
Attempting to renew cert (www.mydomain.com) from /etc/letsencrypt/renewal/www.mydomain.com.conf produced an unexpected error: Failed authorization procedure. www.mydomain.com (tls-sni-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Timeout. Skipping.
All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/www.mydomain.com/fullchain.pem (failure)

-------------------------------------------------------------------------------

All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/www.mydomain.com/fullchain.pem (failure)
-------------------------------------------------------------------------------
Running post-hook command: service nginx start
Hook command "service nginx start" returned error code 1
Error output from service:
Job for nginx.service failed because the control process exited with error code$ See "systemctl status nginx.service" and "journalctl -xe" for details.

1 renew failure(s), 0 parse failure(s)

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: www.mydomain.com
   Type:   connection
   Detail: Timeout

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webroot path you provided.

我需要知道还缺少什么才能使续订正常运行

答案1

我现在对 3 个域名执行了此操作并且有效,但请自行承担风险并在执行任何操作之前备份原始文件。

  • 确保你确实有该nginx插件。你可以使用命令安装它sudo apt-get install python-certbot-nginx
  • /etc/letsencrypt/renewal/*.conf使用您选择的编辑器进行 编辑
    • 我做到了vim /etc/letsencrypt/renewal/DOMAIN.conf
  • 在每个文件中,有两行需要替换apache2nginx
    • authenticator: nginx
    • installer: nginx

最后,为了测试是否顺利,请尝试使用以下命令更新您的证书

certbot --dry-run renew

如果没有出现任何错误,则表示续订成功。

答案2

我刚刚完成了我的个人服务器的迁移。我的服务器托管在 Digital Ocean,但通常你可以对托管在任何地方的任何服务器进行迁移。

你只需要为 nginx 配置包含你的域名的新块,然后调用 certbot

sudo certbot --nginx -d example.com -d www.example.com

如果你还想将证书迁移到新服务器,我在我的博客中总结了所有内容https://peacemoon.de/blog/2019/01/13/moving-servers-and-lets-encrypt-certificates-from-apache-to-nginx/

答案3

我设法通过以下方式使其工作:

  1. 将身份验证器设置为 nginx
  2. 注释掉 pre_hook 脚本
  3. 通过将改为systemctl start nginx来编辑 post_hook 脚本。systemctl restart nginx/etc/letsecrypt/renewal/*.com.conf

答案4

您可以尝试另一种方法,使用通用身份验证器,--standalone而不是在 Apache 或 Nginx 之间切换。但是,您会遇到一个问题,正如他们所说:“该插件需要绑定到端口 80 才能执行域验证,因此您可能需要停止现有的网络服务器。“。因此,如果您必须为网络服务器更新证书,则在域验证期间它会停机。

有一个解决方案可以帮助您避免停机:

  1. 使用参数运行 certbot:--standalone --http-01-port 12346— 插件的网络服务器将在端口 12346 而不是 80 上启动,因此您无需停止网络服务器。

  2. 例如运行中间小型反向代理Tinyproxy监听端口 12345。

    此代理非常轻量且易于管理,所以不必担心。它应该监听 HTTP 流量并在两个 Web 服务器之间重定向请求。代理会过滤流量并将 Let's Ecnrypt 验证请求重定向到插件的 Web 服务器端口 12346,并将常规 HTTP 请求重定向到您的 Web 服务器。

  3. 使用 iptables 创建 HTTP 流量重定向以从端口 80 反向代理到端口 12345,并接受新端口上的流量:

    iptables -I INPUT -p tcp -m tcp --dport 12346 -j ACCEPT
    iptables -I INPUT -p tcp -m tcp --dport 12345 -j ACCEPT
    iptables -t nat -I PREROUTING -p tcp -m tcp ! -s 127.0.0.1/32 --dport 80 \
        -j REDIRECT --to-ports 12345
    
  4. 验证完成后立即删除防火墙规则并停止代理服务器。

这就是您自动获得 Let's Encrypt 证书的全部内容,无需停机,也不会更改您的网络服务器内容。

您可能在这里熟悉这个食谱:https://jelastic.com/blog/zero-downtime-renewal-letsencrypt-ssl-certificate/

相关内容