如何阻止Nginx解析上游为IP?反向代理云API连接失败求助
解决Nginx反向代理时因上游域名解析导致的连接拒绝问题
从你的错误日志和描述来看,问题确实出在Nginx对上游域名的解析逻辑上——Nginx默认会在启动时就把upstream块里的域名解析成IP并缓存,而你的Cloud-API依赖请求中的主机名(Host头)来正确路由请求,直接用IP访问就会被拒绝。
下面是两种可行的解决方法,核心都是让Nginx保留域名的使用,同时确保请求的Host头正确传递:
方法1:使用变量+动态解析域名
这种方法通过定义变量来避免Nginx提前解析域名,配合resolver指令实现动态解析:
修改你的Nginx配置如下:
server { listen 8080 default_server; server_name localhost; # 指定DNS服务器,可用公共DNS如8.8.8.8,或你的内网DNS resolver 8.8.8.8 valid=30s; # 用变量存储上游API的域名和端口 set $cloud_api "here-comes-the-cloud-url.com:443"; location ^~ /apiv1/ { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; # 关键:将Host头设置为目标Cloud-API的域名,而不是客户端的$host proxy_set_header Host "here-comes-the-cloud-url.com"; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_cache_bypass $http_upgrade; # 使用变量作为上游地址,触发动态解析 proxy_pass https://$cloud_api$uri; } }
原理说明:
- 当
proxy_pass使用变量时,Nginx不会在启动时解析域名,而是每次请求时通过resolver指定的DNS服务器动态解析 - 必须显式设置
proxy_set_header Host为目标API的域名,否则客户端请求的localhost:8080会被传递给上游,导致服务器无法识别正确的虚拟主机
方法2:使用upstream的resolve参数(Nginx 1.1.9+支持)
如果你更倾向于保留upstream块的结构,可以使用resolve参数让Nginx动态解析上游域名:
# 在http块或server块外定义upstream upstream cloudapi { # 添加resolve参数,让Nginx动态解析域名 server here-comes-the-cloud-url.com:443 resolve; # 指定DNS服务器 resolver 8.8.8.8 valid=30s; } server { listen 8080 default_server; server_name localhost; location ^~ /apiv1/ { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; # 同样要设置正确的Host头 proxy_set_header Host "here-comes-the-cloud-url.com"; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_cache_bypass $http_upgrade; proxy_pass https://cloudapi$uri; } }
验证步骤
- 修改配置后,执行
nginx -t检查配置语法是否正确 - 重启Nginx:
nginx -s reload - 发送测试请求,查看错误日志是否不再出现
connect() failed (111: Connection refused)的报错,同时确认请求能正常得到Cloud-API的响应
内容的提问来源于stack exchange,提问作者bgeissler
相关产品推荐
相关产品推荐

