如何配置Nginx的.well-known/acme-challenge适配Django代理服务?
Nginx适配Django代理的.acme-challenge配置方案
问题背景
前端域名myserver.com的Nginx配置通过单独设置/.well-known/acme-challenge location指向本地目录,能正常通过acme.sh完成SSL证书验证;但后端API域名api.myserver.com的Nginx配置将所有请求代理到Django服务,未配置本地文件访问,导致acme.sh无法完成验证。
解决方案
方案一:Nginx单独配置acme验证路径(推荐)
直接在后端Nginx的server块中添加优先匹配的/.well-known/acme-challenge规则,跳过代理直接读取本地验证文件:
- 创建acme验证文件存储目录并设置权限:
mkdir -p /var/www/acme-challenge/ chown www-data:www-data /var/www/acme-challenge/
- 修改后端Nginx配置:
upstream myapp { server backend:8000; } server { listen 80; server_name api.myserver.com; # 优先处理ACME验证请求,直接读取本地文件 location /.well-known/acme-challenge { allow all; root /var/www/acme-challenge/; try_files $uri =404; } location / { proxy_pass http://myapp; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_redirect off; } return 301 https://api.myserver.com$request_uri; }
- 重载Nginx配置:
nginx -s reload
- 执行acme.sh命令获取证书:
/root/.acme.sh/acme.sh --issue -d api.myserver.com -w /var/www/acme-challenge/
方案二:通过Django处理验证请求(可选)
若需通过Django服务处理验证请求,可添加对应视图和路由:
- 在Django项目中添加验证视图:
from django.http import HttpResponse import os # 验证文件存储目录,需和acme.sh指定目录一致 ACME_CHALLENGE_DIR = "/var/www/acme-challenge/" def acme_challenge(request, filename): file_path = os.path.join(ACME_CHALLENGE_DIR, filename) if os.path.exists(file_path): with open(file_path, 'r') as f: content = f.read() return HttpResponse(content, content_type='text/plain') return HttpResponse(status=404)
- 在项目urls.py中添加路由规则:
from django.urls import path from .views import acme_challenge urlpatterns = [ # 其他业务路由... path('.well-known/acme-challenge/<str:filename>', acme_challenge), ]
- 同样创建并设置
/var/www/acme-challenge/目录权限后,执行相同的acme.sh命令即可。
方案对比
方案一无需修改Django代码,直接通过Nginx处理验证请求,性能更高、更简洁,是首选方案;方案二适合无法修改Nginx配置的场景,但会增加Django的请求处理负担。
内容的提问来源于stack exchange,提问作者Andre Maia
相关产品推荐
相关产品推荐

