acme.sh
acme.sh copied to clipboard
nginx 部分 https 301 重定向写法导致的问题(不是bug)
信息
项目 | 内容 |
---|---|
acme.sh 版本 | v3.0.8 |
时间 | 2024/3/19 |
系统版本 | Debian bookworm Linux 6.1.0-18-amd64 |
内核版本 | 6.1.0-18-amd64 |
起因
我长期使用nginx作为web server,而每次当我使用 acme.sh 搭配 nginx 的时候,大部分时候都会遇到 Invalid response from https://domain/acme-challenge/xxx: 404
的问题,而一些域名就没有问题。
问题
我长期对此深感疑惑,直到某一次,我在证书更新的时候想起来 nginx 配置文件有误,在脚本执行中途退出执行去编辑 nginx 配置,发现本脚本实现 nginx 自动更新是用如下方式完成的:
location ~ "^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)$" {
default_type text/plain;
return 200 "xxx";
}
而如果配置 nginx 时重定向 http(80) 请求到 https(443) 的时候使用的是如下方式:
server{
listen 80;
server_name domain.example;
return 301 https://$host:443/$request_uri;
}
就会出现:请求忽略了 location
,直接被 301 重定向到 https(443),而由于脚本未在 https(443) 的配置中加入验证相关配置,导致出现 let's encrypt 对域名所有权验证时候返回 404 的问题。
方案
我目前是通过给 301 重定向加了个 location /
的条件临时解决了,而对于脚本来说,解决方案也很简单:临时屏蔽相关配置段落中的 return 301 xxx;
和 return 302 xxx;
,或者在相关域名的 https(443) 配置下也添加用于校验的配置段即可。
Please upgrade to the latest code and try again first. Maybe it's already fixed. acme.sh --upgrade
If it's still not working, please provide the log with --debug 2
, otherwise, nobody can help you.
我也遇到了同样的问题,即使我已经使用了acme.sh --upgrade更新到了最新版本。 根据我自己的排查,是因为acme不兼容以下nginx配置:
server {
listen 80;
server_name xxx.xxx.com;
rewrite ^(.*)$ https://${server_name}$1 permanent;
}
这段重定向的代码优先级比acme生成的配置更高。
因为我不确定acme生成的nginx配置是否放置在最前放,以确保优先级。所以我自己手动固定了这个配置:
location ~ "^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)$" {
default_type text/plain;
return 200 "xxx";
}
location / {
rewrite ^(.*)$ https://${server_name}$1 permanent;
}
属实这个坑都好久了!
我也遇到了同样的问题,即使我已经使用了acme.sh --upgrade更新到了最新版本。 根据我自己的排查,是因为acme不兼容以下nginx配置:
server { listen 80; server_name xxx.xxx.com; rewrite ^(.*)$ https://${server_name}$1 permanent; }
这段重定向的代码优先级比acme生成的配置更高。
因为我不确定acme生成的nginx配置是否放置在最前放,以确保优先级。所以我自己手动固定了这个配置:
location ~ "^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)$" { default_type text/plain; return 200 "xxx"; } location / { rewrite ^(.*)$ https://${server_name}$1 permanent; }
只需要改为location /
就行行了,location /
优先级最低。
location / {
rewrite ^(.*)$ https://${server_name}$1 permanent;
}
nginx 的重定向写法太自由了, 所以很难有一个万全的写法. 如果有请提交代码, 否则, 就使用webroot 方法吧.
而如果配置 nginx 时重定向 http(80) 请求到 https(443) 的时候使用的是如下方式:
This looks like a cert-server failing to follow 301 redirect. The redirection restriction may due to security concerns of someone doing malicious redirects to hijack certs. Using rewrite module, a 301 redirection will not be generated.
The cert-server should modify its behavior to try on both 80 and 443 ports. There should be a preponderance to prefer 443 over 80.