【问题标题】:Nginx service that is not properly stopped by the certbot and therefore does not restartNginx 服务没有被 certbot 正确停止,因此不会重新启动
【发布时间】:2019-05-15 19:27:47
【问题描述】:

我的 vps 在 debian 上运行时遇到了一点问题。它通过基于 nginx、gunicorn、django 的基础架构托管多个网站。 有问题的网站有一个由 let's encrypt 管理的 ssl 证书。

我认为当 let's encrypt 想要更新证书时会出现问题。

错误

出现错误时的系统日志:

Dec 12 00:01:46 vps465872 systemd[1]: Starting Certbot...
Dec 12 00:01:49 vps465872 systemd[1]: Stopping A high performance web server and a reverse proxy server...
Dec 12 00:01:49 vps465872 systemd[1]: Stopped A high performance web server and a reverse proxy server.
Dec 12 00:01:55 vps465872 certbot[600]: nginx: [error] open() "/run/nginx.pid" failed (2: No such file or directory)
Dec 12 00:01:56 vps465872 systemd[1]: Starting A high performance web server and a reverse proxy server...
Dec 12 00:01:56 vps465872 nginx[658]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Dec 12 00:01:56 vps465872 nginx[658]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Dec 12 00:01:57 vps465872 nginx[658]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Dec 12 00:01:57 vps465872 nginx[658]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Dec 12 00:01:57 vps465872 nginx[658]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Dec 12 00:01:57 vps465872 nginx[658]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Dec 12 00:01:58 vps465872 nginx[658]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Dec 12 00:01:58 vps465872 nginx[658]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Dec 12 00:01:58 vps465872 nginx[658]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Dec 12 00:01:58 vps465872 nginx[658]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Dec 12 00:01:59 vps465872 nginx[658]: nginx: [emerg] still could not bind()
Dec 12 00:01:59 vps465872 systemd[1]: nginx.service: Control process exited, code=exited status=1
Dec 12 00:01:59 vps465872 systemd[1]: Failed to start A high performance web server and a reverse proxy server.
Dec 12 00:01:59 vps465872 systemd[1]: nginx.service: Unit entered failed state.
Dec 12 00:01:59 vps465872 systemd[1]: nginx.service: Failed with result 'exit-code'.
Dec 12 00:01:59 vps465872 certbot[600]: Hook command "service nginx start" returned error code 1
Dec 12 00:01:59 vps465872 certbot[600]: Error output from service:
Dec 12 00:01:59 vps465872 certbot[600]: Job for nginx.service failed because the control process exited with error code.
Dec 12 00:01:59 vps465872 certbot[600]: See "systemctl status nginx.service" and "journalctl -xe" for details.

复制

就这样吧。让我们手动重做这个过程。我杀死了 nginx 周围的一切:

ps -ef |grep nginx
kill -9 xxxx
kill -9 xxxx

我重新启动 nginx:

service nginx start

然后一切正常。

我对 certbot 进行了试运行:

certbot renew --dry-run

现在我有错误:

Attempting to renew cert (xxx.fr) from /etc/letsencrypt/renewal/xxx.fr.conf produced an unexpected error: Problem binding to port 443: Could not bind to IPv4 or IPv6... Skipping.

调查

我查看/run目录:文件nginx.pid不再存在。

另一方面,一点点 ps -ef |grep nginx 告诉我该进程仍在运行,确实网站正在运行。因此,如果我执行 nginx 启动服务,它会向我输出地址冲突错误。

我在 stackoverflow 上发现有人和我有同样的问题,但解决方案不起作用。但它给了我在哪里看的线索。 Certbot renew: nginx: [error] open() "/run/nginx.pid" failed (2: No such file or directory)

所以我正在寻找: 文件 /etc/letsencrypt/renewal/xxx.fr.conf 包含以下钩子:

[renewalparams]
authenticator = standalone
installer = nginx
pre_hook = service nginx stop
post_hook = service nginx start

很好。我查看了相关的脚本 /etc/init.d/nginx : 一开始它通过

提取 pid
PID=$(cat /etc/nginx/nginx/nginx.conf | grep -Ev' ^\s*#' | awk' BEGIN { RS="[;{}]" } { if ($1 == "pid") print $2 }' | head -n1)

这个命令运行良好。

停止:

stop_nginx() {
    start-stop-daemon --stop --quiet --retry=$STOP_SCHEDULE --pidfile $PID --name $NAME
    RETVAL="$?"
    sleep 1
    return "$RETVAL"
}

开始

start_nginx() {
    start-stop-daemon --start --quiet --pidfile $PID --exec $DAEMON --test > /dev/null \
        || return 1
    start-stop-daemon --start --quiet --pidfile $PID --exec $DAEMON -- \
        $DAEMON_OPTS 2>/dev/null \
        || return 2
}

看起来不错。此外,当服务与其 pid 配合良好时,启动和停止命令也能很好地工作。

结论

好吧,就是这样,我遇到了一个我不明白的问题。

【问题讨论】:

    标签: nginx certbot


    【解决方案1】:

    我可以推荐使用webroot 模式而不是独立模式。要更新证书,它会在您的网络服务器根目录中创建一个“.well-known/acme-challenge/”。

    好处是减少了停机时间,因为您只需要通过post_hook重新启动 nginx 服务,而不是“停止等待启动”

    希望这个替代解决方案有所帮助

    【讨论】:

    • 更好的是,使用service nginx reload 而不是重新启动。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 2016-04-13
    相关资源
    最近更新 更多