没有被certbot正确停止的Nginx服务,因此没有重新启动



我的vps在使用debian运行时遇到了一点问题。它通过基于nginx、gunicorn、django的基础设施托管了几个网站。有问题的站点有一个ssl证书,由我们加密管理。

我认为问题出现在让我们加密想要续订证书时。

错误

出现错误时的系统日志:

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续订:nginx:[error]open(("run/nginx.pid";失败(2:没有这样的文件或目录(

所以我在寻找:文件/etc/letsencrypt/renewing/xxxx.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运行良好时,启动和停止命令运行良好。

结论

好吧,仅此而已,我遇到了一个我不理解的问题。

我可以建议使用webroot模式而不是独立模式。要续订证书,它会在您的Web服务器根目录中创建一个".aknowled/acme challenge/"。

Upside是较少的停机时间,因为您只需要通过post_hook重新启动nginx服务,而不是"停止-等待-启动">

希望这个替代方案能帮助

最新更新