acme.sh icon indicating copy to clipboard operation
acme.sh copied to clipboard

nginx 部分 https 301 重定向写法导致的问题(不是bug)

Open cacheci opened this issue 11 months ago • 6 comments

信息

项目 内容
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) 配置下也添加用于校验的配置段即可。

cacheci avatar Mar 19 '24 18:03 cacheci

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.

github-actions[bot] avatar Mar 19 '24 18:03 github-actions[bot]

我也遇到了同样的问题,即使我已经使用了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;
    } 
 

DeathInTheAir avatar Mar 22 '24 08:03 DeathInTheAir

属实这个坑都好久了!

ShaoxiongXu avatar Mar 27 '24 10:03 ShaoxiongXu

我也遇到了同样的问题,即使我已经使用了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;
    } 

ShaoxiongXu avatar Mar 27 '24 11:03 ShaoxiongXu

nginx 的重定向写法太自由了, 所以很难有一个万全的写法. 如果有请提交代码, 否则, 就使用webroot 方法吧.

Neilpang avatar Apr 01 '24 09:04 Neilpang

而如果配置 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.

jxcang avatar May 28 '24 13:05 jxcang